chat and theme work

This commit is contained in:
Christien Rioux 2023-07-29 10:55:35 -04:00
parent ca6b00e021
commit 96e3251b3b
29 changed files with 729 additions and 389 deletions

View file

@ -46,6 +46,9 @@
"invalid_account_title": "Missing Account", "invalid_account_title": "Missing Account",
"invalid_account_text": "Account is missing, removing from list" "invalid_account_text": "Account is missing, removing from list"
}, },
"empty_contact_list": {
"invite_people": "Invite people to VeilidChat"
},
"themes": { "themes": {
"vapor": "Vapor" "vapor": "Vapor"
} }

View file

@ -1,49 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Chat extends ConsumerWidget {
const Chat({super.key});
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context, WidgetRef ref) {
//
return Align(
alignment: AlignmentDirectional.centerEnd,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
child: Stack(
children: [
Column(
children: [
Container(
height: 48,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
),
child: Align(
alignment: AlignmentDirectional.centerStart,
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(16, 0, 16, 0),
child: Text("current contact",
textAlign: TextAlign.start,
style: Theme.of(context).textTheme.titleMedium),
),
),
),
Expanded(
child: Container(
decoration: const BoxDecoration(),
child: Text("Chat"),
),
),
],
),
],
),
));
}
}

View file

@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:intl/date_symbol_data_local.dart';
import 'package:uuid/uuid.dart';
class ChatComponent extends ConsumerStatefulWidget {
const ChatComponent({super.key});
@override
ChatComponentState createState() => ChatComponentState();
}
class ChatComponentState extends ConsumerState<ChatComponent> {
List<types.Message> _messages = [];
final _unfocusNode = FocusNode();
@override
void initState() {
super.initState();
_loadMessages();
}
@override
void dispose() {
_unfocusNode.dispose();
super.dispose();
}
void _loadMessages() {
final messages = <types.Message>[
types.TextMessage(
id: "abcd",
text: "Hello!",
author: types.User(
id: "1234",
firstName: "Foo",
lastName: "Bar",
role: types.Role.user))
];
_messages = messages;
}
final _user = const types.User(
id: '82091008-a484-4a89-ae75-a22bf8d6f3ac',
);
void _addMessage(types.Message message) {
setState(() {
_messages.insert(0, message);
});
}
void _handleSendPressed(types.PartialText message) {
final textMessage = types.TextMessage(
author: _user,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: message.text,
);
_addMessage(textMessage);
}
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context) {
//
return Align(
alignment: AlignmentDirectional.centerEnd,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
child: Stack(
children: [
Column(
children: [
Container(
height: 48,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
),
child: Align(
alignment: AlignmentDirectional.centerStart,
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(16, 0, 16, 0),
child: Text("current contact",
textAlign: TextAlign.start,
style: Theme.of(context).textTheme.titleMedium),
),
),
),
Expanded(
child: Container(
decoration: const BoxDecoration(),
child: Chat(
//theme: _chatTheme,
messages: _messages,
//onAttachmentPressed: _handleAttachmentPressed,
//onMessageTap: _handleMessageTap,
//onPreviewDataFetched: _handlePreviewDataFetched,
onSendPressed: _handleSendPressed,
showUserAvatars: true,
showUserNames: true,
user: _user,
),
),
),
],
),
],
),
));
}
}

View file

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../entities/proto.dart' as proto;
import 'empty_contact_list_widget.dart';
class ContactListWidget extends ConsumerWidget {
const ContactListWidget({required this.contactList, super.key});
final List<proto.Contact> contactList;
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context, WidgetRef ref) {
//
if (contactList.isEmpty) {
return const EmptyContactListWidget();
}
return Container(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.group_add,
color: Theme.of(context).disabledColor,
size: 48,
),
Text(
'Contacts',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).disabledColor,
),
),
],
),
);
}
}

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
class EmptyChatComponentWidget extends ConsumerWidget { class EmptyChatWidget extends ConsumerWidget {
const EmptyChatComponentWidget({super.key}); const EmptyChatWidget({super.key});
@override @override
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies

View file

@ -1,16 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
class EmptyContactListComponentWidget extends ConsumerWidget { class EmptyContactListWidget extends ConsumerWidget {
const EmptyContactListComponentWidget({super.key}); const EmptyContactListWidget({super.key});
@override @override
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
// //
return Container( return Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor, color: Theme.of(context).scaffoldBackgroundColor,
), ),
@ -18,12 +17,12 @@ class EmptyContactListComponentWidget extends ConsumerWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(
Icons.group_add, Icons.person_add_sharp,
color: Theme.of(context).disabledColor, color: Theme.of(context).disabledColor,
size: 48, size: 48,
), ),
Text( Text(
'Start A Conversation', translate('empty_contact_list.invite_people'),
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).disabledColor, color: Theme.of(context).disabledColor,
), ),

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
class NoContactComponentWidget extends ConsumerWidget { class NoContactWidget extends ConsumerWidget {
const NoContactComponentWidget({super.key}); const NoContactWidget({super.key});
@override @override
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies

View file

@ -143,7 +143,7 @@ message Attachment {
} }
// A single message as part of a series of messages // A single message as part of a series of messages
// Messages are stored in an append-only log in DHT // Messages are stored in a DHTLog
message Message { message Message {
// Author of the message // Author of the message
TypedKey author = 1; TypedKey author = 1;
@ -210,9 +210,6 @@ enum Availability {
// Name - Friendly name // Name - Friendly name
// Title - Title of user // Title - Title of user
// Icon - Little picture to represent user in contact list // Icon - Little picture to represent user in contact list
//
// DHT Key: None
// Encryption: None
message Profile { message Profile {
// Friendy name // Friendy name
string name = 1; string name = 1;
@ -230,8 +227,7 @@ message Profile {
// Pointed to by the identity account map in the identity key // Pointed to by the identity account map in the identity key
// //
// DHT Schema: DFLT(1) // DHT Schema: DFLT(1)
// DHT Key (Private): accountPublicKey // DHT Private: accountSecretKey
// DHT Secret: accountSecretKey
message Account { message Account {
// The user's profile that gets shared with contacts // The user's profile that gets shared with contacts
Profile profile = 1; Profile profile = 1;
@ -240,6 +236,6 @@ message Account {
// Auto-away sets 'away' mode after an inactivity time // Auto-away sets 'away' mode after an inactivity time
uint32 auto_away_timeout_sec = 3; uint32 auto_away_timeout_sec = 3;
// The contacts DHTList for this account // The contacts DHTList for this account
// Schema: SMPL(0,64,[accountPublicKey]) Encryption: accountSecretKey // DHT Private: accountSecretKey
TypedKey contact_list = 4; TypedKey contact_list = 4;
} }

View file

@ -1,11 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:multi_split_view/multi_split_view.dart'; import 'package:split_view/split_view.dart';
import 'package:signal_strength_indicator/signal_strength_indicator.dart'; import 'package:signal_strength_indicator/signal_strength_indicator.dart';
import '../components/chat.dart'; import '../components/chat_component.dart';
import '../components/chat_list.dart';
import '../providers/window_control.dart'; import '../providers/window_control.dart';
import '../tools/tools.dart'; import '../tools/tools.dart';
import 'main_pager/main_pager.dart'; import 'main_pager/main_pager.dart';
@ -22,37 +21,10 @@ class HomePageState extends ConsumerState<HomePage>
with TickerProviderStateMixin { with TickerProviderStateMixin {
final _unfocusNode = FocusNode(); final _unfocusNode = FocusNode();
final MultiSplitViewController _splitController = MultiSplitViewController(
areas: [Area(minimalSize: 300, weight: 0.25), Area(minimalSize: 300)]);
final scaffoldKey = GlobalKey<ScaffoldState>();
bool hasContainerTriggered = false;
final animationsMap = {
'containerOnActionTriggerAnimation': AnimationInfo(
trigger: AnimationTrigger.onActionTrigger,
applyInitialState: false,
effects: [
MoveEffect(
curve: Curves.bounceOut,
delay: 0.ms,
duration: 500.ms,
begin: const Offset(100, 0),
end: Offset.zero,
),
],
),
};
@override @override
void initState() { void initState() {
super.initState(); super.initState();
setupAnimations(
animationsMap.values.where((anim) =>
anim.trigger == AnimationTrigger.onActionTrigger ||
!anim.applyInitialState),
this,
);
WidgetsBinding.instance.addPostFrameCallback((_) async { WidgetsBinding.instance.addPostFrameCallback((_) async {
setState(() {}); setState(() {});
await ref.read(windowControlProvider.notifier).changeWindowSetup( await ref.read(windowControlProvider.notifier).changeWindowSetup(
@ -83,34 +55,35 @@ class HomePageState extends ConsumerState<HomePage>
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies
Widget buildTabletRightPane(BuildContext context) { Widget buildTabletRightPane(BuildContext context) {
// //
return Chat(); return ChatComponent();
} }
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies
Widget buildTablet(BuildContext context) { Widget buildTablet(BuildContext context) {
final theme = Theme.of(context);
final w = MediaQuery.of(context).size.width;
final children = [ final children = [
buildTabletLeftPane(context), ConstrainedBox(
buildTabletRightPane(context), constraints: BoxConstraints(minWidth: 300, maxWidth: 300),
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: w / 2),
child: buildTabletLeftPane(context))),
Expanded(child: buildTabletRightPane(context)),
]; ];
final multiSplitView = MultiSplitView( return Row(
// onWeightChange: _onWeightChange, children: children,
// onDividerTap: _onDividerTap, );
// onDividerDoubleTap: _onDividerDoubleTap,
controller: _splitController,
children: children);
final theme = MultiSplitViewTheme( // final theme = MultiSplitViewTheme(
data: isDesktop // data: isDesktop
? MultiSplitViewThemeData( // ? MultiSplitViewThemeData(
dividerThickness: 1, // dividerThickness: 1,
dividerPainter: DividerPainters.grooved2(thickness: 1)) // dividerPainter: DividerPainters.grooved2(thickness: 1))
: MultiSplitViewThemeData( // : MultiSplitViewThemeData(
dividerThickness: 3, // dividerThickness: 3,
dividerPainter: DividerPainters.grooved2(thickness: 1)), // dividerPainter: DividerPainters.grooved2(thickness: 1)),
child: multiSplitView); // child: multiSplitView);
return theme;
} }
@override @override

View file

@ -1,67 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:window_manager/window_manager.dart';
import '../components/account_bubble.dart';
import '../providers/local_accounts.dart';
import '../providers/logins.dart';
class LoginPage extends ConsumerWidget {
const LoginPage({super.key});
static const path = '/login';
// void _onReorder(WidgetRef ref, int oldIndex, int newIndex) {
// final accounts = ref.read(localAccountsProvider.notifier);
// accounts.reorderAccount(oldIndex, newIndex);
// // xxx fix this so we can await this properly, use FutureBuilder or whatever
// }
@override
Widget build(BuildContext context, WidgetRef ref) {
windowManager.setTitleBarStyle(TitleBarStyle.normal);
final accounts = ref.watch(localAccountsProvider);
final logins = ref.watch(loginsProvider);
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Accounts'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.settings),
tooltip: 'Accessibility',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content:
Text('Accessibility and language options coming soon')));
},
),
],
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(height: 100, color: const Color.fromARGB(255, 255, 0, 0)),
const Spacer(),
// accounts.when(
// error: (obj, err) => Text("error loading accounts: $err"),
// loading: () => CircularProgressIndicator(),
// data: (accountList) => ReorderableGridView.extent(
// maxCrossAxisExtent: 128,
// onReorder: (oldIndex, newIndex) =>
// _onReorder(ref, oldIndex, newIndex),
// children: accountList.map<Widget>((account) {
// return AccountBubble(
// key: ValueKey(
// account.identityMaster.masterRecordKey),
// account: account);
// }).toList(),
// )),
const AddAccountBubble(key: ValueKey('+')),
const Spacer(),
Container(height: 100, color: const Color.fromARGB(255, 0, 255, 0)),
],
),
);
}
}

View file

@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart'; import 'package:flutter_translate/flutter_translate.dart';
import 'package:veilid/veilid.dart'; import 'package:veilid/veilid.dart';
import '../../components/contact_list_widget.dart';
import '../../components/profile.dart'; import '../../components/profile.dart';
import '../../entities/local_account.dart'; import '../../entities/local_account.dart';
import '../../entities/proto.dart' as proto; import '../../entities/proto.dart' as proto;
@ -23,6 +24,7 @@ class AccountPage extends ConsumerStatefulWidget {
class AccountPageState extends ConsumerState<AccountPage> { class AccountPageState extends ConsumerState<AccountPage> {
final _unfocusNode = FocusNode(); final _unfocusNode = FocusNode();
TypedKey? _selectedAccount; TypedKey? _selectedAccount;
List<proto.Contact> _contactList = List<proto.Contact>.empty(growable: true);
@override @override
void initState() { void initState() {
@ -36,13 +38,11 @@ class AccountPageState extends ConsumerState<AccountPage> {
super.dispose(); super.dispose();
} }
@override
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies
Widget buildAccountList(BuildContext context) { Widget buildAccountList(BuildContext context) {
return Center(child: Text("account list")); return Center(child: Text("account list"));
} }
@override
Widget buildUnlockAccount( Widget buildUnlockAccount(
BuildContext context, BuildContext context,
IList<LocalAccount> localAccounts, IList<LocalAccount> localAccounts,
@ -51,7 +51,6 @@ class AccountPageState extends ConsumerState<AccountPage> {
return Center(child: Text("unlock account")); return Center(child: Text("unlock account"));
} }
@override
Widget buildUserAccount( Widget buildUserAccount(
BuildContext context, BuildContext context,
IList<LocalAccount> localAccounts, IList<LocalAccount> localAccounts,
@ -59,8 +58,10 @@ class AccountPageState extends ConsumerState<AccountPage> {
proto.Account account, proto.Account account,
// ignore: prefer_expression_function_bodies // ignore: prefer_expression_function_bodies
) { ) {
return ProfileWidget( return Column(children: <Widget>[
name: account.profile.name, title: account.profile.title); ProfileWidget(name: account.profile.name, title: account.profile.title),
ContactListWidget(contactList: _contactList)
]);
} }
@override @override

View file

@ -1,30 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class ContactsPage extends ConsumerStatefulWidget {
const ContactsPage({super.key});
@override
ContactsPageState createState() => ContactsPageState();
}
class ContactsPageState extends ConsumerState<ContactsPage> {
final _unfocusNode = FocusNode();
@override
void initState() {
super.initState();
}
@override
void dispose() {
_unfocusNode.dispose();
super.dispose();
}
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context) {
return Center(child: Text("Contacts Page"));
}
}

View file

@ -7,7 +7,6 @@ import 'package:stylish_bottom_bar/model/bar_items.dart';
import 'package:stylish_bottom_bar/stylish_bottom_bar.dart'; import 'package:stylish_bottom_bar/stylish_bottom_bar.dart';
import 'account_page.dart'; import 'account_page.dart';
import 'contacts_page.dart';
import 'chats_page.dart'; import 'chats_page.dart';
class MainPager extends ConsumerStatefulWidget { class MainPager extends ConsumerStatefulWidget {
@ -26,30 +25,22 @@ class MainPagerState extends ConsumerState<MainPager>
final _pageController = PageController(); final _pageController = PageController();
var _currentPage = 0; var _currentPage = 0;
final _selectedIconList = <IconData>[ final _selectedIconList = <IconData>[Icons.person, Icons.chat];
Icons.chat,
Icons.contacts,
Icons.person
];
// final _unselectedIconList = <IconData>[ // final _unselectedIconList = <IconData>[
// Icons.chat_outlined, // Icons.chat_outlined,
// Icons.contacts_outlined,
// Icons.person_outlined // Icons.person_outlined
// ]; // ];
final _fabIconList = <IconData>[ final _fabIconList = <IconData>[
Icons.add_comment_sharp,
Icons.person_add_sharp, Icons.person_add_sharp,
Icons.settings_sharp, Icons.add_comment_sharp,
]; ];
final _labelList = <String>[ final _labelList = <String>[
translate('pager.chats'),
translate('pager.contacts'),
translate('pager.account'), translate('pager.account'),
translate('pager.chats'),
]; ];
final List<Widget> _bottomBarPages = [ final List<Widget> _bottomBarPages = [
const ChatsPage(),
const ContactsPage(),
const AccountPage(), const AccountPage(),
const ChatsPage(),
]; ];
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -154,7 +145,7 @@ class MainPagerState extends ConsumerState<MainPager>
currentIndex: _currentPage, currentIndex: _currentPage,
onTap: (index) async { onTap: (index) async {
await _pageController.animateToPage(index, await _pageController.animateToPage(index,
duration: 250.ms, curve: Curves.bounceOut); duration: 250.ms, curve: Curves.easeInOut);
setState(() { setState(() {
_currentPage = index; _currentPage = index;
}); });

View file

@ -29,6 +29,17 @@ class NewAccountPageState extends ConsumerState<NewAccountPage> {
static const String formFieldName = 'name'; static const String formFieldName = 'name';
static const String formFieldTitle = 'title'; static const String formFieldTitle = 'title';
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
setState(() {});
await ref.read(windowControlProvider.notifier).changeWindowSetup(
TitleBarStyle.normal, OrientationCapability.portraitOnly);
});
}
Future<void> createAccount() async { Future<void> createAccount() async {
final imws = await newIdentityMaster(); final imws = await newIdentityMaster();
try { try {

View file

@ -1,4 +0,0 @@
export 'home.dart';
export 'index.dart';
export 'login.dart';
export 'new_account.dart';

View file

@ -112,7 +112,7 @@ class FetchLocalAccountProvider
} }
} }
String _$localAccountsHash() => r'c8214abbc9720449910e74e32fc52d53ca4453c0'; String _$localAccountsHash() => r'd6ced0ad7108c1111603235cf394faa5f6bcdae1';
/// See also [LocalAccounts]. /// See also [LocalAccounts].
@ProviderFor(LocalAccounts) @ProviderFor(LocalAccounts)

View file

@ -1,4 +1,4 @@
export 'account_profile.dart'; export 'account.dart';
export 'connection_state.dart'; export 'connection_state.dart';
export 'local_accounts.dart'; export 'local_accounts.dart';
export 'logins.dart'; export 'logins.dart';

View file

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../pages/pages.dart'; import '../pages/index.dart';
import 'router_notifier.dart'; import 'router_notifier.dart';
part 'router.g.dart'; part 'router.g.dart';

View file

@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../pages/pages.dart'; import '../pages/home.dart';
import '../pages/index.dart';
import '../pages/new_account.dart';
import '../providers/local_accounts.dart'; import '../providers/local_accounts.dart';
part 'router_notifier.g.dart'; part 'router_notifier.g.dart';

View file

@ -1,6 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:radix_colors/radix_colors.dart'; import 'package:radix_colors/radix_colors.dart';
import 'theme_service.dart';
enum RadixThemeColor { enum RadixThemeColor {
scarlet, // tomato + red + violet scarlet, // tomato + red + violet
babydoll, // crimson + purple + pink babydoll, // crimson + purple + pink
@ -265,174 +268,247 @@ RadixColor _radixColorSteps(
} }
} }
ColorScheme _radixColorScheme( extension ToScaleColor on RadixColor {
// ignore: prefer_expression_function_bodies ScaleColor toScale() => ScaleColor(
Brightness brightness, appBackground: step1,
RadixThemeColor themeColor) { subtleBackground: step2,
late RadixColor primaryScale; elementBackground: step3,
late RadixColor primaryAlphaScale; hoverElementBackground: step4,
late RadixColor secondaryScale; activedElementBackground: step5,
late RadixColor tertiaryScale; subtleBorder: step6,
late RadixColor grayScale; border: step7,
late RadixColor errorScale; hoverBorder: step8,
background: step9,
hoverBackground: step10,
subtleText: step11,
text: step12,
);
}
class RadixScheme {
RadixScheme(
{required this.primaryScale,
required this.primaryAlphaScale,
required this.secondaryScale,
required this.tertiaryScale,
required this.grayScale,
required this.errorScale});
RadixColor primaryScale;
RadixColor primaryAlphaScale;
RadixColor secondaryScale;
RadixColor tertiaryScale;
RadixColor grayScale;
RadixColor errorScale;
ScaleScheme toScale() => ScaleScheme(
primaryScale: primaryScale.toScale(),
primaryAlphaScale: primaryAlphaScale.toScale(),
secondaryScale: secondaryScale.toScale(),
tertiaryScale: tertiaryScale.toScale(),
grayScale: grayScale.toScale(),
errorScale: errorScale.toScale(),
);
}
RadixScheme _radixScheme(Brightness brightness, RadixThemeColor themeColor) {
late RadixScheme radixScheme;
switch (themeColor) { switch (themeColor) {
// tomato + red + violet // tomato + red + violet
case RadixThemeColor.scarlet: case RadixThemeColor.scarlet:
primaryScale = radixScheme = RadixScheme(
_radixColorSteps(brightness, false, _RadixBaseColor.tomato); primaryScale:
primaryAlphaScale = _radixColorSteps(brightness, false, _RadixBaseColor.tomato),
_radixColorSteps(brightness, true, _RadixBaseColor.tomato); primaryAlphaScale:
secondaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.red); _radixColorSteps(brightness, true, _RadixBaseColor.tomato),
tertiaryScale = secondaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.violet); _radixColorSteps(brightness, false, _RadixBaseColor.red),
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.tomato); tertiaryScale:
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.yellow); _radixColorSteps(brightness, false, _RadixBaseColor.violet),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.tomato),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.yellow));
// crimson + purple + pink // crimson + purple + pink
case RadixThemeColor.babydoll: case RadixThemeColor.babydoll:
primaryScale = radixScheme = RadixScheme(
_radixColorSteps(brightness, false, _RadixBaseColor.crimson); primaryScale:
primaryAlphaScale = _radixColorSteps(brightness, false, _RadixBaseColor.crimson),
_radixColorSteps(brightness, true, _RadixBaseColor.crimson); primaryAlphaScale:
secondaryScale = _radixColorSteps(brightness, true, _RadixBaseColor.crimson),
_radixColorSteps(brightness, false, _RadixBaseColor.purple); secondaryScale:
tertiaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.pink); _radixColorSteps(brightness, false, _RadixBaseColor.purple),
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.crimson); tertiaryScale:
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.orange); _radixColorSteps(brightness, false, _RadixBaseColor.pink),
grayScale:
_radixGraySteps(brightness, false, _RadixBaseColor.crimson),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.orange));
// pink + cyan + plum // pink + cyan + plum
case RadixThemeColor.vapor: case RadixThemeColor.vapor:
primaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.pink); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.pink); _radixColorSteps(brightness, false, _RadixBaseColor.pink),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.cyan); _radixColorSteps(brightness, true, _RadixBaseColor.pink),
tertiaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.plum); secondaryScale:
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.pink); _radixColorSteps(brightness, false, _RadixBaseColor.cyan),
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.red); tertiaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.plum),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.pink),
errorScale: _radixColorSteps(brightness, false, _RadixBaseColor.red));
// yellow + amber + orange // yellow + amber + orange
case RadixThemeColor.gold: case RadixThemeColor.gold:
primaryScale = radixScheme = RadixScheme(
_radixColorSteps(brightness, false, _RadixBaseColor.yellow); primaryScale:
primaryAlphaScale = _radixColorSteps(brightness, false, _RadixBaseColor.yellow),
_radixColorSteps(brightness, true, _RadixBaseColor.yellow); primaryAlphaScale:
secondaryScale = _radixColorSteps(brightness, true, _RadixBaseColor.yellow),
_radixColorSteps(brightness, false, _RadixBaseColor.amber); secondaryScale:
tertiaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.amber),
_radixColorSteps(brightness, false, _RadixBaseColor.orange); tertiaryScale:
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.yellow); _radixColorSteps(brightness, false, _RadixBaseColor.orange),
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.red); grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.yellow),
errorScale: _radixColorSteps(brightness, false, _RadixBaseColor.red));
// grass + orange + brown // grass + orange + brown
case RadixThemeColor.garden: case RadixThemeColor.garden:
primaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.grass); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.grass); _radixColorSteps(brightness, false, _RadixBaseColor.grass),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.orange); _radixColorSteps(brightness, true, _RadixBaseColor.grass),
tertiaryScale = secondaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.brown); _radixColorSteps(brightness, false, _RadixBaseColor.orange),
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.grass); tertiaryScale:
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.tomato); _radixColorSteps(brightness, false, _RadixBaseColor.brown),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.grass),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.tomato));
// green + brown + amber // green + brown + amber
case RadixThemeColor.forest: case RadixThemeColor.forest:
primaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.green); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.green); _radixColorSteps(brightness, false, _RadixBaseColor.green),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.brown); _radixColorSteps(brightness, true, _RadixBaseColor.green),
tertiaryScale = secondaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.amber); _radixColorSteps(brightness, false, _RadixBaseColor.brown),
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.green); tertiaryScale:
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.tomato); _radixColorSteps(brightness, false, _RadixBaseColor.amber),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.green),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.tomato));
// sky + teal + violet // sky + teal + violet
case RadixThemeColor.arctic: case RadixThemeColor.arctic:
primaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.sky); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.sky); _radixColorSteps(brightness, false, _RadixBaseColor.sky),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.teal); _radixColorSteps(brightness, true, _RadixBaseColor.sky),
tertiaryScale = secondaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.violet); _radixColorSteps(brightness, false, _RadixBaseColor.teal),
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.sky); tertiaryScale:
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.crimson); _radixColorSteps(brightness, false, _RadixBaseColor.violet),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.sky),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.crimson));
// blue + indigo + mint // blue + indigo + mint
case RadixThemeColor.lapis: case RadixThemeColor.lapis:
primaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.blue); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.blue); _radixColorSteps(brightness, false, _RadixBaseColor.blue),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.indigo); _radixColorSteps(brightness, true, _RadixBaseColor.blue),
tertiaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.mint); secondaryScale:
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.blue); _radixColorSteps(brightness, false, _RadixBaseColor.indigo),
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.crimson); tertiaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.mint),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.blue),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.crimson));
// violet + purple + indigo // violet + purple + indigo
case RadixThemeColor.eggplant: case RadixThemeColor.eggplant:
primaryScale = radixScheme = RadixScheme(
_radixColorSteps(brightness, false, _RadixBaseColor.violet); primaryScale:
primaryAlphaScale = _radixColorSteps(brightness, false, _RadixBaseColor.violet),
_radixColorSteps(brightness, true, _RadixBaseColor.violet); primaryAlphaScale:
secondaryScale = _radixColorSteps(brightness, true, _RadixBaseColor.violet),
_radixColorSteps(brightness, false, _RadixBaseColor.purple); secondaryScale:
tertiaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.purple),
_radixColorSteps(brightness, false, _RadixBaseColor.indigo); tertiaryScale:
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.violet); _radixColorSteps(brightness, false, _RadixBaseColor.indigo),
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.crimson); grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.violet),
errorScale:
_radixColorSteps(brightness, false, _RadixBaseColor.crimson));
// lime + yellow + orange // lime + yellow + orange
case RadixThemeColor.lime: case RadixThemeColor.lime:
primaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.lime); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.lime); _radixColorSteps(brightness, false, _RadixBaseColor.lime),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.yellow); _radixColorSteps(brightness, true, _RadixBaseColor.lime),
tertiaryScale = secondaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.orange); _radixColorSteps(brightness, false, _RadixBaseColor.yellow),
grayScale = _radixGraySteps(brightness, false, _RadixBaseColor.lime); tertiaryScale:
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.red); _radixColorSteps(brightness, false, _RadixBaseColor.orange),
grayScale: _radixGraySteps(brightness, false, _RadixBaseColor.lime),
errorScale: _radixColorSteps(brightness, false, _RadixBaseColor.red));
// mauve + slate + sage // mauve + slate + sage
case RadixThemeColor.grim: case RadixThemeColor.grim:
primaryScale = _radixGraySteps(brightness, false, _RadixBaseColor.tomato); radixScheme = RadixScheme(
primaryAlphaScale = primaryScale:
_radixColorSteps(brightness, true, _RadixBaseColor.tomato); _radixGraySteps(brightness, false, _RadixBaseColor.tomato),
secondaryScale = primaryAlphaScale:
_radixColorSteps(brightness, false, _RadixBaseColor.indigo); _radixColorSteps(brightness, true, _RadixBaseColor.tomato),
tertiaryScale = _radixColorSteps(brightness, false, _RadixBaseColor.teal); secondaryScale:
grayScale = brightness == Brightness.dark _radixColorSteps(brightness, false, _RadixBaseColor.indigo),
tertiaryScale:
_radixColorSteps(brightness, false, _RadixBaseColor.teal),
grayScale: brightness == Brightness.dark
? RadixColors.dark.gray ? RadixColors.dark.gray
: RadixColors.gray; : RadixColors.gray,
errorScale = _radixColorSteps(brightness, false, _RadixBaseColor.red); errorScale: _radixColorSteps(brightness, false, _RadixBaseColor.red));
}
return radixScheme;
} }
return ColorScheme( ExtendedColorScheme _radixColorScheme(
Brightness brightness, RadixThemeColor themeColor) {
final radix = _radixScheme(brightness, themeColor);
return ExtendedColorScheme(
scaleScheme: radix.toScale(),
brightness: brightness, brightness: brightness,
primary: primaryScale.step9, primary: radix.primaryScale.step9,
onPrimary: primaryScale.step12, onPrimary: radix.primaryScale.step12,
primaryContainer: primaryScale.step3, primaryContainer: radix.primaryScale.step4,
onPrimaryContainer: primaryScale.step11, onPrimaryContainer: radix.primaryScale.step11,
secondary: secondaryScale.step9, secondary: radix.secondaryScale.step9,
onSecondary: secondaryScale.step12, onSecondary: radix.secondaryScale.step12,
secondaryContainer: secondaryScale.step3, secondaryContainer: radix.secondaryScale.step3,
onSecondaryContainer: secondaryScale.step11, onSecondaryContainer: radix.secondaryScale.step11,
tertiary: tertiaryScale.step9, tertiary: radix.tertiaryScale.step9,
onTertiary: tertiaryScale.step12, onTertiary: radix.tertiaryScale.step12,
tertiaryContainer: tertiaryScale.step3, tertiaryContainer: radix.tertiaryScale.step3,
onTertiaryContainer: tertiaryScale.step11, onTertiaryContainer: radix.tertiaryScale.step11,
error: errorScale.step9, error: radix.errorScale.step9,
onError: errorScale.step12, onError: radix.errorScale.step12,
errorContainer: errorScale.step3, errorContainer: radix.errorScale.step3,
onErrorContainer: errorScale.step11, onErrorContainer: radix.errorScale.step11,
background: primaryScale.step1, //gray scale? background: radix.grayScale.step1,
onBackground: primaryScale.step12, onBackground: radix.grayScale.step11,
surface: primaryScale.step2, //gray scale? surface: radix.primaryScale.step1,
onSurface: primaryScale.step11, onSurface: radix.primaryScale.step12,
surfaceVariant: primaryScale.step3, //gray scale? surfaceVariant: radix.secondaryScale.step2,
onSurfaceVariant: primaryScale.step11, onSurfaceVariant: radix.secondaryScale.step11,
outline: primaryScale.step7, outline: radix.primaryScale.step7,
outlineVariant: primaryScale.step6, outlineVariant: radix.primaryScale.step6,
shadow: RadixColors.dark.gray.step1, shadow: RadixColors.dark.gray.step1,
scrim: primaryScale.step4, scrim: radix.primaryScale.step9,
inverseSurface: primaryScale.step11, inverseSurface: radix.primaryScale.step11,
onInverseSurface: primaryScale.step2, onInverseSurface: radix.primaryScale.step2,
inversePrimary: primaryScale.step10, inversePrimary: radix.primaryScale.step10,
surfaceTint: primaryAlphaScale.step9, surfaceTint: radix.primaryAlphaScale.step4,
); );
} }

View file

@ -1,11 +1,112 @@
// ignore_for_file: always_put_required_named_parameters_first
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../entities/preferences.dart'; import '../entities/preferences.dart';
import 'radix_generator.dart'; import 'radix_generator.dart';
@immutable
class ExtendedColorScheme extends ColorScheme {
const ExtendedColorScheme({
required this.scaleScheme,
required super.brightness,
required super.primary,
required super.onPrimary,
super.primaryContainer,
super.onPrimaryContainer,
required super.secondary,
required super.onSecondary,
super.secondaryContainer,
super.onSecondaryContainer,
super.tertiary,
super.onTertiary,
super.tertiaryContainer,
super.onTertiaryContainer,
required super.error,
required super.onError,
super.errorContainer,
super.onErrorContainer,
required super.background,
required super.onBackground,
required super.surface,
required super.onSurface,
super.surfaceVariant,
super.onSurfaceVariant,
super.outline,
super.outlineVariant,
super.shadow,
super.scrim,
super.inverseSurface,
super.onInverseSurface,
super.inversePrimary,
super.surfaceTint,
});
final ScaleScheme scaleScheme;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ScaleScheme>('scales', scaleScheme));
}
}
class ScaleColor {
ScaleColor({
required this.appBackground,
required this.subtleBackground,
required this.elementBackground,
required this.hoverElementBackground,
required this.activedElementBackground,
required this.subtleBorder,
required this.border,
required this.hoverBorder,
required this.background,
required this.hoverBackground,
required this.subtleText,
required this.text,
});
Color appBackground;
Color subtleBackground;
Color elementBackground;
Color hoverElementBackground;
Color activedElementBackground;
Color subtleBorder;
Color border;
Color hoverBorder;
Color background;
Color hoverBackground;
Color subtleText;
Color text;
}
class ScaleScheme {
ScaleScheme(
{required this.primaryScale,
required this.primaryAlphaScale,
required this.secondaryScale,
required this.tertiaryScale,
required this.grayScale,
required this.errorScale});
ScaleColor primaryScale;
ScaleColor primaryAlphaScale;
ScaleColor secondaryScale;
ScaleColor tertiaryScale;
ScaleColor grayScale;
ScaleColor errorScale;
static ScaleScheme of(BuildContext context) =>
(Theme.of(context).colorScheme as ExtendedColorScheme).scaleScheme;
}
////////////////////////////////////////////////////////////////////////
class ThemeService { class ThemeService {
ThemeService._(); ThemeService._();
static late SharedPreferences prefs; static late SharedPreferences prefs;

View file

@ -7,6 +7,7 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever/screen_retriever_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <veilid/veilid_plugin.h> #include <veilid/veilid_plugin.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
@ -14,6 +15,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) screen_retriever_registrar = g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
g_autoptr(FlPluginRegistrar) veilid_registrar = g_autoptr(FlPluginRegistrar) veilid_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "VeilidPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "VeilidPlugin");
veilid_plugin_register_with_registrar(veilid_registrar); veilid_plugin_register_with_registrar(veilid_registrar);

View file

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
screen_retriever screen_retriever
url_launcher_linux
veilid veilid
window_manager window_manager
) )

View file

@ -9,6 +9,7 @@ import path_provider_foundation
import screen_retriever import screen_retriever
import shared_preferences_foundation import shared_preferences_foundation
import sqflite import sqflite
import url_launcher_macos
import veilid import veilid
import window_manager import window_manager
@ -17,6 +18,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
VeilidPlugin.register(with: registry.registrar(forPlugin: "VeilidPlugin")) VeilidPlugin.register(with: registry.registrar(forPlugin: "VeilidPlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
} }

View file

@ -14,6 +14,8 @@ PODS:
- sqflite (0.0.2): - sqflite (0.0.2):
- FlutterMacOS - FlutterMacOS
- FMDB (>= 2.7.5) - FMDB (>= 2.7.5)
- url_launcher_macos (0.0.1):
- FlutterMacOS
- veilid (0.0.1): - veilid (0.0.1):
- FlutterMacOS - FlutterMacOS
- window_manager (0.2.0): - window_manager (0.2.0):
@ -25,6 +27,7 @@ DEPENDENCIES:
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- veilid (from `Flutter/ephemeral/.symlinks/plugins/veilid/macos`) - veilid (from `Flutter/ephemeral/.symlinks/plugins/veilid/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
@ -43,6 +46,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite: sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
veilid: veilid:
:path: Flutter/ephemeral/.symlinks/plugins/veilid/macos :path: Flutter/ephemeral/.symlinks/plugins/veilid/macos
window_manager: window_manager:
@ -55,6 +60,7 @@ SPEC CHECKSUMS:
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
veilid: a54f57b7bcf0e4e072fe99272d76ca126b2026d0 veilid: a54f57b7bcf0e4e072fe99272d76ca126b2026d0
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8

View file

@ -289,6 +289,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.3"
csslib:
dependency: transitive
description:
name: csslib
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -321,6 +329,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.2"
diffutil_dart:
dependency: transitive
description:
name: diffutil_dart
sha256: e0297e4600b9797edff228ed60f4169a778ea357691ec98408fa3b72994c7d06
url: "https://pub.dev"
source: hosted
version: "3.0.0"
equatable: equatable:
dependency: "direct main" dependency: "direct main"
description: description:
@ -406,6 +422,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.1" version: "3.3.1"
flutter_chat_types:
dependency: transitive
description:
name: flutter_chat_types
sha256: e285b588f6d19d907feb1f6d912deaf22e223656769c34093b64e1c59b094fb9
url: "https://pub.dev"
source: hosted
version: "3.6.2"
flutter_chat_ui:
dependency: "direct main"
description:
name: flutter_chat_ui
sha256: d2b7d99fae88d17fdab13f4be3e6ae15c4ceaa5d3e199b61c254a67222d42611
url: "https://pub.dev"
source: hosted
version: "1.6.9"
flutter_form_builder: flutter_form_builder:
dependency: "direct main" dependency: "direct main"
description: description:
@ -422,11 +454,35 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.18.6" version: "0.18.6"
flutter_link_previewer:
dependency: transitive
description:
name: flutter_link_previewer
sha256: "007069e60f42419fb59872beb7a3cc3ea21e9f1bdff5d40239f376fa62ca9f20"
url: "https://pub.dev"
source: hosted
version: "3.2.2"
flutter_linkify:
dependency: transitive
description:
name: flutter_linkify
sha256: "74669e06a8f358fee4512b4320c0b80e51cffc496607931de68d28f099254073"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_parsed_text:
dependency: transitive
description:
name: flutter_parsed_text
sha256: "529cf5793b7acdf16ee0f97b158d0d4ba0bf06e7121ef180abe1a5b59e32c1e2"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
flutter_riverpod: flutter_riverpod:
dependency: "direct main" dependency: "direct main"
description: description:
@ -541,6 +597,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.6" version: "2.3.6"
html:
dependency: transitive
description:
name: html
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
url: "https://pub.dev"
source: hosted
version: "0.15.4"
http: http:
dependency: transitive dependency: transitive
description: description:
@ -621,6 +685,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.7.1" version: "6.7.1"
linkify:
dependency: transitive
description:
name: linkify
sha256: "4139ea77f4651ab9c315b577da2dd108d9aa0bd84b5d03d33323f1970c645832"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
lint_hard: lint_hard:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -677,14 +749,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
multi_split_view:
dependency: "direct main"
description:
name: multi_split_view
sha256: d68e129bff71fc9e6b66de59e1b79deaf4b91f30940130bfbd2d704c1c713499
url: "https://pub.dev"
source: hosted
version: "2.4.0"
octo_image: octo_image:
dependency: transitive dependency: transitive
description: description:
@ -773,6 +837,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.4.0" version: "5.4.0"
photo_view:
dependency: transitive
description:
name: photo_view
sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb"
url: "https://pub.dev"
source: hosted
version: "0.14.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -901,6 +973,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.6" version: "0.1.6"
scroll_to_index:
dependency: transitive
description:
name: scroll_to_index
sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176
url: "https://pub.dev"
source: hosted
version: "3.0.1"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1010,6 +1090,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
split_view:
dependency: "direct main"
description:
name: split_view
sha256: "7ad0e1c40703901aa1175fd465dec5e965b55324f9cc8e51526479a4a96d01a4"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
@ -1138,6 +1226,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.2" version: "2.2.2"
url_launcher:
dependency: transitive
description:
name: url_launcher
sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e"
url: "https://pub.dev"
source: hosted
version: "6.1.12"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "78cb6dea3e93148615109e58e42c35d1ffbf5ef66c44add673d0ab75f12ff3af"
url: "https://pub.dev"
source: hosted
version: "6.0.37"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1"
url: "https://pub.dev"
source: hosted
version: "3.0.6"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea
url: "https://pub.dev"
source: hosted
version: "2.1.3"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4
url: "https://pub.dev"
source: hosted
version: "2.0.18"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422"
url: "https://pub.dev"
source: hosted
version: "3.0.7"
uuid: uuid:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1185,6 +1337,14 @@ packages:
relative: true relative: true
source: path source: path
version: "0.1.6" version: "0.1.6"
visibility_detector:
dependency: transitive
description:
name: visibility_detector
sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
url: "https://pub.dev"
source: hosted
version: "0.4.0+2"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:

View file

@ -24,6 +24,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_animate: ^4.2.0+1 flutter_animate: ^4.2.0+1
flutter_chat_ui: ^1.6.9
flutter_form_builder: ^9.1.0 flutter_form_builder: ^9.1.0
flutter_hooks: ^0.18.0 flutter_hooks: ^0.18.0
flutter_localizations: flutter_localizations:
@ -39,7 +40,6 @@ dependencies:
intl: ^0.18.0 intl: ^0.18.0
json_annotation: ^4.8.1 json_annotation: ^4.8.1
loggy: ^2.0.3 loggy: ^2.0.3
multi_split_view: ^2.4.0
path: ^1.8.2 path: ^1.8.2
path_provider: ^2.0.11 path_provider: ^2.0.11
protobuf: ^3.0.0 protobuf: ^3.0.0
@ -49,6 +49,7 @@ dependencies:
riverpod_annotation: ^2.1.1 riverpod_annotation: ^2.1.1
shared_preferences: ^2.0.15 shared_preferences: ^2.0.15
signal_strength_indicator: ^0.4.1 signal_strength_indicator: ^0.4.1
split_view: ^3.2.1
stylish_bottom_bar: ^1.0.3 stylish_bottom_bar: ^1.0.3
uuid: ^3.0.7 uuid: ^3.0.7
veilid: veilid:

View file

@ -7,12 +7,15 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever/screen_retriever_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
#include <veilid/veilid_plugin.h> #include <veilid/veilid_plugin.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
ScreenRetrieverPluginRegisterWithRegistrar( ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
VeilidPluginRegisterWithRegistrar( VeilidPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("VeilidPlugin")); registry->GetRegistrarForPlugin("VeilidPlugin"));
WindowManagerPluginRegisterWithRegistrar( WindowManagerPluginRegisterWithRegistrar(

View file

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
screen_retriever screen_retriever
url_launcher_windows
veilid veilid
window_manager window_manager
) )