ditto_live 4.10.0 copy "ditto_live: ^4.10.0" to clipboard
ditto_live: ^4.10.0 copied to clipboard

The Ditto Flutter SDK is an edge sync platform allowing devices to synchronize data with or without an internet connection. For more info, go to https://docs.ditto.live

example/lib/main.dart

// ignore_for_file: invalid_use_of_visible_for_testing_member

import 'package:ditto_live/ditto_live.dart';
import 'package:ditto_live_example/dialog.dart';
import 'package:ditto_live_example/dql_builder.dart';
import 'package:ditto_live_example/presence.dart';
import 'package:ditto_live_example/task.dart';
import 'package:ditto_live_example/task_view.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

const appID = "caf9e870-d416-4b1c-9ab4-fb6e8319dd25";
const token = "cb639c76-5633-44dd-ad28-03a5a43f092e";

const authAppID = "3cffb689-8a99-4b4c-bca1-0809a5135748";

const collection = "tasks13";

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Ditto.init();

  DittoLogger.isEnabled = true;
  DittoLogger.minimumLogLevel = LogLevel.info;
  DittoLogger.customLogCallback = (level, message) {
    print("[$level] => $message");
  };

  runApp(const MaterialApp(
    debugShowCheckedModeBanner: false,
    home: DittoExample(),
  ));
}

class DittoExample extends StatefulWidget {
  const DittoExample({super.key});

  @override
  State<DittoExample> createState() => _DittoExampleState();
}

class _DittoExampleState extends State<DittoExample> {
  Ditto? _ditto;
  var _syncing = true;
  int _pageIndex = 0;

  @override
  void initState() {
    super.initState();

    _initDitto();
  }

  Future<void> _initDitto() async {
    await [
      Permission.bluetoothConnect,
      Permission.bluetoothAdvertise,
      Permission.nearbyWifiDevices,
      Permission.bluetoothScan
    ].request();

    // final identity = await OnlinePlaygroundIdentity.create(
    //   appID: appID,
    //   token: token,
    // );

    final identity = OnlineWithAuthenticationIdentity(
      appID: authAppID,
      authenticationHandler: AuthenticationHandler(
        authenticationExpiringSoon: (authenticator, secondsRemaining) async {
          print(authenticator.status);
          await authenticator.login(token: token, provider: "auth-webhook");
        },
        authenticationRequired: (authenticator) async {
          print(authenticator.status);
          await authenticator.login(token: token, provider: "auth-webhook");
        },
      ),
    );

    final ditto = await Ditto.open(identity: identity);

    ditto.updateTransportConfig((config) {
      config.setAllPeerToPeerEnabled(true);
      config.connect.webSocketUrls.add(
        "wss://$authAppID.cloud.ditto.live",
      );
    });
    ditto.deviceName = "Flutter (${ditto.deviceName})";
    print("Device name: ${ditto.deviceName}");

    print("Persistence directory path as string");
    // print(ditto.persistenceDirectoryString);

    ditto.smallPeerInfo.isEnabled = true;
    ditto.smallPeerInfo.syncScope = SmallPeerInfoSyncScope.bigPeerOnly;

    ditto.startSync();

    setState(() => _ditto = ditto);
  }

  Future<void> _addTask() async {
    final pair = await showAddTaskDialog(context, _ditto!);
    if (pair == null) return;
    final (task, attachment) = pair;

    await _ditto!.store.execute(
      "INSERT INTO COLLECTION $collection (${Task.schema}) DOCUMENTS (:task)",
      arguments: {
        "task": {
          ...task.toJson(),
          "image": attachment,
          // "image": { "_id": asasd, "_ditto_internal_...": 2},
        },
      },
    );
  }

  Future<void> _clearTasks() async {
    await _ditto!.store.execute(
      "EVICT FROM COLLECTION $collection (${Task.schema}) WHERE true",
    );
  }

  @override
  Widget build(BuildContext context) {
    final ditto = _ditto;

    if (ditto == null) return _loading;

    return Scaffold(
      appBar: AppBar(
        title: const Text("Ditto Tasks"),
        actions: [
          IconButton(
            icon: const Icon(Icons.clear),
            tooltip: "Clear",
            onPressed: _clearTasks,
          ),
        ],
      ),
      floatingActionButton: _pageIndex == 0 ? _fab : null,
      body: switch (_pageIndex) {
        0 => Column(
            children: [
              _syncTile,
              const Divider(height: 1),
              Expanded(child: _tasksList),
            ],
          ),
        1 => PresenceView(ditto: _ditto!),
        _ => throw "unreachable",
      },
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.task), label: "Tasks"),
          BottomNavigationBarItem(icon: Icon(Icons.devices), label: "Presence"),
        ],
        currentIndex: _pageIndex,
        onTap: (value) => setState(() => _pageIndex = value),
      ),
    );
  }

  Widget get _loading => Scaffold(
        appBar: AppBar(title: const Text("Ditto Tasks")),
        body: const Center(
          child: CircularProgressIndicator(),
        ),
      );

  Widget get _fab => FloatingActionButton(
        onPressed: _addTask,
        child: const Icon(Icons.add_task),
      );

  Widget get _syncTile => SwitchListTile(
        title: const Text("Syncing"),
        value: _syncing,
        onChanged: (value) {
          if (value) {
            _ditto!.startSync();
          } else {
            _ditto!.stopSync();
          }

          setState(() => _syncing = value);
        },
      );

  Widget get _tasksList => DqlBuilder(
        ditto: _ditto!,
        query:
            "SELECT * FROM COLLECTION $collection (${Task.schema}) WHERE deleted = false",
        builder: (context, response) {
          Widget makeTaskView(QueryResultItem result) {
            final task = Task.fromJson(result.value);
            final imageToken = result.value["image"];

            return _singleTask(task, imageToken);
          }

          final tasks = response.items.map(makeTaskView);

          return ListView(children: [...tasks]);
        },
      );

  Widget _singleTask(Task task, Map<String, dynamic>? image) => Dismissible(
        key: Key("${task.id}-${task.title}"),
        onDismissed: (direction) async {
          await _ditto!.store.execute(
            "UPDATE $collection SET deleted = true WHERE _id = '${task.id}'",
          );

          if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text("Deleted Task ${task.title}")),
            );
          }
        },
        background: _dismissibleBackground(true),
        secondaryBackground: _dismissibleBackground(false),
        child: TaskView(ditto: _ditto!, task: task, token: image),
      );

  Widget _dismissibleBackground(bool primary) => Container(
        color: Colors.red,
        child: Align(
          alignment: primary ? Alignment.centerLeft : Alignment.centerRight,
          child: const Padding(
            padding: EdgeInsets.all(8.0),
            child: Icon(Icons.delete),
          ),
        ),
      );
}
11
likes
140
points
830
downloads

Publisher

verified publisherditto.live

Weekly Downloads

The Ditto Flutter SDK is an edge sync platform allowing devices to synchronize data with or without an internet connection. For more info, go to https://docs.ditto.live

Homepage

Documentation

API reference

License

unknown (license)

Dependencies

cbor, convert, equatable, ffi, flutter, json_annotation, logger, meta, path, path_provider, plugin_platform_interface

More

Packages that depend on ditto_live