Skip to main content

nativemind_freedome 0.1.0 copy "nativemind_freedome: ^0.1.0" to clipboard
nativemind_freedome: ^0.1.0 copied to clipboard

Fulldome UI kit of the NativeMind framework: dome picker, connection and engine status, player controls, show timeline, playlists and cues, calibration wizard, projector-rig editor, audio-zone mixer, [...]

example/lib/main.dart

// The nativemind_freedome prototype (task 4.SDK.9): every widget over the fake ports, light / dark, five languages,
// a scripted copilot model. For the owner's review and the Figma export.
// written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:nativemind_copilot/nativemind_copilot.dart';
import 'package:nativemind_core/nativemind_core.dart';
import 'package:nativemind_freedome/nativemind_freedome.dart';
import 'package:nativemind_freedome/testing.dart';

// written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
void main() {
  NmFreedomeL10n.installExtraLanguages();
  runApp(const FreedomeKitPrototype());
}

/// A scripted on-device model stand-in: asks for the player state, then pauses / resumes / reads domes.
// written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
class DemoLlm implements NmLlmProvider {
  var _n = 0;

  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  @override
  bool get holdsKeys => false;

  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  @override
  Stream<NmLlmChunk> complete(NmLlmRequest r) async* {
    await Future<void>.delayed(const Duration(milliseconds: 400));
    final last = r.messages.last;
    final user = r.messages.lastWhere((m) => m.role == NmLlmRole.user).text.toLowerCase();
    if (last.role == NmLlmRole.user && r.tools.isNotEmpty) {
      final tool = user.contains('pause') || user.contains('пауз')
          ? 'pause'
          : user.contains('calibr') || user.contains('калибр')
          ? 'calibration_status'
          : 'list_domes';
      yield NmLlmToolCallsChunk([NmLlmToolCall(id: 'call${_n++}', name: tool, args: const {})]);
      return;
    }
    final result = last.role == NmLlmRole.tool ? last.text : '';
    for (final w in 'Done. ${result.length > 160 ? '${result.substring(0, 160)}…' : result}'.split(' ')) {
      await Future<void>.delayed(const Duration(milliseconds: 30));
      yield NmLlmTextChunk('$w ');
    }
  }
}

/// The prototype app.
// written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
class FreedomeKitPrototype extends StatefulWidget {
  /// Creates the app.
  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  const FreedomeKitPrototype({super.key});

  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  @override
  State<FreedomeKitPrototype> createState() => _FreedomeKitPrototypeState();
}

// written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
class _FreedomeKitPrototypeState extends State<FreedomeKitPrototype> {
  final _fakes = NmFreedomeFakes();
  final _llm = DemoLlm();
  Timer? _meters;
  var _tick = 0;
  var _dark = false;
  var _locale = const Locale('en');
  var _page = 0;

  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  @override
  void initState() {
    super.initState();
    _meters = Timer.periodic(const Duration(milliseconds: 50), (_) => _fakes.audioZones.emit(NmFreedomeFakes.demoLevels(_tick++)));
  }

  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  @override
  void dispose() {
    _meters?.cancel();
    super.dispose();
  }

  // written by Claude Code (generated by Claude Code), 2026-10-20; SDD: flows/sdd-nativemind-freedome
  @override
  Widget build(BuildContext context) {
    final pages = <(String, NmIconData, Widget)>[
      (
        'Connection',
        NmFugue.globeNetwork,
        Column(
          children: [
            const NmDomeConnectionStatus(compact: true),
            const SizedBox(height: 12),
            NmDomePicker(onScanQr: (_) async => 'freedome://pair?code=DEMO', onOpenSettings: () {}),
            const SizedBox(height: 12),
            NmDomeConnectionStatus(onRetry: () {}, onSignIn: () {}),
            const SizedBox(height: 12),
            const NmEngineStatusPanel(),
          ],
        ),
      ),
      (
        'Player',
        NmFugue.mediaPlayer,
        const Column(
          children: [
            NmDomePlayerControls(compact: true),
            SizedBox(height: 12),
            NmDomePlayerControls(),
            SizedBox(height: 12),
            NmShowTimeline(),
            SizedBox(height: 12),
            NmPlaylistView(),
            SizedBox(height: 12),
            NmCueList(),
          ],
        ),
      ),
      (
        'Calibration',
        NmFugue.target,
        Column(
          children: [
            NmCalibrationWizard(onCapture: (_) async => Uint8List.fromList(List.filled(16, 1))),
            const SizedBox(height: 12),
            const NmCalibrationWizard(plan: NmDomeCalibrationPlan(kind: NmDomeCalibrationKind.audio)),
            const SizedBox(height: 12),
            const NmProjectorRigEditor(),
          ],
        ),
      ),
      ('Audio', NmFugue.speakerVolumeControl, const NmAudioZoneMixer()),
      ('Venues', NmFugue.map, const NmVenueMap(pins: nmDemoVenues)),
      ('Copilot', NmFugue.robot, SizedBox(height: 640, child: NmFreedomeCopilot(provider: _llm))),
    ];
    return NmFreedomeScope.ports(
      ports: _fakes.ports,
      child: MaterialApp(
        title: 'Freedome kit',
        debugShowCheckedModeBanner: false,
        locale: _locale,
        supportedLocales: const [Locale('en'), Locale('ru'), Locale('th'), Locale('hi'), Locale('zh')],
        localizationsDelegates: NmApp.delegates([NmFreedomeL10n.delegate, NmCopilot.delegate]),
        theme: const NmTheme().toThemeData(Brightness.light),
        darkTheme: const NmTheme().toThemeData(Brightness.dark),
        themeMode: _dark ? ThemeMode.dark : ThemeMode.light,
        home: Builder(
          builder: (context) => Scaffold(
            appBar: AppBar(
              title: Text('Freedome kit · ${pages[_page].$1}'),
              actions: [
                for (final l in const ['en', 'ru', 'th', 'hi', 'zh'])
                  TextButton(
                    onPressed: () => setState(() => _locale = Locale(l)),
                    child: Text(l, style: TextStyle(fontWeight: _locale.languageCode == l ? FontWeight.bold : null)),
                  ),
                NmFreedomeIconButton(icon: _dark ? NmFugue.lightBulb : NmFugue.lightBulbOff, label: 'Theme', onPressed: () => setState(() => _dark = !_dark)),
              ],
            ),
            body: Row(
              children: [
                NavigationRail(
                  selectedIndex: _page,
                  onDestinationSelected: (i) => setState(() => _page = i),
                  labelType: NavigationRailLabelType.all,
                  destinations: [for (final p in pages) NavigationRailDestination(icon: NmIcon(p.$2), label: Text(p.$1))],
                ),
                Expanded(
                  child: SingleChildScrollView(
                    padding: const EdgeInsets.all(16),
                    child: Align(
                      alignment: Alignment.topCenter,
                      child: ConstrainedBox(constraints: const BoxConstraints(maxWidth: 960), child: pages[_page].$3),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
0
likes
140
points
29
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Fulldome UI kit of the NativeMind framework: dome picker, connection and engine status, player controls, show timeline, playlists and cues, calibration wizard, projector-rig editor, audio-zone mixer, venue map slot and the dome copilot panel. Ports only — apps (or the freedome_flutter glue) implement them on the Freedome SDK.

Homepage
Repository (GitLab)

Topics

#widget #fulldome #projection #design-system

License

unknown (license)

Dependencies

flutter, flutter_localizations, intl, nativemind_copilot, nativemind_core, nativemind_icons_fugue, nativemind_translations

More

Packages that depend on nativemind_freedome