Compare commits
1 Commits
trunk
...
post-stabl
Author | SHA1 | Date |
---|---|---|
Sarah Jamie Lewis | 7397ad0ee2 |
|
@ -2,6 +2,8 @@
|
||||||
// Details: https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html
|
// Details: https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import '../models/acl.dart';
|
||||||
|
|
||||||
const DefaultPassword = "be gay do crime";
|
const DefaultPassword = "be gay do crime";
|
||||||
|
|
||||||
const LastMessageSeenTimeKey = "profile.lastMessageSeenTime";
|
const LastMessageSeenTimeKey = "profile.lastMessageSeenTime";
|
||||||
|
@ -159,5 +161,7 @@ abstract class Cwtch {
|
||||||
void PublishServerUpdate(String onion);
|
void PublishServerUpdate(String onion);
|
||||||
Future<void> ConfigureConnections(String onion, bool listen, bool peers, bool servers);
|
Future<void> ConfigureConnections(String onion, bool listen, bool peers, bool servers);
|
||||||
|
|
||||||
|
Future<AccessControlList> GetConversationAccessControlList(String profile, int conversation);
|
||||||
|
|
||||||
bool IsLoaded();
|
bool IsLoaded();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
import 'package:cwtch/cwtch/cwtchNotifier.dart';
|
import 'package:cwtch/cwtch/cwtchNotifier.dart';
|
||||||
|
import 'package:cwtch/models/acl.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
|
@ -1141,4 +1142,17 @@ class CwtchFfi implements Cwtch {
|
||||||
EnvironmentConfig.debugLog("Checking that the FFI Interface is Correctly Loaded... $check");
|
EnvironmentConfig.debugLog("Checking that the FFI Interface is Correctly Loaded... $check");
|
||||||
return check;
|
return check;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<AccessControlList> GetConversationAccessControlList(String profile, int conversation) {
|
||||||
|
var getConversationACLC = library.lookup<NativeFunction<get_json_blob_from_str_int_function>>("c_GetConversationAccessControlList");
|
||||||
|
// ignore: non_constant_identifier_names
|
||||||
|
final GetConversationACL = getConversationACLC.asFunction<GetJsonBlobFromStrIntFn>();
|
||||||
|
final utf8profile = profile.toNativeUtf8();
|
||||||
|
Pointer<Utf8> aclRaw = GetConversationACL(utf8profile, utf8profile.length, conversation);
|
||||||
|
AccessControlList acl = AccessControl.FromJson(aclRaw.toDartString());
|
||||||
|
_UnsafeFreePointerAnyUseOfThisFunctionMustBeDoubleApproved(aclRaw);
|
||||||
|
malloc.free(utf8profile);
|
||||||
|
return Future.value(acl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:collection';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:cwtch/config.dart';
|
import 'package:cwtch/config.dart';
|
||||||
|
import 'package:cwtch/models/acl.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
@ -479,4 +480,12 @@ class CwtchGomobile implements Cwtch {
|
||||||
bool IsLoaded() {
|
bool IsLoaded() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<AccessControlList> GetConversationAccessControlList(String profile, int conversation) async {
|
||||||
|
return await cwtchPlatform.invokeMethod("GetConversationAttribute", {"ProfileOnion": profile, "conversation": conversation}).then((dynamic json) {
|
||||||
|
AccessControlList acl = AccessControl.FromJson(json);
|
||||||
|
return acl;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
typedef AccessControlList = Map<String, AccessControl>;
|
||||||
|
|
||||||
|
class AccessControl {
|
||||||
|
bool Blocked = false;
|
||||||
|
bool AutoConnect = false;
|
||||||
|
bool ExchangeAttributes = false;
|
||||||
|
bool ShareFiles = false;
|
||||||
|
bool RenderImages = false;
|
||||||
|
AccessControl({this.Blocked = false, this.AutoConnect = false, this.ExchangeAttributes = false, this.ShareFiles = false, this.RenderImages = false});
|
||||||
|
|
||||||
|
static AccessControlList FromJson(String json) {
|
||||||
|
Map<String, dynamic> accessControlList = jsonDecode(json);
|
||||||
|
return accessControlList.map((key, value) => MapEntry(
|
||||||
|
key,
|
||||||
|
AccessControl(
|
||||||
|
Blocked: value["Blocked"], ExchangeAttributes: value["ExchangeAttributes"], AutoConnect: value["AutoConnect"], RenderImages: value["RenderImages"], ShareFiles: value["ShareFiles"])));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {'Blocked': Blocked, 'AutoConnect': AutoConnect, 'ExchangeAttributes': ExchangeAttributes, 'ShareFiles': ShareFiles, 'RenderImages': RenderImages};
|
||||||
|
}
|
||||||
|
}
|
|
@ -123,7 +123,9 @@ abstract class OpaqueThemeType {
|
||||||
|
|
||||||
get chatImage => null;
|
get chatImage => null;
|
||||||
|
|
||||||
ImageProvider loadImage(String key, {BuildContext? context}) { return AssetImage(""); }
|
ImageProvider loadImage(String key, {BuildContext? context}) {
|
||||||
|
return AssetImage("");
|
||||||
|
}
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
double contactOnionTextSize() {
|
double contactOnionTextSize() {
|
||||||
|
|
|
@ -149,10 +149,7 @@ class YmlTheme extends OpaqueThemeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
File af = File(path.join(Provider
|
File af = File(path.join(Provider.of<FlwtchState>(context, listen: false).cwtch.getAssetsDir(), key));
|
||||||
.of<FlwtchState>(context, listen: false)
|
|
||||||
.cwtch
|
|
||||||
.getAssetsDir(), key));
|
|
||||||
if (af.existsSync()) {
|
if (af.existsSync()) {
|
||||||
return FileImage(af);
|
return FileImage(af);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,154 +19,104 @@ class GlobalSettingsAboutView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GlobalSettingsAboutViewState extends State<GlobalSettingsAboutView> {
|
class _GlobalSettingsAboutViewState extends State<GlobalSettingsAboutView> {
|
||||||
|
|
||||||
ScrollController settingsListScrollController = ScrollController();
|
ScrollController settingsListScrollController = ScrollController();
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
var appIcon = Icon(Icons.info, color: settings.current().mainTextColor);
|
||||||
var appIcon = Icon(Icons.info, color: settings
|
return Scrollbar(
|
||||||
.current()
|
key: Key("AboutSettingsView"),
|
||||||
.mainTextColor);
|
trackVisibility: true,
|
||||||
return Scrollbar(
|
controller: settingsListScrollController,
|
||||||
key: Key("AboutSettingsView"),
|
child: SingleChildScrollView(
|
||||||
trackVisibility: true,
|
clipBehavior: Clip.antiAlias,
|
||||||
controller: settingsListScrollController,
|
controller: settingsListScrollController,
|
||||||
child: SingleChildScrollView(
|
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||||
clipBehavior: Clip.antiAlias,
|
child: ConstrainedBox(
|
||||||
controller: settingsListScrollController,
|
constraints: BoxConstraints(
|
||||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
minHeight: viewportConstraints.maxHeight,
|
||||||
child: ConstrainedBox(
|
),
|
||||||
constraints: BoxConstraints(
|
child: Column(children: [
|
||||||
minHeight: viewportConstraints.maxHeight,
|
AboutListTile(
|
||||||
),
|
icon: appIcon,
|
||||||
child: Column(children: [
|
applicationIcon: Padding(padding: EdgeInsets.all(5), child: Icon(CwtchIcons.cwtch_knott)),
|
||||||
AboutListTile(
|
applicationName: "Cwtch UI",
|
||||||
icon: appIcon,
|
applicationLegalese: '\u{a9} 2021-2023 Open Privacy Research Society',
|
||||||
applicationIcon: Padding(
|
aboutBoxChildren: <Widget>[
|
||||||
padding: EdgeInsets.all(5),
|
Padding(
|
||||||
child: Icon(CwtchIcons.cwtch_knott)),
|
padding: EdgeInsets.fromLTRB(24.0 + 10.0 + (appIcon.size ?? 24.0), 16.0, 0.0, 0.0),
|
||||||
applicationName: "Cwtch UI",
|
// About has 24 padding (ln 389) and there appears to be another 10 of padding in the widget
|
||||||
applicationLegalese:
|
child: SelectableText(AppLocalizations.of(context)!.versionBuilddate.replaceAll("%1", EnvironmentConfig.BUILD_VER).replaceAll("%2", EnvironmentConfig.BUILD_DATE)),
|
||||||
'\u{a9} 2021-2023 Open Privacy Research Society',
|
)
|
||||||
aboutBoxChildren: <Widget>[
|
]),
|
||||||
Padding(
|
SwitchListTile(
|
||||||
padding: EdgeInsets.fromLTRB(
|
// TODO: Translate, Remove, OR Hide Prior to Release
|
||||||
24.0 + 10.0 + (appIcon.size ?? 24.0),
|
title: Text("Show Performance Overlay"),
|
||||||
16.0,
|
subtitle: Text("Display an overlay graph of render time."),
|
||||||
0.0,
|
value: settings.profileMode,
|
||||||
0.0),
|
onChanged: (bool value) {
|
||||||
// About has 24 padding (ln 389) and there appears to be another 10 of padding in the widget
|
setState(() {
|
||||||
child: SelectableText(
|
if (value) {
|
||||||
AppLocalizations.of(context)!
|
settings.profileMode = value;
|
||||||
.versionBuilddate
|
} else {
|
||||||
.replaceAll(
|
settings.profileMode = value;
|
||||||
"%1", EnvironmentConfig.BUILD_VER)
|
}
|
||||||
.replaceAll("%2",
|
});
|
||||||
EnvironmentConfig.BUILD_DATE)),
|
},
|
||||||
)
|
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||||
]),
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
SwitchListTile(
|
secondary: Icon(Icons.bar_chart, color: settings.current().mainTextColor),
|
||||||
// TODO: Translate, Remove, OR Hide Prior to Release
|
),
|
||||||
title: Text("Show Performance Overlay"),
|
Visibility(
|
||||||
subtitle:
|
visible: EnvironmentConfig.BUILD_VER == dev_version && !Platform.isAndroid,
|
||||||
Text("Display an overlay graph of render time."),
|
child: SwitchListTile(
|
||||||
value: settings.profileMode,
|
title: Text("Show Semantic Debugger"),
|
||||||
|
subtitle: Text("Show Accessibility Debugging View"),
|
||||||
|
value: settings.useSemanticDebugger,
|
||||||
onChanged: (bool value) {
|
onChanged: (bool value) {
|
||||||
setState(() {
|
if (value) {
|
||||||
if (value) {
|
settings.useSemanticDebugger = value;
|
||||||
settings.profileMode = value;
|
} else {
|
||||||
} else {
|
settings.useSemanticDebugger = value;
|
||||||
settings.profileMode = value;
|
}
|
||||||
}
|
saveSettings(context);
|
||||||
});
|
|
||||||
},
|
},
|
||||||
activeTrackColor:
|
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||||
settings.theme.defaultButtonActiveColor,
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
inactiveTrackColor:
|
secondary: Icon(Icons.settings_accessibility, color: settings.current().mainTextColor),
|
||||||
settings.theme.defaultButtonDisabledColor,
|
)),
|
||||||
secondary: Icon(Icons.bar_chart,
|
Visibility(
|
||||||
color: settings
|
visible: EnvironmentConfig.BUILD_VER == dev_version && !Platform.isAndroid,
|
||||||
.current()
|
child: FutureBuilder(
|
||||||
.mainTextColor),
|
future: EnvironmentConfig.BUILD_VER != dev_version || Platform.isAndroid ? null : Provider.of<FlwtchState>(context).cwtch.GetDebugInfo(),
|
||||||
),
|
builder: (context, snapshot) {
|
||||||
Visibility(
|
if (snapshot.hasData) {
|
||||||
visible:
|
return Column(
|
||||||
EnvironmentConfig.BUILD_VER == dev_version &&
|
children: [
|
||||||
!Platform.isAndroid,
|
Text("libCwtch Debug Info: " + snapshot.data.toString()),
|
||||||
child: SwitchListTile(
|
Text("Message Cache Size (Mb): " + (Provider.of<FlwtchState>(context).profs.cacheMemUsage() / (1024 * 1024)).toString())
|
||||||
title: Text("Show Semantic Debugger"),
|
],
|
||||||
subtitle:
|
);
|
||||||
Text("Show Accessibility Debugging View"),
|
} else {
|
||||||
value: settings.useSemanticDebugger,
|
return Container();
|
||||||
onChanged: (bool value) {
|
}
|
||||||
if (value) {
|
},
|
||||||
settings.useSemanticDebugger = value;
|
),
|
||||||
} else {
|
),
|
||||||
settings.useSemanticDebugger = value;
|
Visibility(
|
||||||
}
|
visible: EnvironmentConfig.BUILD_VER == dev_version,
|
||||||
saveSettings(context);
|
child: FutureBuilder(
|
||||||
},
|
future: Provider.of<FlwtchState>(context).cwtch.PlatformChannelInfo(),
|
||||||
activeTrackColor:
|
|
||||||
settings.theme.defaultButtonActiveColor,
|
|
||||||
inactiveTrackColor:
|
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(Icons.settings_accessibility,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
)),
|
|
||||||
Visibility(
|
|
||||||
visible: EnvironmentConfig.BUILD_VER == dev_version &&
|
|
||||||
!Platform.isAndroid,
|
|
||||||
child: FutureBuilder(
|
|
||||||
future:
|
|
||||||
EnvironmentConfig.BUILD_VER != dev_version ||
|
|
||||||
Platform.isAndroid
|
|
||||||
? null
|
|
||||||
: Provider
|
|
||||||
.of<FlwtchState>(context)
|
|
||||||
.cwtch
|
|
||||||
.GetDebugInfo(),
|
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
return Column(
|
HashMap<String, String> data = snapshot.data as HashMap<String, String>;
|
||||||
children: [
|
return getPlatformInfo(settings, data);
|
||||||
Text("libCwtch Debug Info: " +
|
|
||||||
snapshot.data.toString()),
|
|
||||||
Text("Message Cache Size (Mb): " +
|
|
||||||
(Provider
|
|
||||||
.of<FlwtchState>(context)
|
|
||||||
.profs
|
|
||||||
.cacheMemUsage() /
|
|
||||||
(1024 * 1024))
|
|
||||||
.toString())
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Container();
|
|
||||||
}
|
}
|
||||||
},
|
return Container();
|
||||||
),
|
}))
|
||||||
),
|
]))));
|
||||||
Visibility(
|
});
|
||||||
visible: EnvironmentConfig.BUILD_VER == dev_version,
|
|
||||||
child: FutureBuilder(
|
|
||||||
future: Provider
|
|
||||||
.of<FlwtchState>(context)
|
|
||||||
.cwtch
|
|
||||||
.PlatformChannelInfo(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.hasData) {
|
|
||||||
HashMap<String, String> data = snapshot.data
|
|
||||||
as HashMap<String, String>;
|
|
||||||
return getPlatformInfo(settings, data);
|
|
||||||
}
|
|
||||||
return Container();
|
|
||||||
}))
|
|
||||||
]))));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,4 +144,4 @@ class _GlobalSettingsAboutViewState extends State<GlobalSettingsAboutView> {
|
||||||
}
|
}
|
||||||
return pinfo.version + "." + pinfo.buildNumber;
|
return pinfo.version + "." + pinfo.buildNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,301 +15,186 @@ class GlobalSettingsAppearanceView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceView> {
|
class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceView> {
|
||||||
|
|
||||||
ScrollController settingsListScrollController = ScrollController();
|
ScrollController settingsListScrollController = ScrollController();
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
return Scrollbar(
|
||||||
return Scrollbar(
|
key: Key("AppearanceSettingsView"),
|
||||||
key: Key("AppearanceSettingsView"),
|
trackVisibility: true,
|
||||||
trackVisibility: true,
|
controller: settingsListScrollController,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
controller: settingsListScrollController,
|
controller: settingsListScrollController,
|
||||||
child: SingleChildScrollView(
|
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||||
clipBehavior: Clip.antiAlias,
|
child: ConstrainedBox(
|
||||||
controller: settingsListScrollController,
|
constraints: BoxConstraints(
|
||||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
minHeight: viewportConstraints.maxHeight,
|
||||||
child: ConstrainedBox(
|
),
|
||||||
constraints: BoxConstraints(
|
child: Column(children: [
|
||||||
minHeight: viewportConstraints.maxHeight,
|
ListTile(
|
||||||
),
|
title: Text(AppLocalizations.of(context)!.settingLanguage),
|
||||||
child: Column(children: [
|
leading: Icon(CwtchIcons.change_language, color: settings.current().mainTextColor),
|
||||||
ListTile(
|
trailing: Container(
|
||||||
title: Text(
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
AppLocalizations.of(context)!.settingLanguage),
|
child: DropdownButton(
|
||||||
leading: Icon(CwtchIcons.change_language,
|
key: Key("languagelist"),
|
||||||
color: settings
|
isExpanded: true,
|
||||||
.current()
|
value: Provider.of<Settings>(context).locale.toString(),
|
||||||
.mainTextColor),
|
onChanged: (String? newValue) {
|
||||||
trailing: Container(
|
setState(() {
|
||||||
width: MediaQuery
|
EnvironmentConfig.debugLog("setting language: $newValue");
|
||||||
.of(context)
|
settings.switchLocaleByCode(newValue!);
|
||||||
.size
|
saveSettings(context);
|
||||||
.width / 4,
|
});
|
||||||
child: DropdownButton(
|
},
|
||||||
key: Key("languagelist"),
|
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
|
||||||
isExpanded: true,
|
return DropdownMenuItem<String>(
|
||||||
value: Provider
|
value: value.toString(),
|
||||||
.of<Settings>(context)
|
child: Text(
|
||||||
.locale
|
key: Key("dropdownLanguage" + value.languageCode),
|
||||||
.toString(),
|
getLanguageFull(context, value.languageCode, value.countryCode),
|
||||||
onChanged: (String? newValue) {
|
style: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
|
||||||
setState(() {
|
overflow: TextOverflow.ellipsis,
|
||||||
EnvironmentConfig.debugLog(
|
),
|
||||||
"setting language: $newValue");
|
);
|
||||||
settings.switchLocaleByCode(newValue!);
|
}).toList()))),
|
||||||
saveSettings(context);
|
SwitchListTile(
|
||||||
});
|
title: Text(AppLocalizations.of(context)!.settingTheme),
|
||||||
},
|
value: settings.current().mode == mode_light,
|
||||||
items: AppLocalizations.supportedLocales
|
onChanged: (bool value) {
|
||||||
.map<DropdownMenuItem<String>>(
|
if (value) {
|
||||||
(Locale value) {
|
settings.setTheme(settings.theme.theme, mode_light);
|
||||||
return DropdownMenuItem<String>(
|
} else {
|
||||||
value: value.toString(),
|
settings.setTheme(settings.theme.theme, mode_dark);
|
||||||
child: Text(
|
}
|
||||||
key: Key("dropdownLanguage" +
|
|
||||||
value.languageCode),
|
|
||||||
getLanguageFull(
|
|
||||||
context,
|
|
||||||
value.languageCode,
|
|
||||||
value.countryCode),
|
|
||||||
style: settings.scaleFonts(
|
|
||||||
defaultDropDownMenuItemTextStyle),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList()))),
|
|
||||||
SwitchListTile(
|
|
||||||
title:
|
|
||||||
Text(AppLocalizations.of(context)!.settingTheme),
|
|
||||||
value: settings
|
|
||||||
.current()
|
|
||||||
.mode == mode_light,
|
|
||||||
onChanged: (bool value) {
|
|
||||||
if (value) {
|
|
||||||
settings.setTheme(
|
|
||||||
settings.theme.theme, mode_light);
|
|
||||||
} else {
|
|
||||||
settings.setTheme(
|
|
||||||
settings.theme.theme, mode_dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save Settings...
|
// Save Settings...
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
activeTrackColor: settings.theme.defaultButtonColor,
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
inactiveTrackColor:
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
settings.theme.defaultButtonDisabledColor,
|
secondary: Icon(CwtchIcons.change_theme, color: settings.current().mainTextColor),
|
||||||
secondary: Icon(CwtchIcons.change_theme,
|
),
|
||||||
color: settings
|
ListTile(
|
||||||
.current()
|
title: Text(AppLocalizations.of(context)!.themeColorLabel),
|
||||||
.mainTextColor),
|
trailing: Container(
|
||||||
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
key: Key("DropdownTheme"),
|
||||||
|
isExpanded: true,
|
||||||
|
value: Provider.of<Settings>(context).theme.theme,
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
settings.setTheme(newValue!, settings.theme.mode);
|
||||||
|
saveSettings(context);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
items: themes.keys.map<DropdownMenuItem<String>>((String themeId) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: themeId,
|
||||||
|
child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
|
||||||
|
);
|
||||||
|
}).toList())),
|
||||||
|
leading: Icon(Icons.palette, color: settings.current().mainTextColor),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text(AppLocalizations.of(context)!.settingUIColumnPortrait),
|
||||||
|
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor),
|
||||||
|
trailing: Container(
|
||||||
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
|
child: DropdownButton(
|
||||||
|
isExpanded: true,
|
||||||
|
value: settings.uiColumnModePortrait.toString(),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
settings.uiColumnModePortrait = Settings.uiColumnModeFromString(newValue!);
|
||||||
|
saveSettings(context);
|
||||||
|
},
|
||||||
|
items: Settings.uiColumnModeOptions(false).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: value.toString(),
|
||||||
|
child: Text(Settings.uiColumnModeToString(value, context), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||||
|
);
|
||||||
|
}).toList()))),
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
AppLocalizations.of(context)!.settingUIColumnLandscape,
|
||||||
|
textWidthBasis: TextWidthBasis.longestLine,
|
||||||
|
softWrap: true,
|
||||||
),
|
),
|
||||||
ListTile(
|
leading: Icon(Icons.stay_primary_landscape, color: settings.current().mainTextColor),
|
||||||
title: Text(
|
trailing: Container(
|
||||||
AppLocalizations.of(context)!.themeColorLabel),
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
trailing: Container(
|
child: Container(
|
||||||
width: MediaQuery
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
.of(context)
|
|
||||||
.size
|
|
||||||
.width / 4,
|
|
||||||
child: DropdownButton<String>(
|
|
||||||
key: Key("DropdownTheme"),
|
|
||||||
isExpanded: true,
|
|
||||||
value: Provider
|
|
||||||
.of<Settings>(context)
|
|
||||||
.theme
|
|
||||||
.theme,
|
|
||||||
onChanged: (String? newValue) {
|
|
||||||
setState(() {
|
|
||||||
settings.setTheme(
|
|
||||||
newValue!, settings.theme.mode);
|
|
||||||
saveSettings(context);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
items: themes.keys
|
|
||||||
.map<DropdownMenuItem<String>>(
|
|
||||||
(String themeId) {
|
|
||||||
return DropdownMenuItem<String>(
|
|
||||||
value: themeId,
|
|
||||||
child: Text(
|
|
||||||
getThemeName(context, themeId),
|
|
||||||
style: settings.scaleFonts(
|
|
||||||
defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
|
|
||||||
);
|
|
||||||
}).toList())),
|
|
||||||
leading: Icon(Icons.palette,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text(AppLocalizations.of(context)!
|
|
||||||
.settingUIColumnPortrait),
|
|
||||||
leading: Icon(Icons.table_chart,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
trailing: Container(
|
|
||||||
width: MediaQuery
|
|
||||||
.of(context)
|
|
||||||
.size
|
|
||||||
.width / 4,
|
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: settings.uiColumnModePortrait
|
value: settings.uiColumnModeLandscape.toString(),
|
||||||
.toString(),
|
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
settings.uiColumnModePortrait =
|
settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!);
|
||||||
Settings.uiColumnModeFromString(
|
|
||||||
newValue!);
|
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
items: Settings.uiColumnModeOptions(false)
|
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||||
.map<DropdownMenuItem<String>>(
|
return DropdownMenuItem<String>(
|
||||||
(DualpaneMode value) {
|
value: value.toString(),
|
||||||
return DropdownMenuItem<String>(
|
child: Text(Settings.uiColumnModeToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||||
value: value.toString(),
|
);
|
||||||
child: Text(
|
}).toList())))),
|
||||||
Settings.uiColumnModeToString(
|
ListTile(
|
||||||
value, context),
|
title: Text(AppLocalizations.of(context)!.defaultScalingText),
|
||||||
style: settings.scaleFonts(
|
subtitle: Text(AppLocalizations.of(context)!.fontScalingDescription),
|
||||||
defaultDropDownMenuItemTextStyle)),
|
trailing: Container(
|
||||||
);
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
}).toList()))),
|
child: Slider(
|
||||||
ListTile(
|
onChanged: (double value) {
|
||||||
title: Text(
|
settings.fontScaling = value;
|
||||||
AppLocalizations.of(context)!
|
|
||||||
.settingUIColumnLandscape,
|
|
||||||
textWidthBasis: TextWidthBasis.longestLine,
|
|
||||||
softWrap: true,
|
|
||||||
),
|
|
||||||
leading: Icon(Icons.stay_primary_landscape,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
trailing: Container(
|
|
||||||
width: MediaQuery
|
|
||||||
.of(context)
|
|
||||||
.size
|
|
||||||
.width / 4,
|
|
||||||
child: Container(
|
|
||||||
width:
|
|
||||||
MediaQuery
|
|
||||||
.of(context)
|
|
||||||
.size
|
|
||||||
.width / 4,
|
|
||||||
child: DropdownButton(
|
|
||||||
isExpanded: true,
|
|
||||||
value: settings.uiColumnModeLandscape
|
|
||||||
.toString(),
|
|
||||||
onChanged: (String? newValue) {
|
|
||||||
settings.uiColumnModeLandscape =
|
|
||||||
Settings.uiColumnModeFromString(
|
|
||||||
newValue!);
|
|
||||||
saveSettings(context);
|
|
||||||
},
|
|
||||||
items:
|
|
||||||
Settings.uiColumnModeOptions(true)
|
|
||||||
.map<DropdownMenuItem<String>>(
|
|
||||||
(DualpaneMode value) {
|
|
||||||
return DropdownMenuItem<String>(
|
|
||||||
value: value.toString(),
|
|
||||||
child: Text(
|
|
||||||
Settings.uiColumnModeToString(
|
|
||||||
value, context),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: settings.scaleFonts(
|
|
||||||
defaultDropDownMenuItemTextStyle)),
|
|
||||||
);
|
|
||||||
}).toList())))),
|
|
||||||
ListTile(
|
|
||||||
title: Text(
|
|
||||||
AppLocalizations.of(context)!.defaultScalingText),
|
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.fontScalingDescription),
|
|
||||||
trailing: Container(
|
|
||||||
width: MediaQuery
|
|
||||||
.of(context)
|
|
||||||
.size
|
|
||||||
.width / 4,
|
|
||||||
child: Slider(
|
|
||||||
onChanged: (double value) {
|
|
||||||
settings.fontScaling = value;
|
|
||||||
// Save Settings...
|
// Save Settings...
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
EnvironmentConfig.debugLog(
|
EnvironmentConfig.debugLog("Font Scaling: $value");
|
||||||
"Font Scaling: $value");
|
},
|
||||||
},
|
min: 0.5,
|
||||||
min: 0.5,
|
divisions: 12,
|
||||||
divisions: 12,
|
max: 2.0,
|
||||||
max: 2.0,
|
label: '${settings.fontScaling * 100}%',
|
||||||
label: '${settings.fontScaling * 100}%',
|
activeColor: settings.current().defaultButtonColor,
|
||||||
activeColor:
|
thumbColor: settings.current().mainTextColor,
|
||||||
settings
|
overlayColor: MaterialStateProperty.all(settings.current().mainTextColor),
|
||||||
.current()
|
inactiveColor: settings.theme.defaultButtonDisabledColor,
|
||||||
.defaultButtonColor,
|
value: settings.fontScaling)),
|
||||||
thumbColor: settings
|
leading: Icon(Icons.format_size, color: settings.current().mainTextColor),
|
||||||
.current()
|
),
|
||||||
.mainTextColor,
|
SwitchListTile(
|
||||||
overlayColor: MaterialStateProperty.all(
|
title: Text(AppLocalizations.of(context)!.streamerModeLabel),
|
||||||
settings
|
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||||
.current()
|
value: settings.streamerMode,
|
||||||
.mainTextColor),
|
onChanged: (bool value) {
|
||||||
inactiveColor:
|
settings.setStreamerMode(value);
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
value: settings.fontScaling)),
|
|
||||||
leading: Icon(Icons.format_size,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
|
||||||
SwitchListTile(
|
|
||||||
title: Text(
|
|
||||||
AppLocalizations.of(context)!.streamerModeLabel),
|
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.descriptionStreamerMode),
|
|
||||||
value: settings.streamerMode,
|
|
||||||
onChanged: (bool value) {
|
|
||||||
settings.setStreamerMode(value);
|
|
||||||
// Save Settings...
|
// Save Settings...
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
activeTrackColor: settings.theme.defaultButtonColor,
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
inactiveTrackColor:
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
settings.theme.defaultButtonDisabledColor,
|
secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor),
|
||||||
secondary: Icon(CwtchIcons.streamer_bunnymask,
|
),
|
||||||
color: settings
|
SwitchListTile(
|
||||||
.current()
|
title: Text(AppLocalizations.of(context)!.formattingExperiment),
|
||||||
.mainTextColor),
|
subtitle: Text(AppLocalizations.of(context)!.messageFormattingDescription),
|
||||||
),
|
value: settings.isExperimentEnabled(FormattingExperiment),
|
||||||
SwitchListTile(
|
onChanged: (bool value) {
|
||||||
title: Text(AppLocalizations.of(context)!
|
if (value) {
|
||||||
.formattingExperiment),
|
settings.enableExperiment(FormattingExperiment);
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
} else {
|
||||||
.messageFormattingDescription),
|
settings.disableExperiment(FormattingExperiment);
|
||||||
value: settings
|
}
|
||||||
.isExperimentEnabled(FormattingExperiment),
|
saveSettings(context);
|
||||||
onChanged: (bool value) {
|
},
|
||||||
if (value) {
|
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||||
settings.enableExperiment(FormattingExperiment);
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
} else {
|
secondary: Icon(Icons.text_fields, color: settings.current().mainTextColor),
|
||||||
settings.disableExperiment(FormattingExperiment);
|
),
|
||||||
}
|
]))));
|
||||||
saveSettings(context);
|
});
|
||||||
},
|
|
||||||
activeTrackColor:
|
|
||||||
settings.theme.defaultButtonActiveColor,
|
|
||||||
inactiveTrackColor:
|
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(Icons.text_fields,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
|
||||||
]))));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
static const androidSettingsChannel = const MethodChannel('androidSettings');
|
static const androidSettingsChannel = const MethodChannel('androidSettings');
|
||||||
static const androidSettingsChangeChannel = const MethodChannel('androidSettingsChanged');
|
static const androidSettingsChangeChannel = const MethodChannel('androidSettingsChanged');
|
||||||
|
|
||||||
|
|
||||||
ScrollController settingsListScrollController = ScrollController();
|
ScrollController settingsListScrollController = ScrollController();
|
||||||
bool powerExempt = false;
|
bool powerExempt = false;
|
||||||
|
|
||||||
|
@ -31,8 +30,8 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
|
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
isBatteryExempt().then((value) => setState(() {
|
isBatteryExempt().then((value) => setState(() {
|
||||||
powerExempt = value;
|
powerExempt = value;
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
powerExempt = false;
|
powerExempt = false;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +50,7 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
//* Android Only Requests
|
//* Android Only Requests
|
||||||
|
|
||||||
Future<bool> isBatteryExempt() async {
|
Future<bool> isBatteryExempt() async {
|
||||||
return await androidSettingsChannel.invokeMethod('isBatteryExempt', {}) ??
|
return await androidSettingsChannel.invokeMethod('isBatteryExempt', {}) ?? false;
|
||||||
false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> requestBatteryExemption() async {
|
Future<void> requestBatteryExemption() async {
|
||||||
|
@ -62,11 +60,9 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
|
|
||||||
//* End Android Only Requests
|
//* End Android Only Requests
|
||||||
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
|
||||||
return Scrollbar(
|
return Scrollbar(
|
||||||
key: Key("BehaviourSettingsView"),
|
key: Key("BehaviourSettingsView"),
|
||||||
trackVisibility: true,
|
trackVisibility: true,
|
||||||
|
@ -83,10 +79,8 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: Platform.isAndroid,
|
visible: Platform.isAndroid,
|
||||||
child: SwitchListTile(
|
child: SwitchListTile(
|
||||||
title: Text(AppLocalizations.of(context)!
|
title: Text(AppLocalizations.of(context)!.settingAndroidPowerExemption),
|
||||||
.settingAndroidPowerExemption),
|
subtitle: Text(AppLocalizations.of(context)!.settingAndroidPowerExemptionDescription),
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.settingAndroidPowerExemptionDescription),
|
|
||||||
value: powerExempt,
|
value: powerExempt,
|
||||||
onChanged: (bool value) {
|
onChanged: (bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
@ -97,17 +91,13 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
activeTrackColor: settings.theme.defaultButtonColor,
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
inactiveTrackColor:
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
settings.theme.defaultButtonDisabledColor,
|
secondary: Icon(Icons.power, color: settings.current().mainTextColor),
|
||||||
secondary: Icon(Icons.power,
|
|
||||||
color: settings.current().mainTextColor),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(AppLocalizations.of(context)!
|
title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel),
|
||||||
.notificationPolicySettingLabel),
|
subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription),
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.notificationPolicySettingDescription),
|
|
||||||
trailing: Container(
|
trailing: Container(
|
||||||
width: MediaQuery.of(context).size.width / 4,
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
|
@ -117,27 +107,17 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
settings.notificationPolicy = newValue!;
|
settings.notificationPolicy = newValue!;
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
items: NotificationPolicy.values.map<
|
items: NotificationPolicy.values.map<DropdownMenuItem<NotificationPolicy>>((NotificationPolicy value) {
|
||||||
DropdownMenuItem<NotificationPolicy>>(
|
return DropdownMenuItem<NotificationPolicy>(
|
||||||
(NotificationPolicy value) {
|
value: value,
|
||||||
return DropdownMenuItem<NotificationPolicy>(
|
child: Text(Settings.notificationPolicyToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||||
value: value,
|
);
|
||||||
child: Text(
|
}).toList())),
|
||||||
Settings.notificationPolicyToString(
|
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||||
value, context),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: settings.scaleFonts(
|
|
||||||
defaultDropDownMenuItemTextStyle)),
|
|
||||||
);
|
|
||||||
}).toList())),
|
|
||||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px,
|
|
||||||
color: settings.current().mainTextColor),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(AppLocalizations.of(context)!
|
title: Text(AppLocalizations.of(context)!.notificationContentSettingLabel),
|
||||||
.notificationContentSettingLabel),
|
subtitle: Text(AppLocalizations.of(context)!.notificationContentSettingDescription),
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.notificationContentSettingDescription),
|
|
||||||
trailing: Container(
|
trailing: Container(
|
||||||
width: MediaQuery.of(context).size.width / 4,
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
|
@ -147,29 +127,17 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
settings.notificationContent = newValue!;
|
settings.notificationContent = newValue!;
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
items: NotificationContent.values.map<
|
items: NotificationContent.values.map<DropdownMenuItem<NotificationContent>>((NotificationContent value) {
|
||||||
DropdownMenuItem<
|
return DropdownMenuItem<NotificationContent>(
|
||||||
NotificationContent>>(
|
value: value,
|
||||||
(NotificationContent value) {
|
child: Text(Settings.notificationContentToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||||
return DropdownMenuItem<
|
);
|
||||||
NotificationContent>(
|
}).toList())),
|
||||||
value: value,
|
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||||
child: Text(
|
|
||||||
Settings.notificationContentToString(
|
|
||||||
value, context),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: settings.scaleFonts(
|
|
||||||
defaultDropDownMenuItemTextStyle)),
|
|
||||||
);
|
|
||||||
}).toList())),
|
|
||||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px,
|
|
||||||
color: settings.current().mainTextColor),
|
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text(
|
title: Text(AppLocalizations.of(context)!.blockUnknownLabel),
|
||||||
AppLocalizations.of(context)!.blockUnknownLabel),
|
subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.descriptionBlockUnknownConnections),
|
|
||||||
value: settings.blockUnknownConnections,
|
value: settings.blockUnknownConnections,
|
||||||
onChanged: (bool value) {
|
onChanged: (bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
@ -182,16 +150,12 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
activeTrackColor: settings.theme.defaultButtonColor,
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
inactiveTrackColor:
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
settings.theme.defaultButtonDisabledColor,
|
secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor),
|
||||||
secondary: Icon(CwtchIcons.block_unknown,
|
|
||||||
color: settings.current().mainTextColor),
|
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text(AppLocalizations.of(context)!
|
title: Text(AppLocalizations.of(context)!.defaultPreserveHistorySetting),
|
||||||
.defaultPreserveHistorySetting),
|
subtitle: Text(AppLocalizations.of(context)!.preserveHistorySettingDescription),
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.preserveHistorySettingDescription),
|
|
||||||
value: settings.preserveHistoryByDefault,
|
value: settings.preserveHistoryByDefault,
|
||||||
onChanged: (bool value) {
|
onChanged: (bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
@ -204,13 +168,11 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
activeTrackColor: settings.theme.defaultButtonColor,
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
inactiveTrackColor:
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
settings.theme.defaultButtonDisabledColor,
|
secondary: Icon(CwtchIcons.peer_history, color: settings.current().mainTextColor),
|
||||||
secondary: Icon(CwtchIcons.peer_history,
|
|
||||||
color: settings.current().mainTextColor),
|
|
||||||
),
|
),
|
||||||
]))));
|
]))));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,8 +186,7 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
|
|
||||||
// set up the AlertDialog
|
// set up the AlertDialog
|
||||||
AlertDialog alert = AlertDialog(
|
AlertDialog alert = AlertDialog(
|
||||||
title:
|
title: Text(AppLocalizations.of(context)!.settingsAndroidPowerReenablePopup),
|
||||||
Text(AppLocalizations.of(context)!.settingsAndroidPowerReenablePopup),
|
|
||||||
actions: [
|
actions: [
|
||||||
okButton,
|
okButton,
|
||||||
],
|
],
|
||||||
|
@ -239,4 +200,4 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,358 +19,224 @@ class GlobalSettingsExperimentsView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GlobalSettingsExperimentsViewState extends State<GlobalSettingsExperimentsView> {
|
class _GlobalSettingsExperimentsViewState extends State<GlobalSettingsExperimentsView> {
|
||||||
|
|
||||||
ScrollController settingsListScrollController = ScrollController();
|
ScrollController settingsListScrollController = ScrollController();
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
return Scrollbar(
|
||||||
return Scrollbar(
|
key: Key("ExperimentsSettingsView"),
|
||||||
key: Key("ExperimentsSettingsView"),
|
trackVisibility: true,
|
||||||
trackVisibility: true,
|
controller: settingsListScrollController,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
controller: settingsListScrollController,
|
controller: settingsListScrollController,
|
||||||
child: SingleChildScrollView(
|
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||||
clipBehavior: Clip.antiAlias,
|
child: ConstrainedBox(
|
||||||
controller: settingsListScrollController,
|
constraints: BoxConstraints(
|
||||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
minHeight: viewportConstraints.maxHeight,
|
||||||
child: ConstrainedBox(
|
),
|
||||||
constraints: BoxConstraints(
|
child: Column(children: [
|
||||||
minHeight: viewportConstraints.maxHeight,
|
SwitchListTile(
|
||||||
),
|
title: Text(AppLocalizations.of(context)!.experimentsEnabled),
|
||||||
child: Column(children: [
|
subtitle: Text(AppLocalizations.of(context)!.descriptionExperiments),
|
||||||
SwitchListTile(
|
value: settings.experimentsEnabled,
|
||||||
title: Text(
|
onChanged: (bool value) {
|
||||||
AppLocalizations.of(context)!.experimentsEnabled),
|
if (value) {
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
settings.enableExperiments();
|
||||||
.descriptionExperiments),
|
} else {
|
||||||
value: settings.experimentsEnabled,
|
settings.disableExperiments();
|
||||||
onChanged: (bool value) {
|
}
|
||||||
if (value) {
|
// Save Settings...
|
||||||
settings.enableExperiments();
|
saveSettings(context);
|
||||||
} else {
|
},
|
||||||
settings.disableExperiments();
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
}
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
// Save Settings...
|
secondary: Icon(CwtchIcons.enable_experiments, color: settings.current().mainTextColor),
|
||||||
saveSettings(context);
|
),
|
||||||
},
|
Visibility(
|
||||||
activeTrackColor: settings.theme.defaultButtonColor,
|
visible: settings.experimentsEnabled,
|
||||||
inactiveTrackColor:
|
child: Column(
|
||||||
settings.theme.defaultButtonDisabledColor,
|
children: [
|
||||||
secondary: Icon(CwtchIcons.enable_experiments,
|
SwitchListTile(
|
||||||
color: settings
|
title: Text(AppLocalizations.of(context)!.enableGroups),
|
||||||
.current()
|
subtitle: Text(AppLocalizations.of(context)!.descriptionExperimentsGroups),
|
||||||
.mainTextColor),
|
value: settings.isExperimentEnabled(TapirGroupsExperiment),
|
||||||
),
|
onChanged: (bool value) {
|
||||||
Visibility(
|
if (value) {
|
||||||
visible: settings.experimentsEnabled,
|
settings.enableExperiment(TapirGroupsExperiment);
|
||||||
child: Column(
|
} else {
|
||||||
children: [
|
settings.disableExperiment(TapirGroupsExperiment);
|
||||||
SwitchListTile(
|
}
|
||||||
title: Text(AppLocalizations.of(context)!
|
// Save Settings...
|
||||||
.enableGroups),
|
saveSettings(context);
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
},
|
||||||
.descriptionExperimentsGroups),
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
value: settings.isExperimentEnabled(
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
TapirGroupsExperiment),
|
secondary: Icon(CwtchIcons.enable_groups, color: settings.current().mainTextColor),
|
||||||
onChanged: (bool value) {
|
),
|
||||||
if (value) {
|
Visibility(
|
||||||
settings.enableExperiment(
|
visible: !Platform.isAndroid && !Platform.isIOS,
|
||||||
TapirGroupsExperiment);
|
child: SwitchListTile(
|
||||||
} else {
|
title: Text(AppLocalizations.of(context)!.settingServers),
|
||||||
settings.disableExperiment(
|
subtitle: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled()
|
||||||
TapirGroupsExperiment);
|
? Text(AppLocalizations.of(context)!.settingServersDescription)
|
||||||
}
|
: Text("This version of Cwtch has been compiled without support for the server hosting experiment."),
|
||||||
// Save Settings...
|
value: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled() && settings.isExperimentEnabled(ServerManagementExperiment),
|
||||||
saveSettings(context);
|
onChanged: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled()
|
||||||
},
|
|
||||||
activeTrackColor:
|
|
||||||
settings.theme.defaultButtonColor,
|
|
||||||
inactiveTrackColor:
|
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(CwtchIcons.enable_groups,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible:
|
|
||||||
!Platform.isAndroid && !Platform.isIOS,
|
|
||||||
child: SwitchListTile(
|
|
||||||
title: Text(AppLocalizations.of(context)!
|
|
||||||
.settingServers),
|
|
||||||
subtitle: Provider
|
|
||||||
.of<FlwtchState>(
|
|
||||||
context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsServersCompiled()
|
|
||||||
? Text(AppLocalizations.of(context)!
|
|
||||||
.settingServersDescription)
|
|
||||||
: Text(
|
|
||||||
"This version of Cwtch has been compiled without support for the server hosting experiment."),
|
|
||||||
value: Provider
|
|
||||||
.of<FlwtchState>(context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsServersCompiled() &&
|
|
||||||
settings.isExperimentEnabled(
|
|
||||||
ServerManagementExperiment),
|
|
||||||
onChanged: Provider
|
|
||||||
.of<FlwtchState>(
|
|
||||||
context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsServersCompiled()
|
|
||||||
? (bool value) {
|
|
||||||
Provider.of<ServerListState>(
|
|
||||||
context,
|
|
||||||
listen: false)
|
|
||||||
.clear();
|
|
||||||
if (value) {
|
|
||||||
settings.enableExperiment(
|
|
||||||
ServerManagementExperiment);
|
|
||||||
} else {
|
|
||||||
settings.disableExperiment(
|
|
||||||
ServerManagementExperiment);
|
|
||||||
}
|
|
||||||
// Save Settings...
|
|
||||||
saveSettings(context);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
activeTrackColor:
|
|
||||||
settings.theme.defaultButtonColor,
|
|
||||||
inactiveTrackColor: settings
|
|
||||||
.theme.defaultButtonDisabledColor,
|
|
||||||
inactiveThumbColor: settings
|
|
||||||
.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(CwtchIcons.dns_24px),
|
|
||||||
)),
|
|
||||||
SwitchListTile(
|
|
||||||
title: Text(AppLocalizations.of(context)!
|
|
||||||
.settingFileSharing),
|
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
|
||||||
.descriptionFileSharing),
|
|
||||||
value: settings.isExperimentEnabled(
|
|
||||||
FileSharingExperiment),
|
|
||||||
onChanged: (bool value) {
|
|
||||||
if (value) {
|
|
||||||
if (checkDownloadDirectory(
|
|
||||||
context, settings)) {
|
|
||||||
settings.enableExperiment(
|
|
||||||
FileSharingExperiment);
|
|
||||||
} else {
|
|
||||||
settings.enableExperiment(
|
|
||||||
FileSharingExperiment);
|
|
||||||
settings.disableExperiment(
|
|
||||||
ImagePreviewsExperiment);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
settings.disableExperiment(
|
|
||||||
FileSharingExperiment);
|
|
||||||
settings.disableExperiment(
|
|
||||||
ImagePreviewsExperiment);
|
|
||||||
}
|
|
||||||
saveSettings(context);
|
|
||||||
},
|
|
||||||
activeTrackColor:
|
|
||||||
settings.theme.defaultButtonColor,
|
|
||||||
inactiveTrackColor:
|
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(CwtchIcons.attached_file_3,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: settings.isExperimentEnabled(
|
|
||||||
FileSharingExperiment),
|
|
||||||
child: Column(children: [
|
|
||||||
SwitchListTile(
|
|
||||||
title: Text(AppLocalizations.of(context)!
|
|
||||||
.settingImagePreviews),
|
|
||||||
subtitle: Text(
|
|
||||||
AppLocalizations.of(context)!
|
|
||||||
.settingImagePreviewsDescription),
|
|
||||||
value: settings.isExperimentEnabled(
|
|
||||||
ImagePreviewsExperiment),
|
|
||||||
onChanged: (bool value) {
|
|
||||||
if (value) {
|
|
||||||
if (checkDownloadDirectory(
|
|
||||||
context, settings)) {
|
|
||||||
settings.enableExperiment(
|
|
||||||
ImagePreviewsExperiment);
|
|
||||||
} else {
|
|
||||||
settings.disableExperiment(
|
|
||||||
ImagePreviewsExperiment);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
settings.disableExperiment(
|
|
||||||
ImagePreviewsExperiment);
|
|
||||||
}
|
|
||||||
saveSettings(context);
|
|
||||||
},
|
|
||||||
activeTrackColor: settings
|
|
||||||
.theme.defaultButtonActiveColor,
|
|
||||||
inactiveTrackColor: settings
|
|
||||||
.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(Icons.photo,
|
|
||||||
color:
|
|
||||||
settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: settings.isExperimentEnabled(
|
|
||||||
ImagePreviewsExperiment) &&
|
|
||||||
!Platform.isAndroid,
|
|
||||||
child: CwtchFolderPicker(
|
|
||||||
testKey: Key("DownloadFolderPicker"),
|
|
||||||
label: AppLocalizations.of(context)!
|
|
||||||
.settingDownloadFolder,
|
|
||||||
initialValue: settings.downloadPath,
|
|
||||||
textStyle: settings.scaleFonts(
|
|
||||||
defaultDropDownMenuItemTextStyle),
|
|
||||||
description: AppLocalizations.of(
|
|
||||||
context)!
|
|
||||||
.fileSharingSettingsDownloadFolderDescription,
|
|
||||||
tooltip: AppLocalizations.of(context)!
|
|
||||||
.fileSharingSettingsDownloadFolderTooltip,
|
|
||||||
onSave: (newVal) {
|
|
||||||
settings.downloadPath = newVal;
|
|
||||||
saveSettings(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
SwitchListTile(
|
|
||||||
title: Text(AppLocalizations.of(context)!
|
|
||||||
.blodeuweddExperimentEnable),
|
|
||||||
subtitle: Provider
|
|
||||||
.of<FlwtchState>(context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsBlodeuweddSupported()
|
|
||||||
? Text(AppLocalizations.of(context)!
|
|
||||||
.blodeuweddDescription)
|
|
||||||
: Text(AppLocalizations.of(context)!
|
|
||||||
.blodeuweddNotSupported),
|
|
||||||
value: Provider
|
|
||||||
.of<FlwtchState>(context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsBlodeuweddSupported() &&
|
|
||||||
settings.isExperimentEnabled(
|
|
||||||
BlodeuweddExperiment),
|
|
||||||
onChanged: Provider
|
|
||||||
.of<FlwtchState>(context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsBlodeuweddSupported()
|
|
||||||
? (bool value) {
|
? (bool value) {
|
||||||
|
Provider.of<ServerListState>(context, listen: false).clear();
|
||||||
|
if (value) {
|
||||||
|
settings.enableExperiment(ServerManagementExperiment);
|
||||||
|
} else {
|
||||||
|
settings.disableExperiment(ServerManagementExperiment);
|
||||||
|
}
|
||||||
|
// Save Settings...
|
||||||
|
saveSettings(context);
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
|
inactiveThumbColor: settings.theme.defaultButtonDisabledColor,
|
||||||
|
secondary: Icon(CwtchIcons.dns_24px),
|
||||||
|
)),
|
||||||
|
SwitchListTile(
|
||||||
|
title: Text(AppLocalizations.of(context)!.settingFileSharing),
|
||||||
|
subtitle: Text(AppLocalizations.of(context)!.descriptionFileSharing),
|
||||||
|
value: settings.isExperimentEnabled(FileSharingExperiment),
|
||||||
|
onChanged: (bool value) {
|
||||||
|
if (value) {
|
||||||
|
if (checkDownloadDirectory(context, settings)) {
|
||||||
|
settings.enableExperiment(FileSharingExperiment);
|
||||||
|
} else {
|
||||||
|
settings.enableExperiment(FileSharingExperiment);
|
||||||
|
settings.disableExperiment(ImagePreviewsExperiment);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
settings.disableExperiment(FileSharingExperiment);
|
||||||
|
settings.disableExperiment(ImagePreviewsExperiment);
|
||||||
|
}
|
||||||
|
saveSettings(context);
|
||||||
|
},
|
||||||
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
|
secondary: Icon(CwtchIcons.attached_file_3, color: settings.current().mainTextColor),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: settings.isExperimentEnabled(FileSharingExperiment),
|
||||||
|
child: Column(children: [
|
||||||
|
SwitchListTile(
|
||||||
|
title: Text(AppLocalizations.of(context)!.settingImagePreviews),
|
||||||
|
subtitle: Text(AppLocalizations.of(context)!.settingImagePreviewsDescription),
|
||||||
|
value: settings.isExperimentEnabled(ImagePreviewsExperiment),
|
||||||
|
onChanged: (bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
settings.enableExperiment(
|
if (checkDownloadDirectory(context, settings)) {
|
||||||
BlodeuweddExperiment);
|
settings.enableExperiment(ImagePreviewsExperiment);
|
||||||
|
} else {
|
||||||
|
settings.disableExperiment(ImagePreviewsExperiment);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
settings.disableExperiment(
|
settings.disableExperiment(ImagePreviewsExperiment);
|
||||||
BlodeuweddExperiment);
|
|
||||||
}
|
}
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
}
|
},
|
||||||
: null,
|
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||||
activeTrackColor:
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
settings.theme.defaultButtonColor,
|
secondary: Icon(Icons.photo, color: settings.current().mainTextColor),
|
||||||
inactiveTrackColor:
|
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
inactiveThumbColor:
|
|
||||||
settings.theme.defaultButtonDisabledColor,
|
|
||||||
secondary: Icon(Icons.assistant,
|
|
||||||
color: settings
|
|
||||||
.current()
|
|
||||||
.mainTextColor),
|
|
||||||
),
|
),
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: Provider
|
visible: settings.isExperimentEnabled(ImagePreviewsExperiment) && !Platform.isAndroid,
|
||||||
.of<FlwtchState>(context,
|
|
||||||
listen: false)
|
|
||||||
.cwtch
|
|
||||||
.IsBlodeuweddSupported() &&
|
|
||||||
settings.isExperimentEnabled(
|
|
||||||
BlodeuweddExperiment),
|
|
||||||
child: CwtchFolderPicker(
|
child: CwtchFolderPicker(
|
||||||
testKey: Key("DownloadFolderPicker"),
|
testKey: Key("DownloadFolderPicker"),
|
||||||
label: AppLocalizations.of(context)!
|
label: AppLocalizations.of(context)!.settingDownloadFolder,
|
||||||
.settingDownloadFolder,
|
initialValue: settings.downloadPath,
|
||||||
initialValue: settings.blodeuweddPath,
|
textStyle: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
|
||||||
description: AppLocalizations.of(context)!
|
description: AppLocalizations.of(context)!.fileSharingSettingsDownloadFolderDescription,
|
||||||
.blodeuweddPath,
|
tooltip: AppLocalizations.of(context)!.fileSharingSettingsDownloadFolderTooltip,
|
||||||
tooltip: AppLocalizations.of(context)!
|
|
||||||
.blodeuweddPath,
|
|
||||||
onSave: (newVal) {
|
onSave: (newVal) {
|
||||||
settings.blodeuweddPath = newVal;
|
settings.downloadPath = newVal;
|
||||||
saveSettings(context);
|
saveSettings(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
]),
|
||||||
)),
|
),
|
||||||
Visibility(
|
SwitchListTile(
|
||||||
visible: settings.experimentsEnabled,
|
title: Text(AppLocalizations.of(context)!.blodeuweddExperimentEnable),
|
||||||
child: SwitchListTile(
|
subtitle: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported()
|
||||||
title: Text(AppLocalizations.of(context)!
|
? Text(AppLocalizations.of(context)!.blodeuweddDescription)
|
||||||
.enableExperimentClickableLinks),
|
: Text(AppLocalizations.of(context)!.blodeuweddNotSupported),
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
value: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment),
|
||||||
.experimentClickableLinksDescription),
|
onChanged: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported()
|
||||||
value: settings.isExperimentEnabled(
|
? (bool value) {
|
||||||
ClickableLinksExperiment),
|
if (value) {
|
||||||
onChanged: (bool value) {
|
settings.enableExperiment(BlodeuweddExperiment);
|
||||||
if (value) {
|
} else {
|
||||||
settings.enableExperiment(
|
settings.disableExperiment(BlodeuweddExperiment);
|
||||||
ClickableLinksExperiment);
|
}
|
||||||
} else {
|
saveSettings(context);
|
||||||
settings.disableExperiment(
|
}
|
||||||
ClickableLinksExperiment);
|
: null,
|
||||||
}
|
activeTrackColor: settings.theme.defaultButtonColor,
|
||||||
saveSettings(context);
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
},
|
inactiveThumbColor: settings.theme.defaultButtonDisabledColor,
|
||||||
activeTrackColor:
|
secondary: Icon(Icons.assistant, color: settings.current().mainTextColor),
|
||||||
settings.theme.defaultButtonActiveColor,
|
),
|
||||||
inactiveTrackColor:
|
Visibility(
|
||||||
settings.theme.defaultButtonDisabledColor,
|
visible: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment),
|
||||||
secondary: Icon(Icons.link,
|
child: CwtchFolderPicker(
|
||||||
color: settings
|
testKey: Key("DownloadFolderPicker"),
|
||||||
.current()
|
label: AppLocalizations.of(context)!.settingDownloadFolder,
|
||||||
.mainTextColor),
|
initialValue: settings.blodeuweddPath,
|
||||||
)),
|
description: AppLocalizations.of(context)!.blodeuweddPath,
|
||||||
Visibility(
|
tooltip: AppLocalizations.of(context)!.blodeuweddPath,
|
||||||
visible: settings.experimentsEnabled,
|
onSave: (newVal) {
|
||||||
child: SwitchListTile(
|
settings.blodeuweddPath = newVal;
|
||||||
title: Text(AppLocalizations.of(context)!
|
saveSettings(context);
|
||||||
.enableExperimentQRCode),
|
},
|
||||||
subtitle: Text(AppLocalizations.of(context)!
|
),
|
||||||
.experimentQRCodeDescription),
|
),
|
||||||
value: settings
|
],
|
||||||
.isExperimentEnabled(QRCodeExperiment),
|
)),
|
||||||
onChanged: (bool value) {
|
Visibility(
|
||||||
if (value) {
|
visible: settings.experimentsEnabled,
|
||||||
settings.enableExperiment(QRCodeExperiment);
|
child: SwitchListTile(
|
||||||
} else {
|
title: Text(AppLocalizations.of(context)!.enableExperimentClickableLinks),
|
||||||
settings.disableExperiment(QRCodeExperiment);
|
subtitle: Text(AppLocalizations.of(context)!.experimentClickableLinksDescription),
|
||||||
}
|
value: settings.isExperimentEnabled(ClickableLinksExperiment),
|
||||||
saveSettings(context);
|
onChanged: (bool value) {
|
||||||
},
|
if (value) {
|
||||||
activeTrackColor:
|
settings.enableExperiment(ClickableLinksExperiment);
|
||||||
settings.theme.defaultButtonActiveColor,
|
} else {
|
||||||
inactiveTrackColor:
|
settings.disableExperiment(ClickableLinksExperiment);
|
||||||
settings.theme.defaultButtonDisabledColor,
|
}
|
||||||
secondary: Icon(Icons.qr_code,
|
saveSettings(context);
|
||||||
color: settings
|
},
|
||||||
.current()
|
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||||
.mainTextColor),
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
)),
|
secondary: Icon(Icons.link, color: settings.current().mainTextColor),
|
||||||
]))));
|
)),
|
||||||
});
|
Visibility(
|
||||||
|
visible: settings.experimentsEnabled,
|
||||||
|
child: SwitchListTile(
|
||||||
|
title: Text(AppLocalizations.of(context)!.enableExperimentQRCode),
|
||||||
|
subtitle: Text(AppLocalizations.of(context)!.experimentQRCodeDescription),
|
||||||
|
value: settings.isExperimentEnabled(QRCodeExperiment),
|
||||||
|
onChanged: (bool value) {
|
||||||
|
if (value) {
|
||||||
|
settings.enableExperiment(QRCodeExperiment);
|
||||||
|
} else {
|
||||||
|
settings.disableExperiment(QRCodeExperiment);
|
||||||
|
}
|
||||||
|
saveSettings(context);
|
||||||
|
},
|
||||||
|
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||||
|
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||||
|
secondary: Icon(Icons.qr_code, color: settings.current().mainTextColor),
|
||||||
|
)),
|
||||||
|
]))));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,9 +245,7 @@ class _GlobalSettingsExperimentsViewState extends State<GlobalSettingsExperiment
|
||||||
if (settings.downloadPath != "") {
|
if (settings.downloadPath != "") {
|
||||||
} else {
|
} else {
|
||||||
// check if the default download path exists
|
// check if the default download path exists
|
||||||
var path = Provider.of<FlwtchState>(context, listen: false)
|
var path = Provider.of<FlwtchState>(context, listen: false).cwtch.defaultDownloadPath();
|
||||||
.cwtch
|
|
||||||
.defaultDownloadPath();
|
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
settings.downloadPath = path;
|
settings.downloadPath = path;
|
||||||
} else {
|
} else {
|
||||||
|
@ -393,11 +257,10 @@ class _GlobalSettingsExperimentsViewState extends State<GlobalSettingsExperiment
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
final snackBar = SnackBar(
|
final snackBar = SnackBar(
|
||||||
content: Text(
|
content: Text(AppLocalizations.of(context)!.errorDownloadDirectoryDoesNotExist),
|
||||||
AppLocalizations.of(context)!.errorDownloadDirectoryDoesNotExist),
|
|
||||||
);
|
);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ class GlobalSettingsView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
||||||
|
|
||||||
ScrollController settingsListScrollController = ScrollController();
|
ScrollController settingsListScrollController = ScrollController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -35,7 +34,6 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultTabController(
|
return DefaultTabController(
|
||||||
|
@ -46,23 +44,10 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
||||||
bottom: TabBar(
|
bottom: TabBar(
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(
|
Tab(key: Key("OpenSettingsAppearance"), icon: Icon(Icons.palette), text: AppLocalizations.of(context)!.settingsGroupAppearance),
|
||||||
key: Key("OpenSettingsAppearance"),
|
Tab(key: Key("OpenSettingsBehaviour"), icon: Icon(Icons.settings), text: AppLocalizations.of(context)!.settingGroupBehaviour),
|
||||||
icon: Icon(Icons.palette),
|
Tab(key: Key("OpenSettingsExperiments"), icon: Icon(CwtchIcons.enable_experiments), text: AppLocalizations.of(context)!.settingsGroupExperiments),
|
||||||
text: AppLocalizations.of(context)!
|
Tab(icon: Icon(Icons.info), text: AppLocalizations.of(context)!.settingsGroupAbout),
|
||||||
.settingsGroupAppearance),
|
|
||||||
Tab(
|
|
||||||
key: Key("OpenSettingsBehaviour"),
|
|
||||||
icon: Icon(Icons.settings),
|
|
||||||
text:
|
|
||||||
AppLocalizations.of(context)!.settingGroupBehaviour),
|
|
||||||
Tab(
|
|
||||||
key: Key("OpenSettingsExperiments"),
|
|
||||||
icon: Icon(CwtchIcons.enable_experiments),
|
|
||||||
text: AppLocalizations.of(context)!
|
|
||||||
.settingsGroupExperiments),
|
|
||||||
Tab(icon: Icon(Icons.info), text: AppLocalizations.of(context)!
|
|
||||||
.settingsGroupAbout),
|
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
body: _buildSettingsList(),
|
body: _buildSettingsList(),
|
||||||
|
@ -71,15 +56,11 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
||||||
|
|
||||||
Widget _buildSettingsList() {
|
Widget _buildSettingsList() {
|
||||||
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
return Consumer<Settings>(builder: (ccontext, settings, child) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
|
||||||
return TabBarView(children: [
|
return TabBarView(children: [
|
||||||
GlobalSettingsAppearanceView(),
|
GlobalSettingsAppearanceView(),
|
||||||
|
|
||||||
GlobalSettingsBehaviourView(),
|
GlobalSettingsBehaviourView(),
|
||||||
|
|
||||||
GlobalSettingsExperimentsView(),
|
GlobalSettingsExperimentsView(),
|
||||||
|
|
||||||
GlobalSettingsAboutView(),
|
GlobalSettingsAboutView(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -90,7 +71,5 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
||||||
/// Send an UpdateGlobalSettings to the Event Bus
|
/// Send an UpdateGlobalSettings to the Event Bus
|
||||||
saveSettings(context) {
|
saveSettings(context) {
|
||||||
var settings = Provider.of<Settings>(context, listen: false);
|
var settings = Provider.of<Settings>(context, listen: false);
|
||||||
Provider.of<FlwtchState>(context, listen: false)
|
Provider.of<FlwtchState>(context, listen: false).cwtch.UpdateSettings(jsonEncode(settings.asJson()));
|
||||||
.cwtch
|
|
||||||
.UpdateSettings(jsonEncode(settings.asJson()));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,12 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
ProfileInfoState profileInfoState = Provider.of<ProfileInfoState>(context, listen: false);
|
||||||
|
ContactInfoState contact = Provider.of<ContactInfoState>(context, listen: false);
|
||||||
|
Provider.of<FlwtchState>(context, listen: false).cwtch.GetConversationAccessControlList(profileInfoState.onion, contact.identifier).then((value) {
|
||||||
|
EnvironmentConfig.debugLog("acl: ${jsonEncode(value)}");
|
||||||
|
});
|
||||||
|
|
||||||
return Scrollbar(
|
return Scrollbar(
|
||||||
trackVisibility: true,
|
trackVisibility: true,
|
||||||
controller: peerSettingsScrollController,
|
controller: peerSettingsScrollController,
|
||||||
|
|
Loading…
Reference in New Issue