💄 Optimize styles

This commit is contained in:
LittleSheep 2025-05-19 23:29:51 +08:00
parent b918986fc5
commit 9d6cf54bf8
8 changed files with 157 additions and 34 deletions

View File

@ -1,5 +1,6 @@
{ {
"login": "Login", "login": "Login",
"loginDescription": "Existing user? We're welcome you back!",
"forgotPassword": "Forgot password", "forgotPassword": "Forgot password",
"loginPickFactor": "Pick a factor", "loginPickFactor": "Pick a factor",
"loginMultiFactor": { "loginMultiFactor": {
@ -19,6 +20,7 @@
"password": "Password", "password": "Password",
"next": "Next", "next": "Next",
"createAccount": "Create an Account", "createAccount": "Create an Account",
"createAccountDescription": "New to here? We got you covered!",
"nickname": "Nickname", "nickname": "Nickname",
"email": "Email", "email": "Email",
"bio": "Bio", "bio": "Bio",
@ -252,5 +254,9 @@
"leaveChatRoom": "Leave Chat Room", "leaveChatRoom": "Leave Chat Room",
"leaveChatRoomHint": "Are you sure to leave this chat room?", "leaveChatRoomHint": "Are you sure to leave this chat room?",
"leaveRealm": "Leave Realm", "leaveRealm": "Leave Realm",
"leaveRealmHint": "Are you sure to leave this realm?" "leaveRealmHint": "Are you sure to leave this realm?",
"walletNotFound": "Wallet not found",
"walletCreateHint": "You don't have a wallet yet. Create one to start using the Solar Network eWallet.",
"walletCreate": "Create a Wallet",
"settingsServerUrl": "Server URL"
} }

View File

@ -5,7 +5,7 @@ import 'package:shared_preferences/shared_preferences.dart';
const kTokenPairStoreKey = 'dyn_user_tk'; const kTokenPairStoreKey = 'dyn_user_tk';
const kNetworkServerDefault = 'http://localhost:5071'; const kNetworkServerDefault = 'https://ppa.solian.app';
const kNetworkServerStoreKey = 'app_server_url'; const kNetworkServerStoreKey = 'app_server_url';
const kAppbarTransparentStoreKey = 'app_bar_transparent'; const kAppbarTransparentStoreKey = 'app_bar_transparent';

View File

@ -267,30 +267,66 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppScaffold( return AppScaffold(
appBar: AppBar(title: const Text('Account')), appBar: AppBar(title: const Text('Account')),
body: Column( body:
children: <Widget>[ ConstrainedBox(
ListTile( constraints: const BoxConstraints(maxWidth: 360),
leading: const Icon(Symbols.person_add), child: Column(
trailing: const Icon(Symbols.chevron_right), crossAxisAlignment: CrossAxisAlignment.stretch,
title: Text('createAccount').tr(), mainAxisAlignment: MainAxisAlignment.center,
subtitle: Text('New to here? We got you covered!'), children: <Widget>[
contentPadding: EdgeInsets.symmetric(horizontal: 24), Padding(
onTap: () { padding: const EdgeInsets.symmetric(horizontal: 24),
context.router.push(CreateAccountRoute()); child: Card(
}, child: InkWell(
), onTap: () {
ListTile( context.router.push(CreateAccountRoute());
leading: const Icon(Symbols.login), },
trailing: const Icon(Symbols.chevron_right), child: Padding(
subtitle: Text('Existing user? We\'re welcome you back!'), padding: const EdgeInsets.all(16),
contentPadding: EdgeInsets.symmetric(horizontal: 24), child: Column(
title: Text('login').tr(), children: [
onTap: () { Icon(Symbols.person_add, size: 48),
context.router.push(LoginRoute()); const SizedBox(height: 8),
}, Text('createAccount').tr().bold(),
), Text('createAccountDescription').tr(),
], ],
), ),
),
),
),
),
const Gap(8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Card(
child: InkWell(
onTap: () {
context.router.push(LoginRoute());
},
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Icon(Symbols.login, size: 48),
const SizedBox(height: 8),
Text('login').tr().bold(),
Text('loginDescription').tr(),
],
),
),
),
),
),
const Gap(8),
TextButton(
onPressed: () {
context.router.push(SettingsRoute());
},
child: Text('appSettings').tr(),
).center(),
],
),
).center(),
); );
} }
} }

View File

@ -146,6 +146,8 @@ class TabsNavigationWidget extends HookConsumerWidget {
bottomNavigationBar: bottomNavigationBar:
!useHorizontalLayout && isTabRoute !useHorizontalLayout && isTabRoute
? NavigationBar( ? NavigationBar(
height: 56,
labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
selectedIndex: activeIndex, selectedIndex: activeIndex,
onDestinationSelected: (index) { onDestinationSelected: (index) {
router.replace(routes[index]); router.replace(routes[index]);

View File

@ -16,6 +16,7 @@ import 'package:island/services/file.dart';
import 'package:island/widgets/alert.dart'; import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/cloud_files.dart';
import 'package:island/widgets/response.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
@ -480,7 +481,11 @@ class _RealmInviteSheet extends HookConsumerWidget {
}, },
), ),
loading: () => const Center(child: CircularProgressIndicator()), loading: () => const Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(child: Text('Error: $error')), error:
(error, _) => ResponseErrorWidget(
error: error,
onRetry: () => ref.invalidate(realmInvitesProvider),
),
), ),
), ),
], ],

View File

@ -7,6 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/app_scaffold.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:island/pods/config.dart';
@RoutePage() @RoutePage()
class SettingsScreen extends HookConsumerWidget { class SettingsScreen extends HookConsumerWidget {
@ -14,6 +15,10 @@ class SettingsScreen extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final serverUrl = ref.watch(serverUrlProvider);
final prefs = ref.watch(sharedPreferencesProvider);
final controller = TextEditingController(text: serverUrl);
return AppScaffold( return AppScaffold(
appBar: AppBar(title: const Text('Settings')), appBar: AppBar(title: const Text('Settings')),
body: SingleChildScrollView( body: SingleChildScrollView(
@ -61,6 +66,43 @@ class SettingsScreen extends HookConsumerWidget {
), ),
), ),
), ),
ListTile(
isThreeLine: true,
minLeadingWidth: 48,
title: Text('settingsServerUrl').tr(),
contentPadding: const EdgeInsets.only(left: 24, right: 17),
leading: const Icon(Symbols.link),
subtitle: Padding(
padding: const EdgeInsets.only(top: 6),
child: TextField(
controller: controller,
decoration: InputDecoration(
hintText: kNetworkServerDefault,
suffixIcon: IconButton(
icon: const Icon(Symbols.restart_alt),
onPressed: () {
controller.text = kNetworkServerDefault;
prefs.setString(
kNetworkServerStoreKey,
kNetworkServerDefault,
);
ref.invalidate(serverUrlProvider);
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
isDense: true,
),
onSubmitted: (value) {
if (value.isNotEmpty) {
prefs.setString(kNetworkServerStoreKey, value);
ref.invalidate(serverUrlProvider);
}
},
),
),
),
], ],
), ),
), ),

View File

@ -1,10 +1,12 @@
import 'package:auto_route/annotations.dart'; import 'package:auto_route/annotations.dart';
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/wallet.dart'; import 'package:island/models/wallet.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/response.dart'; import 'package:island/widgets/response.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
@ -14,10 +16,17 @@ import 'package:styled_widget/styled_widget.dart';
part 'wallet.g.dart'; part 'wallet.g.dart';
@riverpod @riverpod
Future<SnWallet> walletCurrent(Ref ref) async { Future<SnWallet?> walletCurrent(Ref ref) async {
final apiClient = ref.watch(apiClientProvider); try {
final resp = await apiClient.get('/wallets'); final apiClient = ref.watch(apiClientProvider);
return SnWallet.fromJson(resp.data); final resp = await apiClient.get('/wallets');
return SnWallet.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
return null;
}
rethrow;
}
} }
const Map<String, IconData> kCurrencyIconData = { const Map<String, IconData> kCurrencyIconData = {
@ -71,6 +80,16 @@ class WalletScreen extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final wallet = ref.watch(walletCurrentProvider); final wallet = ref.watch(walletCurrentProvider);
Future<void> createWallet() async {
final client = ref.read(apiClientProvider);
try {
await client.post('/wallets');
ref.invalidate(walletCurrentProvider);
} catch (err) {
showErrorAlert(err);
}
}
String getCurrencyTranslationKey(String currency, {bool isShort = false}) { String getCurrencyTranslationKey(String currency, {bool isShort = false}) {
return 'walletCurrency${isShort ? 'Short' : ''}${currency[0].toUpperCase()}${currency.substring(1).toLowerCase()}'; return 'walletCurrency${isShort ? 'Short' : ''}${currency[0].toUpperCase()}${currency.substring(1).toLowerCase()}';
} }
@ -79,6 +98,19 @@ class WalletScreen extends HookConsumerWidget {
appBar: AppBar(title: Text('wallet').tr()), appBar: AppBar(title: Text('wallet').tr()),
body: wallet.when( body: wallet.when(
data: (data) { data: (data) {
if (data == null) {
return Column(
children: [
Text('walletNotFound').tr(),
Text('walletCreateHint').tr(),
TextButton(
onPressed: createWallet,
child: Text('walletCreate').tr(),
),
],
);
}
return Column( return Column(
children: [ children: [
Column( Column(

View File

@ -6,11 +6,11 @@ part of 'wallet.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$walletCurrentHash() => r'9123af148c4a27e079bbe90c7d4e41d08e408a39'; String _$walletCurrentHash() => r'94e6f3776ce15679d17238e372660c365c9b1028';
/// See also [walletCurrent]. /// See also [walletCurrent].
@ProviderFor(walletCurrent) @ProviderFor(walletCurrent)
final walletCurrentProvider = AutoDisposeFutureProvider<SnWallet>.internal( final walletCurrentProvider = AutoDisposeFutureProvider<SnWallet?>.internal(
walletCurrent, walletCurrent,
name: r'walletCurrentProvider', name: r'walletCurrentProvider',
debugGetCreateSourceHash: debugGetCreateSourceHash:
@ -23,7 +23,7 @@ final walletCurrentProvider = AutoDisposeFutureProvider<SnWallet>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead') @Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element // ignore: unused_element
typedef WalletCurrentRef = AutoDisposeFutureProviderRef<SnWallet>; typedef WalletCurrentRef = AutoDisposeFutureProviderRef<SnWallet?>;
String _$transactionListNotifierHash() => String _$transactionListNotifierHash() =>
r'148ffb0ee9e3be3b92de432f314d8ee2f09e9a24'; r'148ffb0ee9e3be3b92de432f314d8ee2f09e9a24';