theme work

This commit is contained in:
Christien Rioux 2023-08-17 18:10:24 -04:00
parent e76e3cf0ba
commit 411705283d
17 changed files with 373 additions and 87 deletions

View File

@ -105,6 +105,21 @@
"groups": "Groups" "groups": "Groups"
}, },
"themes": { "themes": {
"vapor": "Vapor" "vapor": "Vapor",
"scarlet": "Scarlet",
"babydoll": "Babydoll",
"gold": "Gold",
"garden": "Garden",
"forest": "Forest",
"arctic": "Arctic",
"lapis": "Lapis",
"eggplant": "Eggplant",
"lime": "Lime",
"grim": "Grim",
"contrast": "Contrast"
},
"settings_page": {
"titlebar": "Settings",
"color_theme": "Color Theme"
} }
} }

View File

@ -2,10 +2,11 @@ import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_translate/flutter_translate.dart'; import 'package:flutter_translate/flutter_translate.dart';
import 'package:go_router/go_router.dart';
class DefaultAppBar extends AppBar { class DefaultAppBar extends AppBar {
DefaultAppBar(BuildContext context, DefaultAppBar(
{required super.title, super.key, Widget? leading, List<Widget>? actions}) {required super.title, super.key, Widget? leading, super.actions})
: super( : super(
leading: leading ?? leading: leading ??
Container( Container(
@ -15,17 +16,5 @@ class DefaultAppBar extends AppBar {
shape: BoxShape.circle), shape: BoxShape.circle),
child: child:
SvgPicture.asset('assets/images/vlogo.svg', height: 32) SvgPicture.asset('assets/images/vlogo.svg', height: 32)
.paddingAll(4)), .paddingAll(4)));
actions: (actions ?? <Widget>[])
..add(
IconButton(
icon: const Icon(Icons.settings),
tooltip: translate('app_bar.settings_tooltip'),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
'Accessibility and language options coming soon')));
},
),
));
} }

View File

@ -2,6 +2,8 @@ import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
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';
import 'package:go_router/go_router.dart';
import '../tools/tools.dart'; import '../tools/tools.dart';
@ -29,10 +31,18 @@ class ProfileWidget extends ConsumerWidget {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
side: BorderSide(color: scale.primaryScale.border))), side: BorderSide(color: scale.primaryScale.border))),
child: Column(mainAxisSize: MainAxisSize.min, children: [ child: Row(children: [
Column(mainAxisSize: MainAxisSize.min, children: [
Text(name, style: textTheme.headlineSmall).paddingAll(8), Text(name, style: textTheme.headlineSmall).paddingAll(8),
if (title != null && title!.isNotEmpty) if (title != null && title!.isNotEmpty)
Text(title!, style: textTheme.bodyMedium).paddingLTRB(8, 0, 8, 8), Text(title!, style: textTheme.bodyMedium).paddingLTRB(8, 0, 8, 8),
]).expanded(),
IconButton(
icon: const Icon(Icons.settings),
tooltip: translate('app_bar.settings_tooltip'),
onPressed: () async {
context.go('/home/settings');
})
])).paddingAll(8); ])).paddingAll(8);
} }

View File

@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:signal_strength_indicator/signal_strength_indicator.dart';
import '../providers/connection_state.dart';
import '../tools/tools.dart';
class SignalStrengthMeterWidget extends ConsumerWidget {
const SignalStrengthMeterWidget({super.key});
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final scale = theme.extension<ScaleScheme>()!;
const iconSize = 16.0;
final connState = ref.watch(globalConnectionStateProvider).asData?.value;
if (connState == null) {
return const Icon(Icons.signal_cellular_off, size: iconSize);
}
late final double value;
late final Color color;
late final Color inactiveColor;
switch (connState) {
case GlobalConnectionState.detached:
return Icon(Icons.signal_cellular_nodata,
size: iconSize, color: scale.grayScale.text);
case GlobalConnectionState.detaching:
return Icon(Icons.signal_cellular_off,
size: iconSize, color: scale.grayScale.text);
case GlobalConnectionState.attaching:
value = 0;
color = scale.primaryScale.text;
case GlobalConnectionState.attachedWeak:
value = 1;
color = scale.primaryScale.text;
case GlobalConnectionState.attachedStrong:
value = 2;
color = scale.primaryScale.text;
case GlobalConnectionState.attachedGood:
value = 3;
color = scale.primaryScale.text;
case GlobalConnectionState.fullyAttached:
value = 4;
color = scale.primaryScale.text;
case GlobalConnectionState.overAttached:
value = 4;
color = scale.secondaryScale.subtleText;
}
inactiveColor = scale.grayScale.subtleText;
return SignalStrengthIndicator.bars(
value: value,
activeColor: color,
inactiveColor: inactiveColor,
size: iconSize,
barCount: 4,
spacing: 1,
);
}
}

View File

@ -7,7 +7,6 @@ import 'home.dart';
class ChatOnlyPage extends ConsumerStatefulWidget { class ChatOnlyPage extends ConsumerStatefulWidget {
const ChatOnlyPage({super.key}); const ChatOnlyPage({super.key});
static const path = '/chat';
@override @override
ChatOnlyPageState createState() => ChatOnlyPageState(); ChatOnlyPageState createState() => ChatOnlyPageState();

View File

@ -5,7 +5,6 @@ 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:split_view/split_view.dart'; import 'package:split_view/split_view.dart';
import 'package:signal_strength_indicator/signal_strength_indicator.dart';
import '../../entities/proto.dart' as proto; import '../../entities/proto.dart' as proto;
import '../components/chat_component.dart'; import '../components/chat_component.dart';
@ -21,7 +20,6 @@ import 'main_pager/main_pager.dart';
class HomePage extends ConsumerStatefulWidget { class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key}); const HomePage({super.key});
static const path = '/home';
@override @override
HomePageState createState() => HomePageState(); HomePageState createState() => HomePageState();

View File

@ -7,7 +7,6 @@ import '../providers/window_control.dart';
class IndexPage extends ConsumerWidget { class IndexPage extends ConsumerWidget {
const IndexPage({super.key}); const IndexPage({super.key});
static const path = '/';
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View File

@ -5,8 +5,10 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart'; import 'package:flutter_translate/flutter_translate.dart';
import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:go_router/go_router.dart';
import '../components/default_app_bar.dart'; import '../components/default_app_bar.dart';
import '../components/signal_strength_meter.dart';
import '../providers/local_accounts.dart'; import '../providers/local_accounts.dart';
import '../providers/logins.dart'; import '../providers/logins.dart';
import '../providers/window_control.dart'; import '../providers/window_control.dart';
@ -15,7 +17,6 @@ import '../veilid_support/veilid_support.dart';
class NewAccountPage extends ConsumerStatefulWidget { class NewAccountPage extends ConsumerStatefulWidget {
const NewAccountPage({super.key}); const NewAccountPage({super.key});
static const path = '/new_account';
@override @override
NewAccountPageState createState() => NewAccountPageState(); NewAccountPageState createState() => NewAccountPageState();
@ -136,8 +137,17 @@ class NewAccountPageState extends ConsumerState<NewAccountPage> {
return Scaffold( return Scaffold(
// resizeToAvoidBottomInset: false, // resizeToAvoidBottomInset: false,
appBar: DefaultAppBar(context, appBar: DefaultAppBar(
title: Text(translate('new_account_page.titlebar'))), title: Text(translate('new_account_page.titlebar')),
actions: [
const SignalStrengthMeterWidget(),
IconButton(
icon: const Icon(Icons.settings),
tooltip: translate('app_bar.settings_tooltip'),
onPressed: () async {
context.go('/new_account/settings');
})
]),
body: _newAccountForm( body: _newAccountForm(
context, context,
onSubmit: (formKey) async { onSubmit: (formKey) async {

View File

@ -1,28 +1,174 @@
import 'package:animated_theme_switcher/animated_theme_switcher.dart';
import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
class LoginPage extends ConsumerWidget { import '../components/default_app_bar.dart';
const LoginPage({super.key}); import '../components/signal_strength_meter.dart';
static const path = '/settings'; import '../entities/preferences.dart';
import '../providers/local_accounts.dart';
import '../providers/logins.dart';
import '../providers/window_control.dart';
import '../tools/tools.dart';
import '../veilid_support/veilid_support.dart';
class SettingsPage extends ConsumerStatefulWidget {
const SettingsPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) => const Scaffold( SettingsPageState createState() => SettingsPageState();
body: Center( }
child: Column(
mainAxisAlignment: MainAxisAlignment.center, class SettingsPageState extends ConsumerState<SettingsPage> {
final _formKey = GlobalKey<FormBuilderState>();
late bool isInAsyncCall = false;
ThemeService? themeService;
ThemePreferences? themePreferences;
static const String formFieldTheme = 'theme';
// static const String formFieldTitle = 'title';
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await ref.read(windowControlProvider.notifier).changeWindowSetup(
TitleBarStyle.normal, OrientationCapability.normal);
final tsinst = await ThemeService.instance;
setState(() {
themeService = tsinst;
themePreferences = tsinst.load();
});
});
}
List<DropdownMenuItem<dynamic>> _getThemeDropdownItems() {
const colorPrefs = ColorPreference.values;
final colorNames = {
ColorPreference.scarlet: translate('themes.scarlet'),
ColorPreference.vapor: translate('themes.vapor'),
ColorPreference.babydoll: translate('themes.babydoll'),
ColorPreference.gold: translate('themes.gold'),
ColorPreference.garden: translate('themes.garden'),
ColorPreference.forest: translate('themes.forest'),
ColorPreference.arctic: translate('themes.arctic'),
ColorPreference.lapis: translate('themes.lapis'),
ColorPreference.eggplant: translate('themes.eggplant'),
ColorPreference.lime: translate('themes.lime'),
ColorPreference.grim: translate('themes.grim'),
ColorPreference.contrast: translate('themes.contrast')
};
return colorPrefs
.map((e) => DropdownMenuItem(value: e, child: Text(colorNames[e]!)))
.toList();
}
@override
Widget build(BuildContext context) {
ref.watch(windowControlProvider);
final themeService = ref.watch(themeServiceProvider).asData();
return ThemeSwitchingArea(
child: Scaffold(
// resizeToAvoidBottomInset: false,
appBar: DefaultAppBar(
title: Text(translate('settings_page.titlebar')),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => context.pop<void>(),
),
actions: const <Widget>[
SignalStrengthMeterWidget(),
]),
body: FormBuilder(
key: _formKey,
child: ListView(
children: [ children: [
Text('Settings Page'), ThemeSwitcher.withTheme(
builder: (_, switcher, theme) => FormBuilderDropdown(
name: formFieldTheme,
decoration: InputDecoration(
label: Text(translate('settings_page.color_theme'))),
items: _getThemeDropdownItems(),
initialValue: themePreferences?.colorPreference,
onChanged: (value) async {
final tprefs = themePreferences;
if (tprefs != null) {
final newPrefs = tprefs.copyWith(
colorPreference: value as ColorPreference);
final tservice = themeService;
if (tservice != null) {
await tservice.save(newPrefs);
switcher.changeTheme(theme: tservice.get(newPrefs));
}
setState(() {
themePreferences = newPrefs;
});
}
}))
// Text(translate('settings_page.header'))
// .textStyle(context.headlineSmall)
// .paddingSymmetric(vertical: 16),
// FormBuilderTextField(
// autofocus: true,
// name: formFieldName,
// decoration:
// InputDecoration(hintText: translate('account.form_name')),
// maxLength: 64,
// // The validator receives the text that the user has entered.
// validator: FormBuilderValidators.compose([
// FormBuilderValidators.required(),
// ]),
// ),
// FormBuilderTextField(
// name: formFieldTitle,
// maxLength: 64,
// decoration:
// InputDecoration(hintText: translate('account.form_title')),
// ),
// Row(children: [
// const Spacer(),
// Text(translate('new_account_page.instructions'))
// .toCenter()
// .flexible(flex: 6),
// const Spacer(),
// ]).paddingSymmetric(vertical: 4),
// ElevatedButton( // ElevatedButton(
// onPressed: () async { // onPressed: () async {
// ref.watch(authNotifierProvider.notifier).login( // if (_formKey.currentState?.saveAndValidate() ?? false) {
// "myEmail", // setState(() {
// "myPassword", // isInAsyncCall = true;
// ); // });
// try {
// await onSubmit(_formKey);
// } finally {
// if (mounted) {
// setState(() {
// isInAsyncCall = false;
// });
// }
// }
// }
// }, // },
// child: const Text("Login"), // child: Text(translate('new_account_page.create')),
// ), // ).paddingSymmetric(vertical: 4).alignAtCenterRight(),
], ],
), ),
), ).paddingSymmetric(horizontal: 24, vertical: 8),
); ));
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<bool>('isInAsyncCall', isInAsyncCall));
}
} }

View File

@ -2,7 +2,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../tools/tools.dart'; import '../tools/tools.dart';
enum ConnectionState { enum GlobalConnectionState {
detached, detached,
detaching, detaching,
attaching, attaching,
@ -13,7 +13,7 @@ enum ConnectionState {
overAttached, overAttached,
} }
ExternalStreamState<ConnectionState> globalConnectionState = ExternalStreamState<GlobalConnectionState> globalConnectionState =
ExternalStreamState<ConnectionState>(ConnectionState.detached); ExternalStreamState<GlobalConnectionState>(GlobalConnectionState.detached);
AutoDisposeStreamProvider<ConnectionState> globalConnectionStateProvider = AutoDisposeStreamProvider<GlobalConnectionState> globalConnectionStateProvider =
globalConnectionState.provider(); globalConnectionState.provider();

View File

@ -17,7 +17,7 @@ GoRouter router(RouterRef ref) {
navigatorKey: _key, navigatorKey: _key,
refreshListenable: notifier, refreshListenable: notifier,
debugLogDiagnostics: true, debugLogDiagnostics: true,
initialLocation: IndexPage.path, initialLocation: '/',
routes: notifier.routes, routes: notifier.routes,
redirect: notifier.redirect, redirect: notifier.redirect,
); );

View File

@ -6,7 +6,7 @@ part of 'router.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$routerHash() => r'2273f69a347c52bbb53358ac9034ab0ea760ecce'; String _$routerHash() => r'86eecb1955be62ef8e6f6efcec0fa615289cb823';
/// This simple provider caches our GoRouter. /// This simple provider caches our GoRouter.
/// ///

View File

@ -6,6 +6,7 @@ import '../pages/chat_only_page.dart';
import '../pages/home.dart'; import '../pages/home.dart';
import '../pages/index.dart'; import '../pages/index.dart';
import '../pages/new_account.dart'; import '../pages/new_account.dart';
import '../pages/settings.dart';
import '../providers/chat.dart'; import '../providers/chat.dart';
import '../providers/local_accounts.dart'; import '../providers/local_accounts.dart';
import '../tools/responsive.dart'; import '../tools/responsive.dart';
@ -47,13 +48,13 @@ class RouterNotifier extends _$RouterNotifier implements Listenable {
// No matter where we are, if there's not // No matter where we are, if there's not
switch (state.location) { switch (state.location) {
case IndexPage.path: case '/':
return hasAnyAccount ? HomePage.path : NewAccountPage.path; return hasAnyAccount ? '/home' : '/new_account';
case NewAccountPage.path: case '/new_account':
return hasAnyAccount ? HomePage.path : null; return hasAnyAccount ? '/home' : null;
case HomePage.path: case '/home':
if (!hasAnyAccount) { if (!hasAnyAccount) {
return NewAccountPage.path; return '/new_account';
} }
if (responsiveVisibility( if (responsiveVisibility(
context: context, context: context,
@ -61,13 +62,13 @@ class RouterNotifier extends _$RouterNotifier implements Listenable {
tabletLandscape: false, tabletLandscape: false,
desktop: false)) { desktop: false)) {
if (hasActiveChat) { if (hasActiveChat) {
return ChatOnlyPage.path; return '/home/chat';
} }
} }
return null; return null;
case ChatOnlyPage.path: case '/home/chat':
if (!hasAnyAccount) { if (!hasAnyAccount) {
return NewAccountPage.path; return '/new_account';
} }
if (responsiveVisibility( if (responsiveVisibility(
context: context, context: context,
@ -75,35 +76,50 @@ class RouterNotifier extends _$RouterNotifier implements Listenable {
tabletLandscape: false, tabletLandscape: false,
desktop: false)) { desktop: false)) {
if (!hasActiveChat) { if (!hasActiveChat) {
return HomePage.path; return '/home';
} }
} else { } else {
return HomePage.path; return '/home';
} }
return null; return null;
case '/home/settings':
case '/new_account/settings':
return null;
default: default:
return hasAnyAccount ? null : NewAccountPage.path; return hasAnyAccount ? null : '/new_account';
} }
} }
/// Our application routes /// Our application routes
List<GoRoute> get routes => [ List<GoRoute> get routes => [
GoRoute( GoRoute(
path: IndexPage.path, path: '/',
builder: (context, state) => const IndexPage(), builder: (context, state) => const IndexPage(),
), ),
GoRoute( GoRoute(
path: HomePage.path, path: '/home',
builder: (context, state) => const HomePage(), builder: (context, state) => const HomePage(),
routes: [
GoRoute(
path: 'settings',
builder: (context, state) => const SettingsPage(),
), ),
GoRoute( GoRoute(
path: NewAccountPage.path, path: 'chat',
builder: (context, state) => const NewAccountPage(),
),
GoRoute(
path: ChatOnlyPage.path,
builder: (context, state) => const ChatOnlyPage(), builder: (context, state) => const ChatOnlyPage(),
), ),
],
),
GoRoute(
path: '/new_account',
builder: (context, state) => const NewAccountPage(),
routes: [
GoRoute(
path: 'settings',
builder: (context, state) => const SettingsPage(),
),
],
),
]; ];
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////

View File

@ -6,7 +6,7 @@ part of 'router_notifier.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$routerNotifierHash() => r'6493fee7e11afead973a5bece304b3c94f7fa1c6'; String _$routerNotifierHash() => r'745bae688e8675c3046b95f29cbe0122bac3f189';
/// See also [RouterNotifier]. /// See also [RouterNotifier].
@ProviderFor(RouterNotifier) @ProviderFor(RouterNotifier)

View File

@ -4,11 +4,14 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart'; import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:riverpod_annotation/riverpod_annotation.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';
part 'theme_service.g.dart';
class ScaleColor { class ScaleColor {
ScaleColor({ ScaleColor({
required this.appBackground, required this.appBackground,
@ -191,15 +194,27 @@ class ThemeService {
Brightness.dark; Brightness.dark;
ThemeData get initial { ThemeData get initial {
final themePreferences = load();
return get(themePreferences);
}
ThemePreferences load() {
final themePreferencesJson = prefs.getString('themePreferences'); final themePreferencesJson = prefs.getString('themePreferences');
final themePreferences = themePreferencesJson != null ThemePreferences? themePreferences;
? ThemePreferences.fromJson(themePreferencesJson) if (themePreferencesJson != null) {
: const ThemePreferences( try {
themePreferences = ThemePreferences.fromJson(themePreferencesJson);
// ignore: avoid_catches_without_on_clauses
} catch (_) {
// ignore
}
}
return themePreferences ??
const ThemePreferences(
colorPreference: ColorPreference.vapor, colorPreference: ColorPreference.vapor,
brightnessPreference: BrightnessPreference.system, brightnessPreference: BrightnessPreference.system,
displayScale: 1, displayScale: 1,
); );
return get(themePreferences);
} }
Future<void> save(ThemePreferences themePreferences) async { Future<void> save(ThemePreferences themePreferences) async {
@ -256,3 +271,6 @@ class ThemeService {
return themeData; return themeData;
} }
} }
@riverpod
Future<ThemeService> themeService() => ThemeService.instance;

View File

@ -0,0 +1,23 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'theme_service.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$themeServiceHash() => r'a319ae893d3b5cf5718a0c1a21c22bd073f5fd34';
/// See also [themeService].
@ProviderFor(themeService)
final themeServiceProvider = AutoDisposeFutureProvider<ThemeService>.internal(
themeService,
name: r'themeServiceProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$themeServiceHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef ThemeServiceRef = AutoDisposeFutureProviderRef<ThemeService>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions

View File

@ -61,42 +61,42 @@ class Processor {
//loggy.info("Attachment: ${updateAttachment.json}"); //loggy.info("Attachment: ${updateAttachment.json}");
// Set connection meter and ui state for connection state // Set connection meter and ui state for connection state
var cs = ConnectionState.detached; var cs = GlobalConnectionState.detached;
var checkPublicInternet = false; var checkPublicInternet = false;
switch (updateAttachment.state) { switch (updateAttachment.state) {
case AttachmentState.detached: case AttachmentState.detached:
cs = ConnectionState.detached; cs = GlobalConnectionState.detached;
break; break;
case AttachmentState.detaching: case AttachmentState.detaching:
cs = ConnectionState.detaching; cs = GlobalConnectionState.detaching;
break; break;
case AttachmentState.attaching: case AttachmentState.attaching:
cs = ConnectionState.attaching; cs = GlobalConnectionState.attaching;
break; break;
case AttachmentState.attachedWeak: case AttachmentState.attachedWeak:
checkPublicInternet = true; checkPublicInternet = true;
cs = ConnectionState.attachedWeak; cs = GlobalConnectionState.attachedWeak;
break; break;
case AttachmentState.attachedGood: case AttachmentState.attachedGood:
checkPublicInternet = true; checkPublicInternet = true;
cs = ConnectionState.attachedGood; cs = GlobalConnectionState.attachedGood;
break; break;
case AttachmentState.attachedStrong: case AttachmentState.attachedStrong:
checkPublicInternet = true; checkPublicInternet = true;
cs = ConnectionState.attachedStrong; cs = GlobalConnectionState.attachedStrong;
break; break;
case AttachmentState.fullyAttached: case AttachmentState.fullyAttached:
checkPublicInternet = true; checkPublicInternet = true;
cs = ConnectionState.fullyAttached; cs = GlobalConnectionState.fullyAttached;
break; break;
case AttachmentState.overAttached: case AttachmentState.overAttached:
checkPublicInternet = true; checkPublicInternet = true;
cs = ConnectionState.overAttached; cs = GlobalConnectionState.overAttached;
break; break;
} }
if (checkPublicInternet) { if (checkPublicInternet) {
if (!updateAttachment.publicInternetReady) { if (!updateAttachment.publicInternetReady) {
cs = ConnectionState.attaching; cs = GlobalConnectionState.attaching;
} }
} }