✨ Able to config preferred language
This commit is contained in:
parent
5a85985534
commit
5d6fb2442f
@ -241,6 +241,8 @@
|
|||||||
"settingsMisc": "Misc",
|
"settingsMisc": "Misc",
|
||||||
"settingsMiscAbout": "About",
|
"settingsMiscAbout": "About",
|
||||||
"settingsMiscAboutDescription": "View the version information of Solian.",
|
"settingsMiscAboutDescription": "View the version information of Solian.",
|
||||||
|
"settingsAccountLanguage": "Account Language",
|
||||||
|
"settingsAccountLanguageDescription": "Set the language for email, notification, and other account-related content.",
|
||||||
"sensitiveContent": "Sensitive Content",
|
"sensitiveContent": "Sensitive Content",
|
||||||
"sensitiveContentCollapsed": "Sensitive content has been collapsed.",
|
"sensitiveContentCollapsed": "Sensitive content has been collapsed.",
|
||||||
"sensitiveContentDescription": "This content has been marked as sensitive, and may not be suitable for all viewers.",
|
"sensitiveContentDescription": "This content has been marked as sensitive, and may not be suitable for all viewers.",
|
||||||
@ -606,5 +608,6 @@
|
|||||||
"one": "{} Source Point",
|
"one": "{} Source Point",
|
||||||
"other": "{} Source Points"
|
"other": "{} Source Points"
|
||||||
},
|
},
|
||||||
"aiThinkingProcess": "AI Thinking Process"
|
"aiThinkingProcess": "AI Thinking Process",
|
||||||
|
"accountSettingsApplied": "Account settings have been applied."
|
||||||
}
|
}
|
||||||
|
@ -239,6 +239,8 @@
|
|||||||
"settingsMisc": "杂项",
|
"settingsMisc": "杂项",
|
||||||
"settingsMiscAbout": "关于",
|
"settingsMiscAbout": "关于",
|
||||||
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
||||||
|
"settingsAccountLanguage": "帐号偏好语言",
|
||||||
|
"settingsAccountLanguageDescription": "设置邮件、通知和其他帐号相关内容的语言。",
|
||||||
"sensitiveContent": "敏感内容",
|
"sensitiveContent": "敏感内容",
|
||||||
"sensitiveContentCollapsed": "敏感内容已折叠。",
|
"sensitiveContentCollapsed": "敏感内容已折叠。",
|
||||||
"sensitiveContentDescription": "此内容已被标记,可能不适合所有人查看。",
|
"sensitiveContentDescription": "此内容已被标记,可能不适合所有人查看。",
|
||||||
@ -604,5 +606,6 @@
|
|||||||
"one": "{} 源点",
|
"one": "{} 源点",
|
||||||
"other": "{} 源点"
|
"other": "{} 源点"
|
||||||
},
|
},
|
||||||
"aiThinkingProcess": "AI 思考过程"
|
"aiThinkingProcess": "AI 思考过程",
|
||||||
|
"accountSettingsApplied": "帐号设置已应用。"
|
||||||
}
|
}
|
||||||
|
@ -239,6 +239,8 @@
|
|||||||
"settingsMisc": "雜項",
|
"settingsMisc": "雜項",
|
||||||
"settingsMiscAbout": "關於",
|
"settingsMiscAbout": "關於",
|
||||||
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
||||||
|
"settingsAccountLanguage": "帳號偏好語言",
|
||||||
|
"settingsAccountLanguageDescription": "設置郵件、通知和其他帳號相關內容的語言。",
|
||||||
"sensitiveContent": "敏感內容",
|
"sensitiveContent": "敏感內容",
|
||||||
"sensitiveContentCollapsed": "敏感內容已摺疊。",
|
"sensitiveContentCollapsed": "敏感內容已摺疊。",
|
||||||
"sensitiveContentDescription": "此內容已被標記,可能不適合所有人查看。",
|
"sensitiveContentDescription": "此內容已被標記,可能不適合所有人查看。",
|
||||||
@ -604,5 +606,6 @@
|
|||||||
"one": "{} 源點",
|
"one": "{} 源點",
|
||||||
"other": "{} 源點"
|
"other": "{} 源點"
|
||||||
},
|
},
|
||||||
"aiThinkingProcess": "AI 思考過程"
|
"aiThinkingProcess": "AI 思考過程",
|
||||||
|
"accountSettingsApplied": "帳號設置已應用。"
|
||||||
}
|
}
|
||||||
|
@ -239,6 +239,8 @@
|
|||||||
"settingsMisc": "雜項",
|
"settingsMisc": "雜項",
|
||||||
"settingsMiscAbout": "關於",
|
"settingsMiscAbout": "關於",
|
||||||
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
||||||
|
"settingsAccountLanguage": "帳號偏好語言",
|
||||||
|
"settingsAccountLanguageDescription": "設置郵件、通知和其他帳號相關內容的語言。",
|
||||||
"sensitiveContent": "敏感內容",
|
"sensitiveContent": "敏感內容",
|
||||||
"sensitiveContentCollapsed": "敏感內容已摺疊。",
|
"sensitiveContentCollapsed": "敏感內容已摺疊。",
|
||||||
"sensitiveContentDescription": "此內容已被標記,可能不適合所有人查看。",
|
"sensitiveContentDescription": "此內容已被標記,可能不適合所有人查看。",
|
||||||
@ -604,5 +606,6 @@
|
|||||||
"one": "{} 源點",
|
"one": "{} 源點",
|
||||||
"other": "{} 源點"
|
"other": "{} 源點"
|
||||||
},
|
},
|
||||||
"aiThinkingProcess": "AI 思考過程"
|
"aiThinkingProcess": "AI 思考過程",
|
||||||
|
"accountSettingsApplied": "帳號設置已應用。"
|
||||||
}
|
}
|
||||||
|
@ -53,4 +53,11 @@ class UserProvider extends ChangeNotifier {
|
|||||||
user = null;
|
user = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLanguage(String? value) {
|
||||||
|
if (value == null) return;
|
||||||
|
if (user == null) return;
|
||||||
|
user = user!.copyWith(language: value);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,41 @@
|
|||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:dropdown_button2/dropdown_button2.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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/providers/userinfo.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
import 'package:intl/locale.dart';
|
||||||
|
|
||||||
class AccountSettingsScreen extends StatelessWidget {
|
class AccountSettingsScreen extends StatelessWidget {
|
||||||
const AccountSettingsScreen({super.key});
|
const AccountSettingsScreen({super.key});
|
||||||
|
|
||||||
|
Future<void> _setAccountLanguage(BuildContext context, Locale? value) async {
|
||||||
|
if (value == null) return;
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final ua = context.read<UserProvider>();
|
||||||
|
await sn.client.put('/cgi/id/users/me/language', data: {
|
||||||
|
'language': value.toString(),
|
||||||
|
});
|
||||||
|
if (!context.mounted) return;
|
||||||
|
context.showSnackbar('accountSettingsApplied'.tr());
|
||||||
|
await ua.refreshUser();
|
||||||
|
} catch (err) {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final ua = context.watch<UserProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: PageBackButton(),
|
leading: PageBackButton(),
|
||||||
@ -21,6 +45,42 @@ class AccountSettingsScreen extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text('settingsAccountLanguage').tr(),
|
||||||
|
subtitle: Text('settingsAccountLanguageDescription').tr(),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
|
leading: const Icon(Symbols.translate),
|
||||||
|
trailing: DropdownButtonHideUnderline(
|
||||||
|
child: DropdownButton2<Locale?>(
|
||||||
|
isExpanded: true,
|
||||||
|
items: [
|
||||||
|
...EasyLocalization.of(context)!.supportedLocales.mapIndexed((idx, ele) {
|
||||||
|
return DropdownMenuItem<Locale?>(
|
||||||
|
value: Locale.parse(ele.toString()),
|
||||||
|
child: Text('${ele.languageCode}-${ele.countryCode}').fontSize(14),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
value: ua.user?.language != null ? Locale.parse(ua.user!.language) : Locale.parse('en-US'),
|
||||||
|
onChanged: (Locale? value) {
|
||||||
|
if (value == null) return;
|
||||||
|
_setAccountLanguage(context, value);
|
||||||
|
ua.setLanguage(value.toString());
|
||||||
|
},
|
||||||
|
buttonStyleData: const ButtonStyleData(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
height: 40,
|
||||||
|
width: 160,
|
||||||
|
),
|
||||||
|
menuItemStyleData: const MenuItemStyleData(
|
||||||
|
height: 40,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('accountProfileEdit').tr(),
|
title: Text('accountProfileEdit').tr(),
|
||||||
subtitle: Text('accountProfileEditSubtitle').tr(),
|
subtitle: Text('accountProfileEditSubtitle').tr(),
|
||||||
|
@ -44,6 +44,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
'nick': nickname,
|
'nick': nickname,
|
||||||
'email': email,
|
'email': email,
|
||||||
'password': password,
|
'password': password,
|
||||||
|
'language': EasyLocalization.of(context)!.currentLocale.toString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
@ -21,6 +21,7 @@ class SnAccount with _$SnAccount {
|
|||||||
required String name,
|
required String name,
|
||||||
required String nick,
|
required String nick,
|
||||||
required Map<String, dynamic> permNodes,
|
required Map<String, dynamic> permNodes,
|
||||||
|
required String language,
|
||||||
required SnAccountProfile? profile,
|
required SnAccountProfile? profile,
|
||||||
@Default([]) List<SnAccountBadge> badges,
|
@Default([]) List<SnAccountBadge> badges,
|
||||||
required DateTime? suspendedAt,
|
required DateTime? suspendedAt,
|
||||||
|
@ -33,6 +33,7 @@ mixin _$SnAccount {
|
|||||||
String get name => throw _privateConstructorUsedError;
|
String get name => throw _privateConstructorUsedError;
|
||||||
String get nick => throw _privateConstructorUsedError;
|
String get nick => throw _privateConstructorUsedError;
|
||||||
Map<String, dynamic> get permNodes => throw _privateConstructorUsedError;
|
Map<String, dynamic> get permNodes => throw _privateConstructorUsedError;
|
||||||
|
String get language => throw _privateConstructorUsedError;
|
||||||
SnAccountProfile? get profile => throw _privateConstructorUsedError;
|
SnAccountProfile? get profile => throw _privateConstructorUsedError;
|
||||||
List<SnAccountBadge> get badges => throw _privateConstructorUsedError;
|
List<SnAccountBadge> get badges => throw _privateConstructorUsedError;
|
||||||
DateTime? get suspendedAt => throw _privateConstructorUsedError;
|
DateTime? get suspendedAt => throw _privateConstructorUsedError;
|
||||||
@ -69,6 +70,7 @@ abstract class $SnAccountCopyWith<$Res> {
|
|||||||
String name,
|
String name,
|
||||||
String nick,
|
String nick,
|
||||||
Map<String, dynamic> permNodes,
|
Map<String, dynamic> permNodes,
|
||||||
|
String language,
|
||||||
SnAccountProfile? profile,
|
SnAccountProfile? profile,
|
||||||
List<SnAccountBadge> badges,
|
List<SnAccountBadge> badges,
|
||||||
DateTime? suspendedAt,
|
DateTime? suspendedAt,
|
||||||
@ -107,6 +109,7 @@ class _$SnAccountCopyWithImpl<$Res, $Val extends SnAccount>
|
|||||||
Object? name = null,
|
Object? name = null,
|
||||||
Object? nick = null,
|
Object? nick = null,
|
||||||
Object? permNodes = null,
|
Object? permNodes = null,
|
||||||
|
Object? language = null,
|
||||||
Object? profile = freezed,
|
Object? profile = freezed,
|
||||||
Object? badges = null,
|
Object? badges = null,
|
||||||
Object? suspendedAt = freezed,
|
Object? suspendedAt = freezed,
|
||||||
@ -164,6 +167,10 @@ class _$SnAccountCopyWithImpl<$Res, $Val extends SnAccount>
|
|||||||
? _value.permNodes
|
? _value.permNodes
|
||||||
: permNodes // ignore: cast_nullable_to_non_nullable
|
: permNodes // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>,
|
as Map<String, dynamic>,
|
||||||
|
language: null == language
|
||||||
|
? _value.language
|
||||||
|
: language // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
profile: freezed == profile
|
profile: freezed == profile
|
||||||
? _value.profile
|
? _value.profile
|
||||||
: profile // ignore: cast_nullable_to_non_nullable
|
: profile // ignore: cast_nullable_to_non_nullable
|
||||||
@ -231,6 +238,7 @@ abstract class _$$SnAccountImplCopyWith<$Res>
|
|||||||
String name,
|
String name,
|
||||||
String nick,
|
String nick,
|
||||||
Map<String, dynamic> permNodes,
|
Map<String, dynamic> permNodes,
|
||||||
|
String language,
|
||||||
SnAccountProfile? profile,
|
SnAccountProfile? profile,
|
||||||
List<SnAccountBadge> badges,
|
List<SnAccountBadge> badges,
|
||||||
DateTime? suspendedAt,
|
DateTime? suspendedAt,
|
||||||
@ -268,6 +276,7 @@ class __$$SnAccountImplCopyWithImpl<$Res>
|
|||||||
Object? name = null,
|
Object? name = null,
|
||||||
Object? nick = null,
|
Object? nick = null,
|
||||||
Object? permNodes = null,
|
Object? permNodes = null,
|
||||||
|
Object? language = null,
|
||||||
Object? profile = freezed,
|
Object? profile = freezed,
|
||||||
Object? badges = null,
|
Object? badges = null,
|
||||||
Object? suspendedAt = freezed,
|
Object? suspendedAt = freezed,
|
||||||
@ -325,6 +334,10 @@ class __$$SnAccountImplCopyWithImpl<$Res>
|
|||||||
? _value._permNodes
|
? _value._permNodes
|
||||||
: permNodes // ignore: cast_nullable_to_non_nullable
|
: permNodes // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>,
|
as Map<String, dynamic>,
|
||||||
|
language: null == language
|
||||||
|
? _value.language
|
||||||
|
: language // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
profile: freezed == profile
|
profile: freezed == profile
|
||||||
? _value.profile
|
? _value.profile
|
||||||
: profile // ignore: cast_nullable_to_non_nullable
|
: profile // ignore: cast_nullable_to_non_nullable
|
||||||
@ -373,6 +386,7 @@ class _$SnAccountImpl extends _SnAccount {
|
|||||||
required this.name,
|
required this.name,
|
||||||
required this.nick,
|
required this.nick,
|
||||||
required final Map<String, dynamic> permNodes,
|
required final Map<String, dynamic> permNodes,
|
||||||
|
required this.language,
|
||||||
required this.profile,
|
required this.profile,
|
||||||
final List<SnAccountBadge> badges = const [],
|
final List<SnAccountBadge> badges = const [],
|
||||||
required this.suspendedAt,
|
required this.suspendedAt,
|
||||||
@ -429,6 +443,8 @@ class _$SnAccountImpl extends _SnAccount {
|
|||||||
return EqualUnmodifiableMapView(_permNodes);
|
return EqualUnmodifiableMapView(_permNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String language;
|
||||||
@override
|
@override
|
||||||
final SnAccountProfile? profile;
|
final SnAccountProfile? profile;
|
||||||
final List<SnAccountBadge> _badges;
|
final List<SnAccountBadge> _badges;
|
||||||
@ -453,7 +469,7 @@ class _$SnAccountImpl extends _SnAccount {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAccount(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, confirmedAt: $confirmedAt, contacts: $contacts, avatar: $avatar, banner: $banner, description: $description, name: $name, nick: $nick, permNodes: $permNodes, profile: $profile, badges: $badges, suspendedAt: $suspendedAt, affiliatedId: $affiliatedId, affiliatedTo: $affiliatedTo, automatedBy: $automatedBy, automatedId: $automatedId)';
|
return 'SnAccount(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, confirmedAt: $confirmedAt, contacts: $contacts, avatar: $avatar, banner: $banner, description: $description, name: $name, nick: $nick, permNodes: $permNodes, language: $language, profile: $profile, badges: $badges, suspendedAt: $suspendedAt, affiliatedId: $affiliatedId, affiliatedTo: $affiliatedTo, automatedBy: $automatedBy, automatedId: $automatedId)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -479,6 +495,8 @@ class _$SnAccountImpl extends _SnAccount {
|
|||||||
(identical(other.nick, nick) || other.nick == nick) &&
|
(identical(other.nick, nick) || other.nick == nick) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other._permNodes, _permNodes) &&
|
.equals(other._permNodes, _permNodes) &&
|
||||||
|
(identical(other.language, language) ||
|
||||||
|
other.language == language) &&
|
||||||
(identical(other.profile, profile) || other.profile == profile) &&
|
(identical(other.profile, profile) || other.profile == profile) &&
|
||||||
const DeepCollectionEquality().equals(other._badges, _badges) &&
|
const DeepCollectionEquality().equals(other._badges, _badges) &&
|
||||||
(identical(other.suspendedAt, suspendedAt) ||
|
(identical(other.suspendedAt, suspendedAt) ||
|
||||||
@ -509,6 +527,7 @@ class _$SnAccountImpl extends _SnAccount {
|
|||||||
name,
|
name,
|
||||||
nick,
|
nick,
|
||||||
const DeepCollectionEquality().hash(_permNodes),
|
const DeepCollectionEquality().hash(_permNodes),
|
||||||
|
language,
|
||||||
profile,
|
profile,
|
||||||
const DeepCollectionEquality().hash(_badges),
|
const DeepCollectionEquality().hash(_badges),
|
||||||
suspendedAt,
|
suspendedAt,
|
||||||
@ -548,6 +567,7 @@ abstract class _SnAccount extends SnAccount {
|
|||||||
required final String name,
|
required final String name,
|
||||||
required final String nick,
|
required final String nick,
|
||||||
required final Map<String, dynamic> permNodes,
|
required final Map<String, dynamic> permNodes,
|
||||||
|
required final String language,
|
||||||
required final SnAccountProfile? profile,
|
required final SnAccountProfile? profile,
|
||||||
final List<SnAccountBadge> badges,
|
final List<SnAccountBadge> badges,
|
||||||
required final DateTime? suspendedAt,
|
required final DateTime? suspendedAt,
|
||||||
@ -586,6 +606,8 @@ abstract class _SnAccount extends SnAccount {
|
|||||||
@override
|
@override
|
||||||
Map<String, dynamic> get permNodes;
|
Map<String, dynamic> get permNodes;
|
||||||
@override
|
@override
|
||||||
|
String get language;
|
||||||
|
@override
|
||||||
SnAccountProfile? get profile;
|
SnAccountProfile? get profile;
|
||||||
@override
|
@override
|
||||||
List<SnAccountBadge> get badges;
|
List<SnAccountBadge> get badges;
|
||||||
|
@ -26,6 +26,7 @@ _$SnAccountImpl _$$SnAccountImplFromJson(Map<String, dynamic> json) =>
|
|||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
nick: json['nick'] as String,
|
nick: json['nick'] as String,
|
||||||
permNodes: json['perm_nodes'] as Map<String, dynamic>,
|
permNodes: json['perm_nodes'] as Map<String, dynamic>,
|
||||||
|
language: json['language'] as String,
|
||||||
profile: json['profile'] == null
|
profile: json['profile'] == null
|
||||||
? null
|
? null
|
||||||
: SnAccountProfile.fromJson(json['profile'] as Map<String, dynamic>),
|
: SnAccountProfile.fromJson(json['profile'] as Map<String, dynamic>),
|
||||||
@ -56,6 +57,7 @@ Map<String, dynamic> _$$SnAccountImplToJson(_$SnAccountImpl instance) =>
|
|||||||
'name': instance.name,
|
'name': instance.name,
|
||||||
'nick': instance.nick,
|
'nick': instance.nick,
|
||||||
'perm_nodes': instance.permNodes,
|
'perm_nodes': instance.permNodes,
|
||||||
|
'language': instance.language,
|
||||||
'profile': instance.profile?.toJson(),
|
'profile': instance.profile?.toJson(),
|
||||||
'badges': instance.badges.map((e) => e.toJson()).toList(),
|
'badges': instance.badges.map((e) => e.toJson()).toList(),
|
||||||
'suspended_at': instance.suspendedAt?.toIso8601String(),
|
'suspended_at': instance.suspendedAt?.toIso8601String(),
|
||||||
|
@ -152,6 +152,7 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> {
|
|||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
body: Stack(
|
body: Stack(
|
||||||
children: [
|
children: [
|
||||||
Builder(builder: (context) {
|
Builder(builder: (context) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user