flutter-sdk .A Flutter integration for Transloadit's file uploading and encoding service.

Intro

Transloadit is a service that helps you handle file uploads, resize, crop and watermark your images, make GIFs, transcode your videos, extract thumbnails, generate audio waveforms, and so much more. In short, Transloadit is the Swiss Army Knife for your files.

This is a Flutter SDK to make it easy to talk to the Transloadit REST API.

Install

flutter pub add transloadit

Usage

Firstly you need to create a Transloadit client, using your authentication credentials. This will allow us to make requests to the Transloadit API.

TransloaditClient client = TransloaditClient(
        authKey: 'KEY',
        authSecret: 'SECRET');

1. Resize an Image

This example shows how to resize an image using the Transloadit API.

TransloaditClient client = TransloaditClient(
        authKey: 'KEY',
        authSecret: 'SECRET');

// First we create our assembly
TransloaditAssembly assembly = client.newAssembly();

// Next we add two steps, one to import a file, and another to resize it to 400px tall
assembly.addStep("import", "/http/import",
        {"url": "https://demos.transloadit.com/inputs/chameleon.jpg"});
assembly.addStep("resize", "/image/resize", {"height": 400});

// We then send this assembly to Transloadit to be processed
TransloaditResponse response = await assembly.createAssembly();

print(response['ok']) // "ASSEMBLY_COMPLETED"

2. Uploading files with an Assembly

A file from a user's device can be included with an Assembly using the addFile method.

TransloaditClient client = TransloaditClient(
        authKey: 'KEY',
        authSecret: 'SECRET');

// First we create our assembly
TransloaditAssembly assembly = client.newAssembly();

// Add a local file to be sent along with the assembly via the Tus protocol
assembly.addFile(file: file!);
assembly.addStep("resize", "/image/resize", {"height": 400});

// We then send this assembly to Transloadit to be processed
TransloaditResponse response = await assembly.createAssembly();

print(response['ok']) // "ASSEMBLY_COMPLETED"

3. Using a template with fields

TransloaditClient client = TransloaditClient(
        authKey: 'KEY',
        authSecret: 'SECRET');

// Create an assembly from a template ID
TransloaditAssembly assembly = client.runTemplate(
        templateID: 'TEMPLATE_ID', 
        params: {'fields': {'input': 'items.jpg'}});

// We then send this assembly to Transloadit to be processed
TransloaditResponse response = await assembly.createAssembly();

print(response.data["ok"]); // "ASSEMBLY_COMPLETED"

4. Tracking Upload Progress

These two callback methods track the progress of the Tus upload, not the Transloadit Assembly.

TransloaditResponse response = await assembly.createAssembly(
        onProgress: (progressValue) {
          print(progressValue); // Float from 0-100
        },
        onComplete: () {
          // Run on completion
        }),
      );

Example

For a fully working example app, check out examples/.

Documentation

Full documentation for all classes and methods can be found on pub.dev

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add transloadit

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):


dependencies:
  transloadit: ^0.2.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:transloadit/transloadit.dart';

example/lib/main.dart

import 'package:universal_io/io.dart';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:transloadit/transloadit.dart';

void main() {
  runApp(MyApp());
}

Map<int, Color> dark = {
  50: Color.fromRGBO(17, 30, 50, .1),
  100: Color.fromRGBO(17, 30, 50, .2),
  200: Color.fromRGBO(17, 30, 50, .3),
  300: Color.fromRGBO(17, 30, 50, .4),
  400: Color.fromRGBO(17, 30, 50, .5),
  500: Color.fromRGBO(17, 30, 50, .6),
  600: Color.fromRGBO(17, 30, 50, .7),
  700: Color.fromRGBO(17, 30, 50, .8),
  800: Color.fromRGBO(17, 30, 50, .9),
  900: Color.fromRGBO(17, 30, 50, 1),
};

Map<int, Color> light = {
  50: Color.fromRGBO(0, 120, 209, .1),
  100: Color.fromRGBO(0, 120, 209, .2),
  200: Color.fromRGBO(0, 120, 209, .3),
  300: Color.fromRGBO(0, 120, 209, .4),
  400: Color.fromRGBO(0, 120, 209, .5),
  500: Color.fromRGBO(0, 120, 209, .6),
  600: Color.fromRGBO(0, 120, 209, .7),
  700: Color.fromRGBO(0, 120, 209, .8),
  800: Color.fromRGBO(0, 120, 209, .9),
  900: Color.fromRGBO(0, 120, 209, 1),
};

MaterialColor transloaditDark = MaterialColor(0xFF111E32, dark);
MaterialColor transloaditLight = MaterialColor(0xFF0078D1, light);

ColorScheme colorScheme = ColorScheme(
    primary: transloaditDark,
    primaryVariant: dark[500]!,
    secondary: transloaditLight,
    secondaryVariant: light[200]!,
    surface: Colors.white,
    background: Colors.white,
    error: Colors.redAccent,
    onPrimary: Colors.white,
    onSecondary: Colors.white,
    onSurface: transloaditDark,
    onBackground: transloaditDark,
    onError: Colors.white,
    brightness: Brightness.light);

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Transloadit Demo',
      theme: ThemeData(
          // Define the default brightness and colors.
          brightness: Brightness.light,
          colorScheme: colorScheme,
          sliderTheme: SliderThemeData(
            valueIndicatorColor: colorScheme.primary,
            activeTrackColor: colorScheme.primary,
            activeTickMarkColor: colorScheme.primary,
            thumbColor: colorScheme.primary,
            inactiveTrackColor: colorScheme.secondaryVariant,
            inactiveTickMarkColor: Colors.transparent,
            valueIndicatorShape: PaddleSliderValueIndicatorShape(),
          )),
      home: MyHomePage(title: 'Transloadit Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? image;
  String? imageURL;
  double imageRotation = 0;
  bool imageZoom = false;
  bool isProcessing = false;
  bool uploadComplete = false;
  double progress = 0;

  // Opens a file picker to select an on device file
  Future<void> _pickFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['jpg', 'png'],
    );

    if (result != null) {
      File file = File(result.files.single.path!);
      setState(() {
        image = file;
      });
    } else {
      // User canceled the picker
    }
  }

  // Creates a Transloadit assembly to rotate an image by a user-specified amount
  Future<void> _processImage() async {
    if (image != null) {
      setState(() {
        isProcessing = true;
      });

      TransloaditClient client = TransloaditClient(
          authKey: '72a70fba93ce41cba617cfd7c2a44b1a',
          authSecret: '3b2845e9330051ed3adc06b4217c42e4f504f8f3');

      TransloaditAssembly assembly = client.newAssembly();

      assembly.addFile(file: image!);
      assembly.addStep("resize", "/image/resize", {
        "rotation": imageRotation,
        "zoom": imageZoom,
        "trim_whitespace": true,
        "transparent": "#FFFFFF",
        "format": "png"
      });

      TransloaditResponse response = await assembly.createAssembly(
        onProgress: (progressValue) {
          print(progressValue);
          setState(() {
            progress = progressValue;
          });
        },
        onComplete: () => setState(() => uploadComplete = true),
      );

      setState(() {
        imageURL = response.data['results']['resize'][0]['ssl_url'];
        isProcessing = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          _pickFile();
        },
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomAppBar(
        shape: CircularNotchedRectangle(),
        notchMargin: 8.0,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            SizedBox(
              height: 60,
            ),
            IconButton(
              icon: Icon(
                Icons.send,
                color: Colors.white,
              ),
              onPressed: () {
                setState(() {
                  _processImage();
                  progress = 0;
                  uploadComplete = false;
                });
              },
            ),
          ],
        ),
        color: transloaditDark,
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          TransloaditImage(
              isProcessing: isProcessing,
              uploadComplete: uploadComplete,
              progress: progress,
              imageURL: imageURL,
              image: image),
          Expanded(
            child: Column(
              children: [
                TransloaditToggle(
                  text: 'Zoom',
                  value: imageZoom,
                  onChanged: (value) {
                    setState(() {
                      imageZoom = value;
                    });
                  },
                ),
                Divider(),
                TransloaditSlider(
                    text: 'Rotation',
                    value: imageRotation,
                    max: 360,
                    divisions: 12,
                    onChanged: (value) {
                      setState(() {
                        imageRotation = value;
                      });
                    }),
                Divider(),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class TransloaditSlider extends StatelessWidget {
  const TransloaditSlider({
    Key? key,
    required this.text,
    required this.value,
    required this.max,
    required this.divisions,
    required this.onChanged,
  }) : super(key: key);

  final String text;
  final double value;
  final double max;
  final int divisions;
  final Function(double p1) onChanged;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(30, 8, 15, 8),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            text,
            textScaleFactor: 1.5,
          ),
          Slider(
              value: value,
              min: 0,
              max: max,
              label: value.ceil().toString(),
              divisions: divisions,
              onChanged: onChanged),
        ],
      ),
    );
  }
}

class TransloaditToggle extends StatelessWidget {
  const TransloaditToggle({
    Key? key,
    required this.text,
    required this.value,
    required this.onChanged,
  }) : super(key: key);

  final String text;
  final bool value;
  final Function(bool) onChanged;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(30, 8, 15, 8),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            text,
            textScaleFactor: 1.5,
          ),
          Switch(
              value: value,
              activeColor: transloaditDark,
              activeTrackColor: transloaditLight[200],
              inactiveThumbColor: transloaditDark,
              inactiveTrackColor: transloaditDark[100],
              onChanged: onChanged),
        ],
      ),
    );
  }
}

class TransloaditImage extends StatelessWidget {
  const TransloaditImage({
    Key? key,
    required this.isProcessing,
    required this.uploadComplete,
    required this.progress,
    required this.imageURL,
    required this.image,
  }) : super(key: key);

  final bool isProcessing;
  final bool uploadComplete;
  final double progress;
  final String? imageURL;
  final File? image;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Stack(
        alignment: Alignment.center,
        children: [
          Container(color: Colors.grey[200]),
          isProcessing
              ? uploadComplete
                  ? CircularProgressIndicator()
                  : Align(
                      alignment: Alignment.bottomCenter,
                      child: LinearProgressIndicator(
                        color: transloaditDark,
                        backgroundColor: transloaditLight[200],
                        value: progress / 100,
                      ),
                    )
              : imageURL != null
                  ? Image.network(imageURL!)
                  : image != null
                      ? Image.file(image!)
                      : Image(
                          image: AssetImage('assets/transloadit.png'),
                        ),
        ],
      ),
    );
  }
}

#fluter  #dart #mobile-apps #morioh 

Flutter Integration for Transloadit
1.60 GEEK