diff --git a/android/app/src/main/ic_launcher-playstore.png b/android/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 0000000..7973401
Binary files /dev/null and b/android/app/src/main/ic_launcher-playstore.png differ
diff --git a/assets/images/title.svg b/assets/images/title.svg
index 251d26e..96b4148 100644
--- a/assets/images/title.svg
+++ b/assets/images/title.svg
@@ -1,41 +1 @@
-
-
-
+
\ No newline at end of file
diff --git a/assets/images/vlogo.svg b/assets/images/vlogo.svg
index a0976e1..3377044 100644
--- a/assets/images/vlogo.svg
+++ b/assets/images/vlogo.svg
@@ -1,50 +1 @@
-
-
-
+
\ No newline at end of file
diff --git a/assets/sources/title.afdesign b/assets/sources/title.afdesign
index 00dce75..d30be2b 100644
Binary files a/assets/sources/title.afdesign and b/assets/sources/title.afdesign differ
diff --git a/assets/sources/vlogo.afdesign b/assets/sources/vlogo.afdesign
index 297ee75..0feddd9 100644
Binary files a/assets/sources/vlogo.afdesign and b/assets/sources/vlogo.afdesign differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
index d36b1fa..eabd851 100644
--- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,122 +1,122 @@
{
- "images" : [
+ "images": [
{
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "Icon-App-20x20@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-20x20@2x.png",
+ "idiom": "iphone",
+ "scale": "2x",
+ "size": "20x20"
},
{
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "Icon-App-20x20@3x.png",
- "scale" : "3x"
+ "filename": "Icon-App-20x20@3x.png",
+ "idiom": "iphone",
+ "scale": "3x",
+ "size": "20x20"
},
{
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@1x.png",
- "scale" : "1x"
+ "filename": "Icon-App-29x29@1x.png",
+ "idiom": "iphone",
+ "scale": "1x",
+ "size": "29x29"
},
{
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-29x29@2x.png",
+ "idiom": "iphone",
+ "scale": "2x",
+ "size": "29x29"
},
{
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@3x.png",
- "scale" : "3x"
+ "filename": "Icon-App-29x29@3x.png",
+ "idiom": "iphone",
+ "scale": "3x",
+ "size": "29x29"
},
{
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "Icon-App-40x40@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-40x40@2x.png",
+ "idiom": "iphone",
+ "scale": "2x",
+ "size": "40x40"
},
{
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "Icon-App-40x40@3x.png",
- "scale" : "3x"
+ "filename": "Icon-App-40x40@3x.png",
+ "idiom": "iphone",
+ "scale": "3x",
+ "size": "40x40"
},
{
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "Icon-App-60x60@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-60x60@2x.png",
+ "idiom": "iphone",
+ "scale": "2x",
+ "size": "60x60"
},
{
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "Icon-App-60x60@3x.png",
- "scale" : "3x"
+ "filename": "Icon-App-60x60@3x.png",
+ "idiom": "iphone",
+ "scale": "3x",
+ "size": "60x60"
},
{
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "Icon-App-20x20@1x.png",
- "scale" : "1x"
+ "filename": "Icon-App-20x20@1x.png",
+ "idiom": "ipad",
+ "scale": "1x",
+ "size": "20x20"
},
{
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "Icon-App-20x20@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-20x20@2x.png",
+ "idiom": "ipad",
+ "scale": "2x",
+ "size": "20x20"
},
{
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "Icon-App-29x29@1x.png",
- "scale" : "1x"
+ "filename": "Icon-App-29x29@1x.png",
+ "idiom": "ipad",
+ "scale": "1x",
+ "size": "29x29"
},
{
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "Icon-App-29x29@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-29x29@2x.png",
+ "idiom": "ipad",
+ "scale": "2x",
+ "size": "29x29"
},
{
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "Icon-App-40x40@1x.png",
- "scale" : "1x"
+ "filename": "Icon-App-40x40@1x.png",
+ "idiom": "ipad",
+ "scale": "1x",
+ "size": "40x40"
},
{
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "Icon-App-40x40@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-40x40@2x.png",
+ "idiom": "ipad",
+ "scale": "2x",
+ "size": "40x40"
},
{
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "Icon-App-76x76@1x.png",
- "scale" : "1x"
+ "filename": "Icon-App-76x76@1x.png",
+ "idiom": "ipad",
+ "scale": "1x",
+ "size": "76x76"
},
{
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "Icon-App-76x76@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-76x76@2x.png",
+ "idiom": "ipad",
+ "scale": "2x",
+ "size": "76x76"
},
{
- "size" : "83.5x83.5",
- "idiom" : "ipad",
- "filename" : "Icon-App-83.5x83.5@2x.png",
- "scale" : "2x"
+ "filename": "Icon-App-83.5x83.5@2x.png",
+ "idiom": "ipad",
+ "scale": "2x",
+ "size": "83.5x83.5"
},
{
- "size" : "1024x1024",
- "idiom" : "ios-marketing",
- "filename" : "Icon-App-1024x1024@1x.png",
- "scale" : "1x"
+ "filename": "Icon-App-1024x1024@1x.png",
+ "idiom": "ios-marketing",
+ "scale": "1x",
+ "size": "1024x1024"
}
],
- "info" : {
- "version" : 1,
- "author" : "xcode"
+ "info": {
+ "author": "icons_launcher",
+ "version": 1
}
-}
+}
\ No newline at end of file
diff --git a/lib/components/default_app_bar.dart b/lib/components/default_app_bar.dart
index 4b36f06..f029903 100644
--- a/lib/components/default_app_bar.dart
+++ b/lib/components/default_app_bar.dart
@@ -1,3 +1,4 @@
+import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_translate/flutter_translate.dart';
@@ -12,8 +13,9 @@ class DefaultAppBar extends AppBar {
decoration: BoxDecoration(
color: Colors.black.withAlpha(32),
shape: BoxShape.circle),
- child: SvgPicture.asset('assets/images/vlogo.svg',
- height: 48)),
+ child:
+ SvgPicture.asset('assets/images/vlogo.svg', height: 32)
+ .paddingAll(4)),
actions: (actions ?? [])
..add(
IconButton(
diff --git a/lib/entities/identity.g.dart b/lib/entities/identity.g.dart
index 4c8090c..7910de1 100644
--- a/lib/entities/identity.g.dart
+++ b/lib/entities/identity.g.dart
@@ -24,7 +24,7 @@ _$_Identity _$$_IdentityFromJson(Map json) => _$_Identity(
json['account_records'] as Map,
(value) => value as String,
(value) => ISet.fromJson(
- value, AccountRecordInfo.fromJson)),
+ value, (value) => AccountRecordInfo.fromJson(value))),
);
Map _$$_IdentityToJson(_$_Identity instance) =>
diff --git a/lib/entities/user_login.g.dart b/lib/entities/user_login.g.dart
index 3ed8395..17ed500 100644
--- a/lib/entities/user_login.g.dart
+++ b/lib/entities/user_login.g.dart
@@ -24,7 +24,7 @@ Map _$$_UserLoginToJson(_$_UserLogin instance) =>
_$_ActiveLogins _$$_ActiveLoginsFromJson(Map json) =>
_$_ActiveLogins(
userLogins: IList.fromJson(
- json['user_logins'], UserLogin.fromJson),
+ json['user_logins'], (value) => UserLogin.fromJson(value)),
activeUserLogin: json['active_user_login'] == null
? null
: Typed.fromJson(json['active_user_login']),
diff --git a/lib/pages/home.dart b/lib/pages/home.dart
index 50c2f12..a685b00 100644
--- a/lib/pages/home.dart
+++ b/lib/pages/home.dart
@@ -1,26 +1,310 @@
import 'package:flutter/material.dart';
+import 'package:flutter/scheduler.dart';
+import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:signal_strength_indicator/signal_strength_indicator.dart';
-class HomePage extends ConsumerWidget {
+import '../tools/tools.dart';
+
+class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key});
static const path = '/home';
@override
- Widget build(BuildContext context, WidgetRef ref) => Scaffold(
- appBar: AppBar(title: const Text('VeilidChat')),
- body: const Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text('Home Page'),
- // ElevatedButton(
- // onPressed: () {
- // ref.watch(authNotifierProvider.notifier).logout();
- // },
- // child: const Text("Logout"),
- // ),
- ],
- ),
- ),
- );
+ HomePageState createState() => HomePageState();
+}
+
+class HomePageState extends ConsumerState
+ with TickerProviderStateMixin {
+ final _unfocusNode = FocusNode();
+ final scaffoldKey = GlobalKey();
+ 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
+ void initState() {
+ super.initState();
+ // // On page load action.
+ // SchedulerBinding.instance.addPostFrameCallback((_) async {
+ // await actions.initialize(
+ // context,
+ // );
+ // });
+
+ setupAnimations(
+ animationsMap.values.where((anim) =>
+ anim.trigger == AnimationTrigger.onActionTrigger ||
+ !anim.applyInitialState),
+ this,
+ );
+
+ WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
+ }
+
+ @override
+ void dispose() {
+ _unfocusNode.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) => Scaffold(
+ key: scaffoldKey,
+ appBar: AppBar(title: const Text('VeilidChat')),
+ body: SafeArea(
+ child: GestureDetector(
+ onTap: () => FocusScope.of(context).requestFocus(_unfocusNode),
+ child: Stack(
+ children: [
+ if (responsiveVisibility(
+ context: context,
+ phone: false,
+ ))
+ Align(
+ alignment: AlignmentDirectional.centerEnd,
+ child: Container(
+ width: MediaQuery.of(context).size.width * 0.66,
+ height: double.infinity,
+ decoration: BoxDecoration(
+ color: Theme.of(context).scaffoldBackgroundColor,
+ ),
+ child: Stack(
+ children: [
+ Container(
+ width: double.infinity,
+ height: double.infinity,
+ decoration: const BoxDecoration(),
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ Container(
+ width: double.infinity,
+ height: 56,
+ decoration: BoxDecoration(
+ color: Theme.of(context).primaryColor,
+ borderRadius: BorderRadius.circular(0),
+ ),
+ child: Align(
+ alignment: AlignmentDirectional.centerStart,
+ child: Padding(
+ padding:
+ const EdgeInsetsDirectional.fromSTEB(
+ 16, 0, 16, 0),
+ child: Text(
+ "current contact",
+ // getJsonField(
+ // FFAppState().CurrentContact,
+ // r'''$.name''',
+ // ).toString(),
+ textAlign: TextAlign.start,
+ // style: Theme.of(context)
+ // .textTheme....
+ // .override(
+ // fontFamily: 'Noto Sans',
+ // color: FlutterFlowTheme.of(context)
+ // .header,
+ // ),
+ ),
+ ),
+ ),
+ ),
+ Expanded(
+ child: Container(
+ width: double.infinity,
+ height: 100,
+ decoration: const BoxDecoration(),
+ child: ChatComponentWidget(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ // if (FFAppState().CurrentContact == null)
+ // Container(
+ // width: double.infinity,
+ // height: double.infinity,
+ // decoration: const BoxDecoration(),
+ // child: NoContactComponentWidget(),
+ // ),
+ ],
+ ),
+ ).animateOnActionTrigger(
+ animationsMap['containerOnActionTriggerAnimation']!,
+ hasBeenTriggered: hasContainerTriggered),
+ ),
+ if (responsiveVisibility(
+ context: context,
+ phone: false,
+ ))
+ Material(
+ color: Colors.transparent,
+ elevation: 4,
+ child: Container(
+ width: MediaQuery.of(context).size.width * 0.34,
+ height: double.infinity,
+ constraints: BoxConstraints(
+ maxWidth: MediaQuery.of(context).size.width * 0.34,
+ ),
+ decoration: BoxDecoration(
+ color: Theme.of(context).scaffoldBackgroundColor,
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Container(
+ width: double.infinity,
+ height: 56,
+ decoration: BoxDecoration(
+ color: Theme.of(context).secondaryHeaderColor,
+ borderRadius: BorderRadius.circular(0),
+ ),
+ child: Padding(
+ padding: const EdgeInsetsDirectional.fromSTEB(
+ 16, 8, 16, 8),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Align(
+ alignment: AlignmentDirectional.centerStart,
+ child: Text(
+ 'Contacts',
+ textAlign: TextAlign.start,
+ // style: Theme.of(context).dialogTheme.titleTextStyle
+ // .title2
+ // .override(
+ // fontFamily: 'Noto Sans',
+ // color: FlutterFlowTheme.of(context)
+ // .header,
+ // ),
+ ),
+ ),
+ ),
+ SignalStrengthIndicator.bars(
+ value: .5, //_signalStrength,
+ size: 50,
+ barCount: 5,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Expanded(
+ child: Container(
+ width: double.infinity,
+ height: double.infinity,
+ decoration: const BoxDecoration(
+ boxShadow: [
+ BoxShadow(
+ blurRadius: 0,
+ color: Color(0x33000000),
+ offset: Offset(0, 0),
+ )
+ ],
+ ),
+ child: ContactListComponentWidget(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ if (responsiveVisibility(
+ context: context,
+ tablet: false,
+ tabletLandscape: false,
+ desktop: false,
+ ))
+ Material(
+ color: Colors.transparent,
+ elevation: 4,
+ child: Container(
+ width: double.infinity,
+ height: double.infinity,
+ decoration: BoxDecoration(
+ color: Theme.of(context).scaffoldBackgroundColor,
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Container(
+ width: double.infinity,
+ height: 56,
+ decoration: BoxDecoration(
+ //color: Theme.of(context).secondaryColor,
+ borderRadius: BorderRadius.circular(0),
+ ),
+ child: Padding(
+ padding: const EdgeInsetsDirectional.fromSTEB(
+ 16, 8, 16, 8),
+ child: Row(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ Expanded(
+ child: Align(
+ alignment:
+ const AlignmentDirectional(-1, 0),
+ child: Text(
+ 'Contacts',
+ textAlign: TextAlign.start,
+ // style: FlutterFlowTheme.of(context)
+ // .title2
+ // .override(
+ // fontFamily: 'Noto Sans',
+ // color: FlutterFlowTheme.of(context)
+ // .header,
+ // ),
+ ),
+ ),
+ ),
+ SignalStrengthIndicator.bars(
+ value: .5, //_signalStrength,
+ size: 50,
+ barCount: 5,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Expanded(
+ child: Container(
+ width: double.infinity,
+ height: double.infinity,
+ decoration: const BoxDecoration(
+ boxShadow: [
+ BoxShadow(
+ blurRadius: 0,
+ color: Color(0x33000000),
+ offset: Offset(0, 0),
+ )
+ ],
+ ),
+ child: ContactListComponentWidget(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ));
}
diff --git a/lib/pages/new_account.dart b/lib/pages/new_account.dart
index 6e20cee..31619ec 100644
--- a/lib/pages/new_account.dart
+++ b/lib/pages/new_account.dart
@@ -114,8 +114,11 @@ class NewAccountPageState extends ConsumerState {
enableTitleBar(true);
portraitOnly();
-// final localAccountsData = ref.watch(localAccountsProvider);
- final displayModalHUD = isInAsyncCall; // || !localAccountsData.hasValue;
+ final localAccounts = ref.watch(localAccountsProvider);
+ final logins = ref.watch(loginsProvider);
+
+ final displayModalHUD =
+ isInAsyncCall || !localAccounts.hasValue || !logins.hasValue;
return Scaffold(
// resizeToAvoidBottomInset: false,
diff --git a/lib/providers/local_accounts.g.dart b/lib/providers/local_accounts.g.dart
index 9dc7119..078d897 100644
--- a/lib/providers/local_accounts.g.dart
+++ b/lib/providers/local_accounts.g.dart
@@ -6,7 +6,7 @@ part of 'local_accounts.dart';
// RiverpodGenerator
// **************************************************************************
-String _$localAccountsHash() => r'37ed2ab40b6ed9063c7d1d00f067b7006c9a7670';
+String _$localAccountsHash() => r'f69de269e15fabb83d1afbb7fdb6eb7693d0ce24';
/// See also [LocalAccounts].
@ProviderFor(LocalAccounts)
diff --git a/lib/providers/logins.g.dart b/lib/providers/logins.g.dart
index 8b4d078..f55a3b8 100644
--- a/lib/providers/logins.g.dart
+++ b/lib/providers/logins.g.dart
@@ -6,7 +6,7 @@ part of 'logins.dart';
// RiverpodGenerator
// **************************************************************************
-String _$loginsHash() => r'cf7f1a2343340a4dc4ebfa4009e846d0a39c0167';
+String _$loginsHash() => r'ed9dbe91a248f662ccb0fac6edf5b1892cf2ef92';
/// See also [Logins].
@ProviderFor(Logins)
diff --git a/lib/router/router_notifier.dart b/lib/router/router_notifier.dart
index 1565ff2..967a541 100644
--- a/lib/router/router_notifier.dart
+++ b/lib/router/router_notifier.dart
@@ -37,9 +37,13 @@ class RouterNotifier extends _$RouterNotifier implements Listenable {
return null;
}
+ // No matter where we are, if there's not
+
switch (state.location) {
case IndexPage.path:
return hasAnyAccount ? HomePage.path : NewAccountPage.path;
+ case NewAccountPage.path:
+ return hasAnyAccount ? HomePage.path : null;
default:
return hasAnyAccount ? null : NewAccountPage.path;
}
diff --git a/lib/router/router_notifier.g.dart b/lib/router/router_notifier.g.dart
index bb7bbcb..e7cbd85 100644
--- a/lib/router/router_notifier.g.dart
+++ b/lib/router/router_notifier.g.dart
@@ -6,7 +6,7 @@ part of 'router_notifier.dart';
// RiverpodGenerator
// **************************************************************************
-String _$routerNotifierHash() => r'00de1dd715945e96b49507ea55d7b97a78366adc';
+String _$routerNotifierHash() => r'ef31219dde5e12b2bb224c79ca13ab4f414c81b4';
/// See also [RouterNotifier].
@ProviderFor(RouterNotifier)
diff --git a/lib/tools/animations.dart b/lib/tools/animations.dart
new file mode 100644
index 0000000..10cd2e2
--- /dev/null
+++ b/lib/tools/animations.dart
@@ -0,0 +1,98 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_animate/flutter_animate.dart';
+
+enum AnimationTrigger {
+ onPageLoad,
+ onActionTrigger,
+}
+
+class AnimationInfo {
+ AnimationInfo({
+ required this.trigger,
+ required this.effects,
+ this.loop = false,
+ this.reverse = false,
+ this.applyInitialState = true,
+ });
+ final AnimationTrigger trigger;
+ final List> effects;
+ final bool applyInitialState;
+ final bool loop;
+ final bool reverse;
+ late Adapter adapter;
+ late AnimationController controller;
+}
+
+void createAnimation(AnimationInfo animation, TickerProvider vsync) {
+ final newController = AnimationController(vsync: vsync);
+ animation
+ ..controller = newController
+ ..adapter = (ValueAdapter(0)..attach(newController));
+}
+
+void setupAnimations(Iterable animations, TickerProvider vsync) {
+ for (final animation in animations) {
+ createAnimation(animation, vsync);
+ }
+}
+
+extension AnimatedWidgetExtension on Widget {
+ Widget animateOnPageLoad(AnimationInfo animationInfo) => Animate(
+ controller:
+ animationInfo.applyInitialState ? null : animationInfo.controller,
+ adapter: animationInfo.applyInitialState ? null : animationInfo.adapter,
+ effects: animationInfo.effects,
+ child: this,
+ onPlay: (controller) => animationInfo.loop
+ ? controller.repeat(reverse: animationInfo.reverse)
+ : null,
+ onComplete: (controller) => !animationInfo.loop && animationInfo.reverse
+ ? controller.reverse()
+ : null);
+
+ Widget animateOnActionTrigger(
+ AnimationInfo animationInfo, {
+ bool hasBeenTriggered = false,
+ }) =>
+ hasBeenTriggered || animationInfo.applyInitialState
+ ? Animate(
+ controller: animationInfo.controller,
+ adapter: animationInfo.adapter,
+ effects: animationInfo.effects,
+ child: this)
+ : this;
+}
+
+class TiltEffect extends Effect {
+ const TiltEffect({
+ super.delay,
+ super.duration,
+ super.curve,
+ Offset? begin,
+ Offset? end,
+ }) : super(
+ begin: begin ?? Offset.zero,
+ end: end ?? Offset.zero,
+ );
+
+ @override
+ Widget build(
+ BuildContext context,
+ Widget child,
+ AnimationController controller,
+ EffectEntry entry,
+ ) {
+ final animation = buildAnimation(controller, entry);
+ return getOptimizedBuilder(
+ animation: animation,
+ builder: (_, __) => Transform(
+ transform: Matrix4.identity()
+ ..setEntry(3, 2, 0.001)
+ ..rotateX(animation.value.dx)
+ ..rotateY(animation.value.dy),
+ alignment: Alignment.center,
+ child: child,
+ ),
+ );
+ }
+}
diff --git a/lib/tools/responsive.dart b/lib/tools/responsive.dart
new file mode 100644
index 0000000..82d2f3b
--- /dev/null
+++ b/lib/tools/responsive.dart
@@ -0,0 +1,32 @@
+import 'dart:io';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+bool get isAndroid => !kIsWeb && Platform.isAndroid;
+bool get isiOS => !kIsWeb && Platform.isIOS;
+bool get isWeb => kIsWeb;
+
+const kMobileWidthCutoff = 479.0;
+
+bool isMobileWidth(BuildContext context) =>
+ MediaQuery.of(context).size.width < kMobileWidthCutoff;
+
+bool responsiveVisibility({
+ required BuildContext context,
+ bool phone = true,
+ bool tablet = true,
+ bool tabletLandscape = true,
+ bool desktop = true,
+}) {
+ final width = MediaQuery.of(context).size.width;
+ if (width < kMobileWidthCutoff) {
+ return phone;
+ } else if (width < 767) {
+ return tablet;
+ } else if (width < 991) {
+ return tabletLandscape;
+ } else {
+ return desktop;
+ }
+}
diff --git a/lib/tools/tools.dart b/lib/tools/tools.dart
index 19fb828..142f549 100644
--- a/lib/tools/tools.dart
+++ b/lib/tools/tools.dart
@@ -1,6 +1,8 @@
+export 'animations.dart';
export 'desktop_control.dart';
export 'external_stream_state.dart';
export 'json_tools.dart';
export 'phono_byte.dart';
export 'protobuf_tools.dart';
+export 'responsive.dart';
export 'widget_helpers.dart';
diff --git a/lib/veilid_support/veilid_init.g.dart b/lib/veilid_support/veilid_init.g.dart
index 80e9777..bc2ade3 100644
--- a/lib/veilid_support/veilid_init.g.dart
+++ b/lib/veilid_support/veilid_init.g.dart
@@ -6,7 +6,7 @@ part of 'veilid_init.dart';
// RiverpodGenerator
// **************************************************************************
-String _$veilidInstanceHash() => r'6086fc1e7a83e7af81ee05ee84954507d38cb748';
+String _$veilidInstanceHash() => r'cca5cf288bafc4a051a1713e285f4c1d3ef4b680';
/// See also [veilidInstance].
@ProviderFor(veilidInstance)
diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj
index 8d95c36..c5ccbd1 100644
--- a/macos/Runner.xcodeproj/project.pbxproj
+++ b/macos/Runner.xcodeproj/project.pbxproj
@@ -423,6 +423,7 @@
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
@@ -560,6 +561,7 @@
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
@@ -591,6 +593,7 @@
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
index 96d3fee..7b4d860 100644
--- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,68 +1,68 @@
{
- "info": {
- "version": 1,
- "author": "xcode"
+ "images": [
+ {
+ "filename": "app_icon_16.png",
+ "idiom": "mac",
+ "scale": "1x",
+ "size": "16x16"
},
- "images": [
- {
- "size": "16x16",
- "idiom": "mac",
- "filename": "app_icon_16.png",
- "scale": "1x"
- },
- {
- "size": "16x16",
- "idiom": "mac",
- "filename": "app_icon_32.png",
- "scale": "2x"
- },
- {
- "size": "32x32",
- "idiom": "mac",
- "filename": "app_icon_32.png",
- "scale": "1x"
- },
- {
- "size": "32x32",
- "idiom": "mac",
- "filename": "app_icon_64.png",
- "scale": "2x"
- },
- {
- "size": "128x128",
- "idiom": "mac",
- "filename": "app_icon_128.png",
- "scale": "1x"
- },
- {
- "size": "128x128",
- "idiom": "mac",
- "filename": "app_icon_256.png",
- "scale": "2x"
- },
- {
- "size": "256x256",
- "idiom": "mac",
- "filename": "app_icon_256.png",
- "scale": "1x"
- },
- {
- "size": "256x256",
- "idiom": "mac",
- "filename": "app_icon_512.png",
- "scale": "2x"
- },
- {
- "size": "512x512",
- "idiom": "mac",
- "filename": "app_icon_512.png",
- "scale": "1x"
- },
- {
- "size": "512x512",
- "idiom": "mac",
- "filename": "app_icon_1024.png",
- "scale": "2x"
- }
- ]
+ {
+ "filename": "app_icon_32.png",
+ "idiom": "mac",
+ "scale": "2x",
+ "size": "16x16"
+ },
+ {
+ "filename": "app_icon_32.png",
+ "idiom": "mac",
+ "scale": "1x",
+ "size": "32x32"
+ },
+ {
+ "filename": "app_icon_64.png",
+ "idiom": "mac",
+ "scale": "2x",
+ "size": "32x32"
+ },
+ {
+ "filename": "app_icon_128.png",
+ "idiom": "mac",
+ "scale": "1x",
+ "size": "128x128"
+ },
+ {
+ "filename": "app_icon_256.png",
+ "idiom": "mac",
+ "scale": "2x",
+ "size": "128x128"
+ },
+ {
+ "filename": "app_icon_256.png",
+ "idiom": "mac",
+ "scale": "1x",
+ "size": "256x256"
+ },
+ {
+ "filename": "app_icon_512.png",
+ "idiom": "mac",
+ "scale": "2x",
+ "size": "256x256"
+ },
+ {
+ "filename": "app_icon_512.png",
+ "idiom": "mac",
+ "scale": "1x",
+ "size": "512x512"
+ },
+ {
+ "filename": "app_icon_1024.png",
+ "idiom": "mac",
+ "scale": "2x",
+ "size": "512x512"
+ }
+ ],
+ "info": {
+ "author": "icons_launcher",
+ "version": 1
+ }
}
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index a9fc4d7..4cd6ec6 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -374,6 +374,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ flutter_animate:
+ dependency: "direct main"
+ description:
+ name: flutter_animate
+ sha256: "62f346340a96192070e31e3f2a1bd30a28530f1fe8be978821e06cd56b74d6d2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.2.0+1"
flutter_blurhash:
dependency: transitive
description:
@@ -406,14 +414,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.18.6"
- flutter_launcher_icons:
- dependency: "direct dev"
- description:
- name: flutter_launcher_icons
- sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
- url: "https://pub.dev"
- source: hosted
- version: "0.13.1"
flutter_localizations:
dependency: "direct main"
description: flutter
@@ -557,6 +557,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
+ icons_launcher:
+ dependency: "direct dev"
+ description:
+ name: icons_launcher
+ sha256: af05397792f6d82b93375a8a0253b8db0d3f816ef1dd1bf5c35cbab55321d327
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.3"
image:
dependency: transitive
description:
@@ -949,6 +957,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
+ signal_strength_indicator:
+ dependency: "direct main"
+ description:
+ name: signal_strength_indicator
+ sha256: "076f84fbffc69694f0df3d376822d806cc0de67d379aa57ebcdab09384ab839b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.4.1"
sky_engine:
dependency: transitive
description: flutter
diff --git a/pubspec.yaml b/pubspec.yaml
index d2373c5..a9be963 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -22,6 +22,7 @@ dependencies:
fixnum: ^1.1.0
flutter:
sdk: flutter
+ flutter_animate: ^4.2.0+1
flutter_form_builder: ^9.1.0
flutter_hooks: ^0.18.0
flutter_localizations:
@@ -45,6 +46,7 @@ dependencies:
reorderable_grid: ^1.0.7
riverpod_annotation: ^2.1.1
shared_preferences: ^2.0.15
+ signal_strength_indicator: ^0.4.1
uuid: ^3.0.7
veilid:
# veilid: ^0.0.1
@@ -53,29 +55,29 @@ dependencies:
dev_dependencies:
build_runner: ^2.4.6
- flutter_launcher_icons: "^0.13.1"
flutter_test:
sdk: flutter
freezed: ^2.3.5
+ icons_launcher: ^2.1.3
json_serializable: ^6.7.1
lint_hard: ^4.0.0
riverpod_generator: ^2.2.3
-flutter_launcher_icons:
+icons_launcher:
image_path: "assets/launcher/icon.png"
- android: true
- ios: true
- remove_alpha_ios: true
- min_sdk_android: 24 # android min sdk min:16, default 21
- web:
- generate: true
- background_color: "#33183f"
- theme_color: "#863fa6"
- windows:
- generate: true
- icon_size: 48 # min:48, max:256, default: 48
- macos:
- generate: true
+ platforms:
+ android:
+ enable: true
+ ios:
+ enable: true
+ web:
+ enable: true
+ macos:
+ enable: true
+ windows:
+ enable: true
+ linux:
+ enable: true
flutter:
uses-material-design: true
diff --git a/snap/gui/app_icon.desktop b/snap/gui/app_icon.desktop
new file mode 100644
index 0000000..92a01f6
--- /dev/null
+++ b/snap/gui/app_icon.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Name=Flutter Linux App
+Comment=Flutter Linux launcher icon
+Exec=app_icon
+Icon=app_icon.png
+Terminal=false
+Type=Application
+Categories=Entertainment;
diff --git a/snap/gui/app_icon.png b/snap/gui/app_icon.png
new file mode 100644
index 0000000..524a08b
Binary files /dev/null and b/snap/gui/app_icon.png differ
diff --git a/update_icons.sh b/update_icons.sh
index 39baaa3..d60ccca 100755
--- a/update_icons.sh
+++ b/update_icons.sh
@@ -1,2 +1,3 @@
#!/bin/bash
-dart run flutter_launcher_icons
+flutter pub get
+dart run icons_launcher:create
diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico
index 7ba0332..65be1a9 100644
Binary files a/windows/runner/resources/app_icon.ico and b/windows/runner/resources/app_icon.ico differ