wip: dualpane wiring #213
|
@ -136,7 +136,7 @@ class MainActivity: FlutterActivity() {
|
|||
super.onResume()
|
||||
Log.i("MainActivity.kt", "onResume")
|
||||
if (myReceiver == null) {
|
||||
Log.i("MainActivity.kt", "onResume registering localbroadcastreceiver")
|
||||
Log.i("MainActivity.kt", "onResume registering local broadcast receiver / event bus forwarder")
|
||||
val mc = MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, CWTCH_EVENTBUS)
|
||||
val filter = IntentFilter("im.cwtch.flwtch.broadcast.SERVICE_EVENT_BUS")
|
||||
myReceiver = MyBroadcastReceiver(mc)
|
||||
|
@ -163,7 +163,7 @@ class MainActivity: FlutterActivity() {
|
|||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Log.i("MainActivity.kt", "onDestroy")
|
||||
Log.i("MainActivity.kt", "onDestroy - cancelling all WORKER_TAG and pruning old work")
|
||||
WorkManager.getInstance(this).cancelAllWorkByTag(WORKER_TAG)
|
||||
WorkManager.getInstance(this).pruneWork()
|
||||
}
|
||||
|
@ -188,6 +188,8 @@ class MainActivity: FlutterActivity() {
|
|||
val Data = this.optString("Data")
|
||||
}
|
||||
|
||||
// MainActivity.MyBroadcastReceiver receives events from the Cwtch service via im.cwtch.flwtch.broadcast.SERVICE_EVENT_BUS Android local broadcast intents
|
||||
// then it forwards them to the flutter ui engine using the CWTCH_EVENTBUS methodchannel
|
||||
class MyBroadcastReceiver(mc: MethodChannel) : BroadcastReceiver() {
|
||||
val eventBus: MethodChannel = mc
|
||||
|
||||
|
@ -198,5 +200,4 @@ class MainActivity: FlutterActivity() {
|
|||
eventBus.invokeMethod(evtType, evtData)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -97,7 +97,9 @@ class CwtchNotifier {
|
|||
break;
|
||||
case "NewMessageFromPeer":
|
||||
notificationManager.notify("New Message From Peer!");
|
||||
if (appState.selectedProfile != data["ProfileOnion"] || appState.selectedConversation != data["RemotePeer"]) {
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.unreadMessages++;
|
||||
}
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.totalMessages++;
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["RemotePeer"], DateTime.now());
|
||||
break;
|
||||
|
@ -122,7 +124,9 @@ class CwtchNotifier {
|
|||
case "NewMessageFromGroup":
|
||||
if (data["ProfileOnion"] != data["RemotePeer"]) {
|
||||
//not from me
|
||||
if (appState.selectedProfile != data["ProfileOnion"] || appState.selectedConversation != data["GroupID"]) {
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.unreadMessages++;
|
||||
}
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.totalMessages++;
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["GroupID"], DateTime.now());
|
||||
} else {
|
||||
|
|
|
@ -45,10 +45,6 @@ class Flwtch extends StatefulWidget {
|
|||
class FlwtchState extends State<Flwtch> {
|
||||
final TextStyle biggerFont = const TextStyle(fontSize: 18);
|
||||
late Cwtch cwtch;
|
||||
late ProfileInfoState selectedProfile;
|
||||
String selectedConversation = "";
|
||||
var columns = [1]; // default or 'single column' mode
|
||||
//var columns = [1, 1, 2];
|
||||
late ProfileListState profs;
|
||||
final MethodChannel notificationClickChannel = MethodChannel('im.cwtch.flwtch/notificationClickHandler');
|
||||
final MethodChannel shutdownMethodChannel = MethodChannel('im.cwtch.flwtch/shutdown');
|
||||
|
@ -108,7 +104,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
title: 'Cwtch',
|
||||
theme: mkThemeData(settings),
|
||||
home: appState.cwtchInit == true ? (columns.length == 3 ? TripleColumnView() : ShiftRightFixer(child: ProfileMgrView())) : SplashView(),
|
||||
home: appState.cwtchInit == true ? ShiftRightFixer(child: ProfileMgrView()) : SplashView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -128,11 +124,21 @@ class FlwtchState extends State<Flwtch> {
|
|||
});
|
||||
}
|
||||
|
||||
// Invoked via notificationClickChannel by MyBroadcastReceiver in MainActivity.kt
|
||||
// coder beware: args["RemotePeer"] is actually a handle, and could be eg a groupID
|
||||
Future<void> _externalNotificationClicked(MethodCall call) async {
|
||||
var args = jsonDecode(call.arguments);
|
||||
var profile = profs.getProfile(args["ProfileOnion"])!;
|
||||
var contact = profile.contactList.getContact(args["RemotePeer"])!;
|
||||
contact.unreadMessages = 0;
|
||||
|
||||
// single pane mode pushes; double pane mode reads AppState.selectedProfile/Conversation
|
||||
var isLandscape = Provider.of<AppState>(navKey.currentContext!, listen: false).isLandscape(navKey.currentContext!);
|
||||
if (Provider.of<Settings>(navKey.currentContext!, listen: false).uiColumns(isLandscape).length == 1) {
|
||||
if (navKey.currentContext?.findAncestorWidgetOfExactType<MessageView>() != null) {
|
||||
print("messageview already open; popping before pushing replacement");
|
||||
navKey.currentState?.pop();
|
||||
}
|
||||
navKey.currentState?.push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (BuildContext builderContext) {
|
||||
|
@ -146,6 +152,10 @@ class FlwtchState extends State<Flwtch> {
|
|||
},
|
||||
),
|
||||
);
|
||||
} else { //dual pane
|
||||
Provider.of<AppState>(navKey.currentContext!, listen: false).selectedProfile = args["ProfileOnion"];
|
||||
Provider.of<AppState>(navKey.currentContext!, listen: false).selectedConversation = args["RemotePeer"];
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'dart:typed_data';
|
|||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:glob/glob.dart';
|
||||
import 'package:glob/list_local_fs.dart';
|
||||
//import 'package:glob/list_local_fs.dart';
|
||||
|
||||
var globalSettings = Settings(Locale("en", ''), Opaque.dark);
|
||||
var globalErrorHandler = ErrorHandler();
|
||||
|
|
|
@ -64,6 +64,8 @@ class ProfileListState extends ChangeNotifier {
|
|||
class AppState extends ChangeNotifier {
|
||||
bool cwtchInit = false;
|
||||
String appError = "";
|
||||
String? _selectedProfile;
|
||||
String? _selectedConversation;
|
||||
|
||||
void SetCwtchInit() {
|
||||
cwtchInit = true;
|
||||
|
@ -74,6 +76,20 @@ class AppState extends ChangeNotifier {
|
|||
appError = error;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String? get selectedProfile => _selectedProfile;
|
||||
set selectedProfile(String? newVal) {
|
||||
this._selectedProfile = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String? get selectedConversation => _selectedConversation;
|
||||
set selectedConversation(String? newVal) {
|
||||
this._selectedConversation = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool isLandscape(BuildContext c) => MediaQuery.of(c).size.width > MediaQuery.of(c).size.height;
|
||||
}
|
||||
|
||||
class ContactListState extends ChangeNotifier {
|
||||
|
@ -491,6 +507,8 @@ class MessageState extends ChangeNotifier {
|
|||
}
|
||||
|
||||
set loaded(bool newVal) {
|
||||
// quickly-arriving messages get discarded before loading sometimes
|
||||
if (!hasListeners) return;
|
||||
this._loaded = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,13 @@ import 'opaque.dart';
|
|||
|
||||
const TapirGroupsExperiment = "tapir-groups-experiment";
|
||||
|
||||
enum DualpaneMode {
|
||||
Single,
|
||||
Dual1to2,
|
||||
Dual1to4,
|
||||
CopyPortrait,
|
||||
}
|
||||
|
||||
/// Settings govern the *Globally* relevant settings like Locale, Theme and Experiments.
|
||||
/// We also provide access to the version information here as it is also accessed from the
|
||||
/// Settings Pane.
|
||||
|
@ -19,6 +26,8 @@ class Settings extends ChangeNotifier {
|
|||
// explicitly set experiments to false until told otherwise...
|
||||
bool experimentsEnabled = false;
|
||||
HashMap<String, bool> experiments = HashMap.identity();
|
||||
DualpaneMode _uiColumnModePortrait = DualpaneMode.Single;
|
||||
DualpaneMode _uiColumnModeLandscape = DualpaneMode.CopyPortrait;
|
||||
|
||||
bool blockUnknownConnections = false;
|
||||
|
||||
|
@ -73,6 +82,10 @@ class Settings extends ChangeNotifier {
|
|||
// Set the internal experiments map. Casting from the Map<dynamic, dynamic> that we get from JSON
|
||||
experiments = new HashMap<String, bool>.from(settings["Experiments"]);
|
||||
|
||||
// single pane vs dual pane preferences
|
||||
_uiColumnModePortrait = uiColumnModeFromString(settings["UIColumnModePortrait"]);
|
||||
_uiColumnModeLandscape = uiColumnModeFromString(settings["UIColumnModeLandscape"]);
|
||||
|
||||
// Push the experimental settings to Consumers of Settings
|
||||
notifyListeners();
|
||||
}
|
||||
|
@ -134,6 +147,55 @@ class Settings extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
DualpaneMode get uiColumnModePortrait => _uiColumnModePortrait;
|
||||
set uiColumnModePortrait(DualpaneMode newval) {
|
||||
this._uiColumnModePortrait = newval;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
DualpaneMode get uiColumnModeLandscape => _uiColumnModeLandscape;
|
||||
set uiColumnModeLandscape(DualpaneMode newval) {
|
||||
this._uiColumnModeLandscape = newval;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<int> uiColumns(bool isLandscape) {
|
||||
var m = (!isLandscape || uiColumnModeLandscape == DualpaneMode.CopyPortrait) ? uiColumnModePortrait : uiColumnModeLandscape;
|
||||
switch(m) {
|
||||
case DualpaneMode.Single: return [1];
|
||||
case DualpaneMode.Dual1to2: return [1, 2];
|
||||
case DualpaneMode.Dual1to4: return [1, 4];
|
||||
}
|
||||
print("impossible column configuration: portrait/$uiColumnModePortrait landscape/$uiColumnModeLandscape");
|
||||
return [1];
|
||||
}
|
||||
|
||||
static List<DualpaneMode> uiColumnModeOptions(bool isLandscape) {
|
||||
if (isLandscape) return [DualpaneMode.CopyPortrait, DualpaneMode.Single, DualpaneMode.Dual1to2, DualpaneMode.Dual1to4,];
|
||||
else return [DualpaneMode.Single, DualpaneMode.Dual1to2, DualpaneMode.Dual1to4];
|
||||
}
|
||||
|
||||
static DualpaneMode uiColumnModeFromString(String m) {
|
||||
switch(m) {
|
||||
case "DualpaneMode.Single": return DualpaneMode.Single;
|
||||
case "DualpaneMode.Dual1to2": return DualpaneMode.Dual1to2;
|
||||
case "DualpaneMode.Dual1to4": return DualpaneMode.Dual1to4;
|
||||
case "DualpaneMode.CopyPortrait": return DualpaneMode.CopyPortrait;
|
||||
}
|
||||
print("Error: ui requested translation of column mode [$m] which doesn't exist");
|
||||
return DualpaneMode.Single;
|
||||
}
|
||||
|
||||
static String uiColumnModeToString(DualpaneMode m) {
|
||||
// todo: translate
|
||||
switch(m) {
|
||||
case DualpaneMode.Single: return "Single";
|
||||
case DualpaneMode.Dual1to2: return "Double (1:2)";
|
||||
case DualpaneMode.Dual1to4: return "Double (1:4)";
|
||||
case DualpaneMode.CopyPortrait: return "Same as portrait mode setting";
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a default settings object.
|
||||
Settings(this.locale, this.theme);
|
||||
|
||||
|
@ -153,7 +215,9 @@ class Settings extends ChangeNotifier {
|
|||
"ExperimentsEnabled": this.experimentsEnabled,
|
||||
"Experiments": experiments,
|
||||
"StateRootPane": 0,
|
||||
"FirstTime": false
|
||||
"FirstTime": false,
|
||||
"UIColumnModePortrait": uiColumnModePortrait.toString(),
|
||||
"UIColumnModeLandscape": uiColumnModeLandscape.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import '../model.dart';
|
||||
import '../settings.dart';
|
||||
import 'contactsview.dart';
|
||||
import 'messageview.dart';
|
||||
|
||||
|
@ -14,24 +15,25 @@ class DoubleColumnView extends StatefulWidget {
|
|||
class _DoubleColumnViewState extends State<DoubleColumnView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var flwtch = Provider.of<FlwtchState>(context);
|
||||
var flwtch = Provider.of<AppState>(context);
|
||||
var cols = Provider.of<Settings>(context).uiColumns(true);
|
||||
return Flex(
|
||||
direction: Axis.horizontal,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
flex: flwtch.columns[0],
|
||||
flex: cols[0],
|
||||
child: ContactsView(
|
||||
key: widget.key,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: flwtch.columns[1],
|
||||
child: flwtch.selectedConversation == ""
|
||||
? Center(child: Text(AppLocalizations.of(context)!.addContactFirst))
|
||||
flex: cols[1],
|
||||
child: flwtch.selectedConversation == null
|
||||
? Card(child:Center(child: Text(AppLocalizations.of(context)!.addContactFirst)))
|
||||
: //dev
|
||||
MultiProvider(providers: [
|
||||
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context)),
|
||||
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context).contactList.getContact(flwtch.selectedConversation)!),
|
||||
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context).contactList.getContact(flwtch.selectedConversation!)!),
|
||||
], child: Container(child: MessageView())),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -80,24 +80,33 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
secondary: Icon(CwtchIcons.change_theme, color: settings.current().mainTextColor()),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(/*AppLocalizations.of(context)!.settingLanguage*/ "UI Columns", style: TextStyle(color: settings.current().mainTextColor())),
|
||||
title: Text(/*AppLocalizations.of(context)!.settingLanguage*/ "UI Columns in Portrait Mode", style: TextStyle(color: settings.current().mainTextColor())),
|
||||
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor()),
|
||||
trailing: DropdownButton(
|
||||
value: "Single",
|
||||
value: settings.uiColumnModePortrait.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue == "Double (1:2)") {
|
||||
Provider.of<FlwtchState>(context).columns = [1, 2];
|
||||
} else if (newValue == "Double (1:4)") {
|
||||
Provider.of<FlwtchState>(context).columns = [1, 4];
|
||||
} else {
|
||||
Provider.of<FlwtchState>(context).columns = [1];
|
||||
}
|
||||
settings.uiColumnModePortrait = Settings.uiColumnModeFromString(newValue!);
|
||||
saveSettings(context);
|
||||
},
|
||||
// TODO: Only allow in landscape?
|
||||
items: (Platform.isAndroid ? ["Single"] : ["Single", "Double (1:2)", "Double (1:4)"]).map<DropdownMenuItem<String>>((String value) {
|
||||
items: Settings.uiColumnModeOptions(false).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
value: value.toString(),
|
||||
child: Text(Settings.uiColumnModeToString(value)),
|
||||
);
|
||||
}).toList())),
|
||||
ListTile(
|
||||
title: Text(/*AppLocalizations.of(context)!.settingLanguage*/ "UI Columns in Landscape Mode", style: TextStyle(color: settings.current().mainTextColor())),
|
||||
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor()),
|
||||
trailing: DropdownButton(
|
||||
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)),
|
||||
);
|
||||
}).toList())),
|
||||
SwitchListTile(
|
||||
|
|
|
@ -42,10 +42,13 @@ class _MessageViewState extends State<MessageView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var appState = Provider.of<AppState>(context);
|
||||
return WillPopScope(
|
||||
onWillPop: _onWillPop,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
// setting leading to null makes it do the default behaviour; container() hides it
|
||||
leading: Provider.of<Settings>(context).uiColumns(appState.isLandscape(context)).length > 1 ? Container() : null,
|
||||
title: Text(Provider.of<ContactInfoState>(context).nickname),
|
||||
actions: [
|
||||
//IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings),
|
||||
|
|
|
@ -42,7 +42,8 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
// Prevents Android back button from closing the app on the profile manager screen
|
||||
// (which would shutdown connections and all kinds of other expensive to generate things)
|
||||
// TODO pop up a dialogue regarding closing the app?
|
||||
builder: (context, settings, child) => WillPopScope(
|
||||
builder: (context, settings, child) =>
|
||||
WillPopScope(
|
||||
onWillPop: () async {
|
||||
_showShutdown();
|
||||
return closeApp;
|
||||
|
@ -58,7 +59,10 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
width: 32,
|
||||
height: 32,
|
||||
colorBlendMode: BlendMode.dstIn,
|
||||
color: Provider.of<Settings>(context).theme.backgroundHilightElementColor(),
|
||||
color: Provider
|
||||
.of<Settings>(context)
|
||||
.theme
|
||||
.backgroundHilightElementColor(),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
|
|
|
@ -3,9 +3,12 @@ import 'package:cwtch/views/profilemgrview.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import '../model.dart';
|
||||
import '../settings.dart';
|
||||
import 'contactsview.dart';
|
||||
import 'messageview.dart';
|
||||
|
||||
// currently unused but maybe one day?
|
||||
class TripleColumnView extends StatefulWidget {
|
||||
@override
|
||||
_TripleColumnViewState createState() => _TripleColumnViewState();
|
||||
|
@ -14,19 +17,22 @@ class TripleColumnView extends StatefulWidget {
|
|||
class _TripleColumnViewState extends State<TripleColumnView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var flwtch = Provider.of<FlwtchState>(context);
|
||||
var appState = Provider.of<AppState>(context);
|
||||
var settings = Provider.of<Settings>(context);
|
||||
var columns = settings.uiColumns(appState.isLandscape(context));
|
||||
|
||||
return Flex(direction: Axis.horizontal, children: <Widget>[
|
||||
Flexible(
|
||||
flex: flwtch.columns[0],
|
||||
flex: columns[0],
|
||||
child: ProfileMgrView(),
|
||||
),
|
||||
Flexible(
|
||||
flex: flwtch.columns[1],
|
||||
child: flwtch.selectedProfile == null ? Center(child: Text(AppLocalizations.of(context)!.createProfileToBegin)) : ContactsView(), //dev
|
||||
flex: columns[1],
|
||||
child: appState.selectedProfile == null ? Center(child: Text(AppLocalizations.of(context)!.createProfileToBegin)) : ContactsView(), //dev
|
||||
),
|
||||
Flexible(
|
||||
flex: flwtch.columns[2],
|
||||
child: flwtch.selectedConversation == ""
|
||||
flex: columns[2],
|
||||
child: appState.selectedConversation == null
|
||||
? Center(child: Text(AppLocalizations.of(context)!.addContactFirst))
|
||||
: //dev
|
||||
Container(child: MessageView()),
|
||||
|
|
|
@ -77,17 +77,19 @@ class _ContactRowState extends State<ContactRow> {
|
|||
]),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
var flwtch = Provider.of<FlwtchState>(context, listen: false);
|
||||
flwtch.setState(() => flwtch.selectedConversation = contact.onion);
|
||||
// case 2/3 handled by Double/TripleColumnView respectively
|
||||
if (flwtch.columns.length == 1) _pushMessageView(contact.onion);
|
||||
// requery instead of using contactinfostate directly because sometimes listview gets confused about data that resorts
|
||||
Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(contact.onion)!.unreadMessages = 0;
|
||||
// triggers update in Double/TripleColumnView
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = contact.onion;
|
||||
// if in singlepane mode, push to the stack
|
||||
var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context);
|
||||
if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(contact.onion);
|
||||
});
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void _pushMessageView(String handle) {
|
||||
Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(handle)!.unreadMessages = 0;
|
||||
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
|
|
|
@ -30,18 +30,32 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
padding: const EdgeInsets.all(2.0), //border size
|
||||
child: ProfileImage(
|
||||
badgeCount: 0,
|
||||
badgeColor: Provider.of<Settings>(context).theme.portraitProfileBadgeColor(),
|
||||
badgeTextColor: Provider.of<Settings>(context).theme.portraitProfileBadgeTextColor(),
|
||||
badgeColor: Provider
|
||||
.of<Settings>(context)
|
||||
.theme
|
||||
.portraitProfileBadgeColor(),
|
||||
badgeTextColor: Provider
|
||||
.of<Settings>(context)
|
||||
.theme
|
||||
.portraitProfileBadgeTextColor(),
|
||||
diameter: 64.0,
|
||||
imagePath: profile.imagePath,
|
||||
border: profile.isOnline ? Provider.of<Settings>(context).theme.portraitOnlineBorderColor() : Provider.of<Settings>(context).theme.portraitOfflineBorderColor())),
|
||||
border: profile.isOnline ? Provider
|
||||
.of<Settings>(context)
|
||||
.theme
|
||||
.portraitOnlineBorderColor() : Provider
|
||||
.of<Settings>(context)
|
||||
.theme
|
||||
.portraitOfflineBorderColor())),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
profile.nickname,
|
||||
semanticsLabel: profile.nickname,
|
||||
style: Provider.of<FlwtchState>(context).biggerFont,
|
||||
style: Provider
|
||||
.of<FlwtchState>(context)
|
||||
.biggerFont,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
|
@ -65,37 +79,35 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
var flwtch = Provider.of<FlwtchState>(context, listen: false);
|
||||
flwtch.setState(() {
|
||||
flwtch.selectedProfile = profile;
|
||||
flwtch.selectedConversation = "";
|
||||
});
|
||||
var appState = Provider.of<AppState>(context, listen: false);
|
||||
appState.selectedProfile = profile.onion;
|
||||
appState.selectedConversation = null;
|
||||
|
||||
switch (flwtch.columns.length) {
|
||||
case 1:
|
||||
_pushContactList(profile, false);
|
||||
break;
|
||||
case 2:
|
||||
_pushContactList(profile, true);
|
||||
break;
|
||||
} // case 3: handled by TripleColumnView
|
||||
_pushContactList(profile, appState.isLandscape(context));//orientation == Orientation.landscape);
|
||||
});
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void _pushContactList(ProfileInfoState profile, bool includeDoublePane) {
|
||||
void _pushContactList(ProfileInfoState profile, bool isLandscape) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
settings: RouteSettings(name: "conversations"),
|
||||
builder: (BuildContext buildcontext) {
|
||||
return OrientationBuilder(
|
||||
builder: (orientationBuilderContext, orientation) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<ProfileInfoState>.value(value: profile),
|
||||
ChangeNotifierProvider<ContactListState>.value(value: profile.contactList),
|
||||
],
|
||||
builder: (context, widget) => includeDoublePane ? DoubleColumnView() : ContactsView(),
|
||||
builder: (innercontext, widget) {
|
||||
var appState = Provider.of<AppState>(context);
|
||||
var settings = Provider.of<Settings>(context);
|
||||
return settings.uiColumns(appState.isLandscape(innercontext)).length > 1 ? DoubleColumnView() : ContactsView();
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue