fr_mvvm_theme 0.0.2 copy "fr_mvvm_theme: ^0.0.2" to clipboard
fr_mvvm_theme: ^0.0.2 copied to clipboard

Theme switching helpers for FlowR MVVM Flutter apps, including theme models, ThemeExtension utilities, image scheme parsing, and menu UI.

example/lib/main.dart

import 'dart:async' show unawaited;
import 'dart:convert' show jsonDecode;

import 'package:flowr/flowr_mvvm.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:fr_mvvm_theme/fr_mvvm_theme.dart';
import 'package:json_annotation/json_annotation.dart';

part 'main.g.dart';

@JsonSerializable(converters: [FrColorCvt()])
class LoginTheme extends FrPageTheme<LoginTheme> {
  final Color welcomeColor;
  final String logoImg;

  const LoginTheme({required this.welcomeColor, required this.logoImg});

  factory LoginTheme.fromJson(Map<String, dynamic> json) =>
      _$LoginThemeFromJson(json);

  @override
  Map<String, dynamic> toJson() => _$LoginThemeToJson(this);
}

@JsonSerializable(explicitToJson: true)
class ThemeConfig {
  final String themeId;
  final String source;
  final int priority;
  final LoginTheme login;

  const ThemeConfig({
    required this.themeId,
    required this.source,
    required this.priority,
    required this.login,
  });

  factory ThemeConfig.fromJson(Map<String, dynamic> json) =>
      _$ThemeConfigFromJson(json);

  Map<String, dynamic> toJson() => _$ThemeConfigToJson(this);

  AppThemeModel toThemeModel() => AppThemeModel(
    themeId: themeId,
    source: source,
    priority: priority,
    extensions: [login],
  );
}

class AppThemeModel extends FrThemeModel {
  final String source;

  const AppThemeModel({
    required super.themeId,
    required this.source,
    super.priority,
    super.extensions,
  });
}

const builtInTheme = AppThemeModel(
  themeId: 'built_in',
  source: 'code',
  extensions: [
    LoginTheme(
      welcomeColor: Colors.black87,
      logoImg: 'asset://assets/logo/built_in.png',
    ),
  ],
);

class AppThemeViewModel extends IThemeViewModel<AppThemeModel> {
  AppThemeViewModel() : super(builtInTheme) {
    unawaited(loadThemeConfig());
  }

  final List<AppThemeModel> _all = [builtInTheme];

  @override
  Iterable<AppThemeModel> get all => _all;

  Future<void> loadThemeConfig() async {
    final raw = await rootBundle.loadString('assets/theme_config.json');
    final config = ThemeConfig.fromJson(
      jsonDecode(raw) as Map<String, dynamic>,
    );
    final theme = config.toThemeModel();
    _all.removeWhere((item) => item.themeId == theme.themeId);
    _all.add(theme);
    await updateTheme(theme);
  }
}

void main() {
  runApp(
    FrProvider(
      (context) => AppThemeViewModel(),
      child: FrView<AppThemeViewModel, AppThemeModel>(
        builder: (context, state, _) => MaterialApp(
          theme: ThemeData(extensions: state.data.extensions),
          home: const Scaffold(body: Center(child: ThemePreview())),
        ),
      ),
    ),
  );
}

class ThemePreview extends StatelessWidget {
  const ThemePreview({super.key});

  @override
  Widget build(BuildContext context) =>
      FrView<AppThemeViewModel, AppThemeModel>(
        builder: (context, state, _) {
          final theme = context.ofThm<LoginTheme>();
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              DecoratedBox(
                decoration: BoxDecoration(
                  color: theme.welcomeColor.withValues(alpha: 0.08),
                  borderRadius: BorderRadius.circular(20),
                  border: Border.all(
                    color: theme.welcomeColor.withValues(alpha: 0.24),
                  ),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(16),
                  child: Image(
                    image: theme.logoImg.asImageProvider,
                    width: 72,
                    height: 72,
                    fit: BoxFit.contain,
                  ),
                ),
              ),
              const SizedBox(height: 12),
              Text('themeId: ${state.data.themeId}'),
              Text('source: ${state.data.source}'),
              Text(
                'welcomeColor: ${theme.toJson()['welcomeColor']}',
                style: TextStyle(color: theme.welcomeColor),
              ),
              Text('logoImg: ${theme.logoImg}'),
              const SizedBox(height: 16),
              FrThemeSwitchView<AppThemeViewModel, AppThemeModel>(
                buildAnchorTile: (context, theme) => Text(
                  '${theme.themeId} (${theme.source})',
                  style: const TextStyle(color: Colors.black87),
                ),
              ),
            ],
          );
        },
      );
}
0
likes
0
points
392
downloads

Publisher

verified publisherwyattcoder.top

Weekly Downloads

Theme switching helpers for FlowR MVVM Flutter apps, including theme models, ThemeExtension utilities, image scheme parsing, and menu UI.

Repository (GitHub)
View/report issues

Topics

#flowr #theme

License

unknown (license)

Dependencies

flowr, flutter, json_annotation

More

Packages that depend on fr_mvvm_theme