Big refactoring
This commit is contained in:
parent
35beaa4492
commit
1bd36023e7
|
@ -1,3 +1,11 @@
|
|||
# Version 0.15.0
|
||||
### Features:
|
||||
- New room list app bar design
|
||||
- Chat app bar transparent
|
||||
### Changes:
|
||||
- Show presences of users sharing a direct chat
|
||||
- Big refactoring
|
||||
|
||||
# Version 0.14.0 - 2020-05-20
|
||||
### Features:
|
||||
- Implement image viewer
|
||||
|
|
1
ios/Flutter/.last_build_id
Normal file
1
ios/Flutter/.last_build_id
Normal file
|
@ -0,0 +1 @@
|
|||
6c5611b14df049743797687d0807922a
|
151
ios/Podfile.lock
151
ios/Podfile.lock
|
@ -1,52 +1,48 @@
|
|||
PODS:
|
||||
- file_picker (0.0.1):
|
||||
- Flutter
|
||||
- Firebase/Core (6.21.0):
|
||||
- Firebase/Core (6.27.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (= 6.4.0)
|
||||
- Firebase/CoreOnly (6.21.0):
|
||||
- FirebaseCore (= 6.6.5)
|
||||
- Firebase/Messaging (6.21.0):
|
||||
- FirebaseAnalytics (= 6.6.1)
|
||||
- Firebase/CoreOnly (6.27.0):
|
||||
- FirebaseCore (= 6.8.0)
|
||||
- Firebase/Messaging (6.27.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 4.3.0)
|
||||
- FirebaseMessaging (~> 4.5.0)
|
||||
- firebase_messaging (0.0.1):
|
||||
- Firebase/Core
|
||||
- Firebase/Messaging
|
||||
- Flutter
|
||||
- FirebaseAnalytics (6.4.0):
|
||||
- FirebaseCore (~> 6.6)
|
||||
- FirebaseInstallations (~> 1.1)
|
||||
- GoogleAppMeasurement (= 6.4.0)
|
||||
- FirebaseAnalytics (6.6.1):
|
||||
- FirebaseCore (~> 6.8)
|
||||
- FirebaseInstallations (~> 1.4)
|
||||
- GoogleAppMeasurement (= 6.6.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
|
||||
- GoogleUtilities/MethodSwizzler (~> 6.0)
|
||||
- GoogleUtilities/Network (~> 6.0)
|
||||
- "GoogleUtilities/NSData+zlib (~> 6.0)"
|
||||
- nanopb (= 0.3.9011)
|
||||
- FirebaseAnalyticsInterop (1.5.0)
|
||||
- FirebaseCore (6.6.5):
|
||||
- FirebaseCoreDiagnostics (~> 1.2)
|
||||
- FirebaseCoreDiagnosticsInterop (~> 1.2)
|
||||
- nanopb (~> 1.30905.0)
|
||||
- FirebaseCore (6.8.0):
|
||||
- FirebaseCoreDiagnostics (~> 1.3)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
- GoogleUtilities/Logger (~> 6.5)
|
||||
- FirebaseCoreDiagnostics (1.2.2):
|
||||
- FirebaseCoreDiagnosticsInterop (~> 1.2)
|
||||
- GoogleDataTransportCCTSupport (~> 2.0)
|
||||
- FirebaseCoreDiagnostics (1.4.0):
|
||||
- GoogleDataTransportCCTSupport (~> 3.1)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
- GoogleUtilities/Logger (~> 6.5)
|
||||
- nanopb (~> 0.3.901)
|
||||
- FirebaseCoreDiagnosticsInterop (1.2.0)
|
||||
- FirebaseInstallations (1.1.1):
|
||||
- FirebaseCore (~> 6.6)
|
||||
- GoogleUtilities/UserDefaults (~> 6.5)
|
||||
- nanopb (~> 1.30905.0)
|
||||
- FirebaseInstallations (1.4.0):
|
||||
- FirebaseCore (~> 6.8)
|
||||
- GoogleUtilities/Environment (~> 6.6)
|
||||
- GoogleUtilities/UserDefaults (~> 6.6)
|
||||
- PromisesObjC (~> 1.2)
|
||||
- FirebaseInstanceID (4.3.2):
|
||||
- FirebaseCore (~> 6.6)
|
||||
- FirebaseInstanceID (4.4.0):
|
||||
- FirebaseCore (~> 6.8)
|
||||
- FirebaseInstallations (~> 1.0)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
- GoogleUtilities/UserDefaults (~> 6.5)
|
||||
- FirebaseMessaging (4.3.0):
|
||||
- FirebaseAnalyticsInterop (~> 1.5)
|
||||
- FirebaseCore (~> 6.6)
|
||||
- FirebaseMessaging (4.5.0):
|
||||
- FirebaseCore (~> 6.8)
|
||||
- FirebaseInstanceID (~> 4.3)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.5)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
|
@ -54,6 +50,8 @@ PODS:
|
|||
- GoogleUtilities/UserDefaults (~> 6.5)
|
||||
- Protobuf (>= 3.9.2, ~> 3.9)
|
||||
- Flutter (1.0.0)
|
||||
- flutter_keyboard_visibility (0.7.0):
|
||||
- Flutter
|
||||
- flutter_local_notifications (0.0.1):
|
||||
- Flutter
|
||||
- flutter_secure_storage (3.3.1):
|
||||
|
@ -62,42 +60,45 @@ PODS:
|
|||
- Flutter
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/SQLCipher (2.7.5):
|
||||
- SQLCipher
|
||||
- FMDB/standard (2.7.5)
|
||||
- GoogleAppMeasurement (6.4.0):
|
||||
- GoogleAppMeasurement (6.6.1):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
|
||||
- GoogleUtilities/MethodSwizzler (~> 6.0)
|
||||
- GoogleUtilities/Network (~> 6.0)
|
||||
- "GoogleUtilities/NSData+zlib (~> 6.0)"
|
||||
- nanopb (= 0.3.9011)
|
||||
- GoogleDataTransport (5.1.0)
|
||||
- GoogleDataTransportCCTSupport (2.0.1):
|
||||
- GoogleDataTransport (~> 5.1)
|
||||
- nanopb (~> 0.3.901)
|
||||
- GoogleUtilities/AppDelegateSwizzler (6.5.2):
|
||||
- nanopb (~> 1.30905.0)
|
||||
- GoogleDataTransport (6.2.1)
|
||||
- GoogleDataTransportCCTSupport (3.2.0):
|
||||
- GoogleDataTransport (~> 6.1)
|
||||
- nanopb (~> 1.30905.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (6.6.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (6.5.2)
|
||||
- GoogleUtilities/Logger (6.5.2):
|
||||
- GoogleUtilities/Environment (6.6.0):
|
||||
- PromisesObjC (~> 1.2)
|
||||
- GoogleUtilities/Logger (6.6.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/MethodSwizzler (6.5.2):
|
||||
- GoogleUtilities/MethodSwizzler (6.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network (6.5.2):
|
||||
- GoogleUtilities/Network (6.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (6.5.2)"
|
||||
- GoogleUtilities/Reachability (6.5.2):
|
||||
- "GoogleUtilities/NSData+zlib (6.6.0)"
|
||||
- GoogleUtilities/Reachability (6.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (6.5.2):
|
||||
- GoogleUtilities/UserDefaults (6.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- image_picker (0.0.1):
|
||||
- Flutter
|
||||
- nanopb (0.3.9011):
|
||||
- nanopb/decode (= 0.3.9011)
|
||||
- nanopb/encode (= 0.3.9011)
|
||||
- nanopb/decode (0.3.9011)
|
||||
- nanopb/encode (0.3.9011)
|
||||
- nanopb (1.30905.0):
|
||||
- nanopb/decode (= 1.30905.0)
|
||||
- nanopb/encode (= 1.30905.0)
|
||||
- nanopb/decode (1.30905.0)
|
||||
- nanopb/encode (1.30905.0)
|
||||
- OLMKit (3.1.0):
|
||||
- OLMKit/olmc (= 3.1.0)
|
||||
- OLMKit/olmcpp (= 3.1.0)
|
||||
|
@ -107,8 +108,8 @@ PODS:
|
|||
- Flutter
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- PromisesObjC (1.2.8)
|
||||
- Protobuf (3.11.4)
|
||||
- PromisesObjC (1.2.9)
|
||||
- Protobuf (3.12.0)
|
||||
- receive_sharing_intent (0.0.1):
|
||||
- Flutter
|
||||
- share (0.5.2):
|
||||
|
@ -116,6 +117,14 @@ PODS:
|
|||
- sqflite (0.0.1):
|
||||
- Flutter
|
||||
- FMDB (~> 2.7.2)
|
||||
- sqflite_sqlcipher (0.0.1):
|
||||
- Flutter
|
||||
- FMDB/SQLCipher (~> 2.7.5)
|
||||
- SQLCipher (4.4.0):
|
||||
- SQLCipher/standard (= 4.4.0)
|
||||
- SQLCipher/common (4.4.0)
|
||||
- SQLCipher/standard (4.4.0):
|
||||
- SQLCipher/common
|
||||
- url_launcher (0.0.1):
|
||||
- Flutter
|
||||
- url_launcher_macos (0.0.1):
|
||||
|
@ -129,6 +138,7 @@ DEPENDENCIES:
|
|||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
- flutter_sound (from `.symlinks/plugins/flutter_sound/ios`)
|
||||
|
@ -139,6 +149,7 @@ DEPENDENCIES:
|
|||
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||
- share (from `.symlinks/plugins/share/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- sqflite_sqlcipher (from `.symlinks/plugins/sqflite_sqlcipher/ios`)
|
||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||
- url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
|
||||
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
|
||||
|
@ -148,10 +159,8 @@ SPEC REPOS:
|
|||
trunk:
|
||||
- Firebase
|
||||
- FirebaseAnalytics
|
||||
- FirebaseAnalyticsInterop
|
||||
- FirebaseCore
|
||||
- FirebaseCoreDiagnostics
|
||||
- FirebaseCoreDiagnosticsInterop
|
||||
- FirebaseInstallations
|
||||
- FirebaseInstanceID
|
||||
- FirebaseMessaging
|
||||
|
@ -164,6 +173,7 @@ SPEC REPOS:
|
|||
- OLMKit
|
||||
- PromisesObjC
|
||||
- Protobuf
|
||||
- SQLCipher
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
file_picker:
|
||||
|
@ -172,6 +182,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_keyboard_visibility:
|
||||
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||
flutter_local_notifications:
|
||||
:path: ".symlinks/plugins/flutter_local_notifications/ios"
|
||||
flutter_secure_storage:
|
||||
|
@ -190,6 +202,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/share/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
sqflite_sqlcipher:
|
||||
:path: ".symlinks/plugins/sqflite_sqlcipher/ios"
|
||||
url_launcher:
|
||||
:path: ".symlinks/plugins/url_launcher/ios"
|
||||
url_launcher_macos:
|
||||
|
@ -201,35 +215,36 @@ EXTERNAL SOURCES:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
file_picker: 408623be2125b79a4539cf703be3d4b3abe5e245
|
||||
Firebase: f378c80340dd41c0ad0914af740c021eb282a04b
|
||||
firebase_messaging: 73b3e7dd7b3b6a7e4bdac10d5295211ca4f87f90
|
||||
FirebaseAnalytics: a1a0b3327ceb5cd5b4bacffdb293f6c909aa087d
|
||||
FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae
|
||||
FirebaseCore: 9f495d3afacb7b558711e6218ebb14b1c51b5802
|
||||
FirebaseCoreDiagnostics: e9b4cd8ba60dee0f2d13347332e4b7898cca5b61
|
||||
FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
|
||||
FirebaseInstallations: acb3216eb9784d3b1d2d2d635ff74fa892cc0c44
|
||||
FirebaseInstanceID: 7ee0d6777013bb952f377b41965bf132b6a075be
|
||||
FirebaseMessaging: 4ec33842d36b3319e062e51fb8b35a74f726950d
|
||||
Firebase: fc4cbf6f1592636431821ef9a3c557e4dfd9f268
|
||||
firebase_messaging: cffb57ce40958c6204f03fb0c81713e4cd1e240c
|
||||
FirebaseAnalytics: 0ea640473474f036cabbc2576e20c2d63671c92f
|
||||
FirebaseCore: feda061cb1ee6d8ad4824f4a4a8ffbcfe284f595
|
||||
FirebaseCoreDiagnostics: 4505e4d4009b1d93f605088ee7d7764d5f0d1c84
|
||||
FirebaseInstallations: 293f567159b6d66d1c990f13bb868066096c94ec
|
||||
FirebaseInstanceID: 3b119bfe90e904851218159c9a4ecb847cc51d18
|
||||
FirebaseMessaging: ad9e1a80ea64905e01a0ce1b3eb76a2944544151
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
flutter_keyboard_visibility: 6195387fb6d8f46e5cd6dda4a4154e41f800f545
|
||||
flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186
|
||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||
flutter_sound: 0e8163ceac1e00eb6d894e2ae4641ba726a2c479
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
GoogleAppMeasurement: 6e68a94d0eaeb1d73ef6b0ed4f7334e29d63ae29
|
||||
GoogleDataTransport: b29a21d813e906014ca16c00897827e40e4a24ab
|
||||
GoogleDataTransportCCTSupport: 6f15a89b0ca35d6fa523e1f752ef818588885988
|
||||
GoogleUtilities: ad0f3b691c67909d03a3327cc205222ab8f42e0e
|
||||
GoogleAppMeasurement: 2fd5c5a56c069db635c8e7b92d4809a9591d0a69
|
||||
GoogleDataTransport: 9a8a16f79feffc7f42096743de2a7c4815e84020
|
||||
GoogleDataTransportCCTSupport: 489c1265d2c85b68187a83a911913d190012158d
|
||||
GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1
|
||||
image_picker: e3eacd46b94694dde7cf2705955cece853aa1a8f
|
||||
nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd
|
||||
nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
|
||||
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
|
||||
open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d
|
||||
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
|
||||
PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6
|
||||
Protobuf: 176220c526ad8bd09ab1fb40a978eac3fef665f7
|
||||
PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75
|
||||
Protobuf: 2793fcd0622a00b546c60e7cbbcc493e043e9bb9
|
||||
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
|
||||
share: bae0a282aab4483288913fc4dc0b935d4b491f2e
|
||||
sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0
|
||||
sqflite_sqlcipher: 45e72be2f26bde6ad196ff8b084123d8634ba921
|
||||
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
|
||||
url_launcher: a1c0cc845906122c4784c542523d8cacbded5626
|
||||
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
|
||||
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
|
||||
|
|
|
@ -328,7 +328,6 @@
|
|||
/* Begin XCBuildConfiguration section */
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
|
@ -446,7 +445,6 @@
|
|||
};
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
|
@ -503,7 +501,6 @@
|
|||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
|
|
|
@ -167,7 +167,12 @@ class SimpleDialogs {
|
|||
children: <Widget>[
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(width: 16),
|
||||
Text(L10n.of(context).loadingPleaseWait),
|
||||
Expanded(
|
||||
child: Text(
|
||||
L10n.of(context).loadingPleaseWait,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:fluffychat/components/dialogs/presence_dialog.dart';
|
||||
import 'package:fluffychat/utils/app_route.dart';
|
||||
import 'package:fluffychat/views/chat.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../utils/client_presence_extension.dart';
|
||||
import '../avatar.dart';
|
||||
import '../matrix.dart';
|
||||
|
||||
|
@ -10,50 +11,48 @@ class PresenceListItem extends StatelessWidget {
|
|||
|
||||
const PresenceListItem(this.presence);
|
||||
|
||||
static final Map<String, Profile> _presences = {};
|
||||
|
||||
Future<Profile> _requestProfile(BuildContext context) async {
|
||||
_presences[presence.senderId] ??=
|
||||
await Matrix.of(context).client.getProfileFromUserId(presence.senderId);
|
||||
return _presences[presence.senderId];
|
||||
void _startChatAction(BuildContext context, String userId) async {
|
||||
final roomId = await User(userId,
|
||||
room: Room(client: Matrix.of(context).client, id: ''))
|
||||
.startDirectChat();
|
||||
await Navigator.of(context).pushAndRemoveUntil(
|
||||
AppRoute.defaultRoute(
|
||||
context,
|
||||
ChatView(roomId),
|
||||
),
|
||||
(Route r) => r.isFirst);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<Profile>(
|
||||
future: _requestProfile(context),
|
||||
future:
|
||||
Matrix.of(context).client.requestProfileCached(presence.senderId),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) return Container();
|
||||
Uri avatarUrl;
|
||||
var displayname = presence.senderId.localpart;
|
||||
if (snapshot.hasData) {
|
||||
avatarUrl = snapshot.data.avatarUrl;
|
||||
displayname = snapshot.data.displayname;
|
||||
displayname =
|
||||
snapshot.data.displayname ?? presence.senderId.localpart;
|
||||
}
|
||||
return InkWell(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (c) => PresenceDialog(
|
||||
presence,
|
||||
avatarUrl: avatarUrl,
|
||||
displayname: displayname,
|
||||
),
|
||||
child: Container(
|
||||
width: 80,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 9),
|
||||
Avatar(avatarUrl, displayname),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
displayname,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
onTap: () => _startChatAction(context, presence.senderId),
|
||||
child: Container(
|
||||
width: 80,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 9),
|
||||
Avatar(avatarUrl, displayname),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
displayname,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -3,8 +3,18 @@ import 'package:famedlysdk/famedlysdk.dart';
|
|||
extension ClientPresenceExtension on Client {
|
||||
List<Presence> get statusList {
|
||||
final statusList = presences.values.toList().reversed.toList();
|
||||
statusList.removeWhere((p) => p.presence.statusMsg?.isEmpty ?? true);
|
||||
final directRooms = rooms.where((r) => r.isDirectChat).toList();
|
||||
statusList.removeWhere((p) =>
|
||||
directRooms.indexWhere((r) => r.directChatMatrixID == p.senderId) ==
|
||||
-1);
|
||||
statusList.reversed.toList();
|
||||
return statusList;
|
||||
}
|
||||
|
||||
static final Map<String, Profile> presencesCache = {};
|
||||
|
||||
Future<Profile> requestProfileCached(String senderId) async {
|
||||
presencesCache[senderId] ??= await getProfileFromUserId(senderId);
|
||||
return presencesCache[senderId];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -358,7 +358,9 @@ class _ChatState extends State<_Chat> {
|
|||
}
|
||||
|
||||
return Scaffold(
|
||||
extendBodyBehindAppBar: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).appBarTheme.color.withOpacity(0.9),
|
||||
leading: selectMode
|
||||
? IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
|
@ -462,337 +464,328 @@ class _ChatState extends State<_Chat> {
|
|||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SafeArea(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
if (_loadingHistory) LinearProgressIndicator(),
|
||||
Expanded(
|
||||
child: FutureBuilder<bool>(
|
||||
future: getTimeline(),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
Column(
|
||||
children: <Widget>[
|
||||
if (_loadingHistory) LinearProgressIndicator(),
|
||||
Expanded(
|
||||
child: FutureBuilder<bool>(
|
||||
future: getTimeline(),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
if (room.notificationCount != null &&
|
||||
room.notificationCount > 0 &&
|
||||
timeline != null &&
|
||||
timeline.events.isNotEmpty) {
|
||||
room.sendReadReceipt(timeline.events.first.eventId);
|
||||
}
|
||||
if (room.notificationCount != null &&
|
||||
room.notificationCount > 0 &&
|
||||
timeline != null &&
|
||||
timeline.events.isNotEmpty) {
|
||||
room.sendReadReceipt(timeline.events.first.eventId);
|
||||
}
|
||||
|
||||
if (timeline.events.isEmpty) return Container();
|
||||
if (timeline.events.isEmpty) return Container();
|
||||
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: max(
|
||||
0,
|
||||
(MediaQuery.of(context).size.width -
|
||||
AdaptivePageLayout.defaultMinWidth *
|
||||
3.5) /
|
||||
2),
|
||||
),
|
||||
reverse: true,
|
||||
itemCount: timeline.events.length + 2,
|
||||
controller: _scrollController,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
return i == timeline.events.length + 1
|
||||
? _canLoadMore && !_loadingHistory
|
||||
? FlatButton(
|
||||
child: Text(
|
||||
L10n.of(context).loadMore,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration:
|
||||
TextDecoration.underline,
|
||||
),
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: max(
|
||||
0,
|
||||
(MediaQuery.of(context).size.width -
|
||||
AdaptivePageLayout.defaultMinWidth *
|
||||
3.5) /
|
||||
2),
|
||||
),
|
||||
reverse: true,
|
||||
itemCount: timeline.events.length + 2,
|
||||
controller: _scrollController,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
return i == timeline.events.length + 1
|
||||
? _canLoadMore && !_loadingHistory
|
||||
? FlatButton(
|
||||
child: Text(
|
||||
L10n.of(context).loadMore,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
onPressed: requestHistory,
|
||||
)
|
||||
: Container()
|
||||
: i == 0
|
||||
? AnimatedContainer(
|
||||
height: seenByText.isEmpty ? 0 : 24,
|
||||
duration: seenByText.isEmpty
|
||||
? Duration(milliseconds: 0)
|
||||
: Duration(milliseconds: 500),
|
||||
alignment:
|
||||
timeline.events.first.senderId ==
|
||||
client.userID
|
||||
? Alignment.topRight
|
||||
: Alignment.topLeft,
|
||||
child: Text(
|
||||
seenByText,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
onPressed: requestHistory,
|
||||
)
|
||||
: Container()
|
||||
: i == 0
|
||||
? AnimatedContainer(
|
||||
height: seenByText.isEmpty ? 0 : 24,
|
||||
duration: seenByText.isEmpty
|
||||
? Duration(milliseconds: 0)
|
||||
: Duration(milliseconds: 500),
|
||||
alignment:
|
||||
timeline.events.first.senderId ==
|
||||
client.userID
|
||||
? Alignment.topRight
|
||||
: Alignment.topLeft,
|
||||
child: Text(
|
||||
seenByText,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
),
|
||||
)
|
||||
: Message(timeline.events[i - 1],
|
||||
onAvatarTab: (Event event) {
|
||||
sendController.text +=
|
||||
' ${event.senderId}';
|
||||
}, onSelect: (Event event) {
|
||||
if (!event.redacted) {
|
||||
if (selectedEvents.contains(event)) {
|
||||
setState(
|
||||
() =>
|
||||
selectedEvents.remove(event),
|
||||
);
|
||||
} else {
|
||||
setState(
|
||||
() => selectedEvents.add(event),
|
||||
);
|
||||
}
|
||||
selectedEvents.sort(
|
||||
(a, b) => a.originServerTs
|
||||
.compareTo(b.originServerTs),
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
),
|
||||
)
|
||||
: Message(timeline.events[i - 1],
|
||||
onAvatarTab: (Event event) {
|
||||
sendController.text +=
|
||||
' ${event.senderId}';
|
||||
}, onSelect: (Event event) {
|
||||
if (!event.redacted) {
|
||||
if (selectedEvents.contains(event)) {
|
||||
setState(
|
||||
() => selectedEvents.remove(event),
|
||||
);
|
||||
} else {
|
||||
setState(
|
||||
() => selectedEvents.add(event),
|
||||
);
|
||||
}
|
||||
},
|
||||
longPressSelect: selectedEvents.isEmpty,
|
||||
selected: selectedEvents
|
||||
.contains(timeline.events[i - 1]),
|
||||
timeline: timeline,
|
||||
nextEvent: i >= 2
|
||||
? timeline.events[i - 2]
|
||||
: null);
|
||||
});
|
||||
},
|
||||
),
|
||||
selectedEvents.sort(
|
||||
(a, b) => a.originServerTs
|
||||
.compareTo(b.originServerTs),
|
||||
);
|
||||
}
|
||||
},
|
||||
longPressSelect: selectedEvents.isEmpty,
|
||||
selected: selectedEvents
|
||||
.contains(timeline.events[i - 1]),
|
||||
timeline: timeline,
|
||||
nextEvent: i >= 2
|
||||
? timeline.events[i - 2]
|
||||
: null);
|
||||
});
|
||||
},
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
height: replyEvent != null ? 56 : 0,
|
||||
child: Material(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () => setState(() => replyEvent = null),
|
||||
),
|
||||
Expanded(
|
||||
child: ReplyContent(replyEvent),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
height: replyEvent != null ? 56 : 0,
|
||||
child: Material(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
thickness: 1,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () => setState(() => replyEvent = null),
|
||||
),
|
||||
Expanded(
|
||||
child: ReplyContent(replyEvent),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
room.canSendDefaultMessages &&
|
||||
room.membership == Membership.join
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.backgroundColor
|
||||
.withOpacity(0.8),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: selectMode
|
||||
? <Widget>[
|
||||
Container(
|
||||
height: 56,
|
||||
child: FlatButton(
|
||||
onPressed: () =>
|
||||
forwardEventsAction(context),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.keyboard_arrow_left),
|
||||
Text(L10n.of(context).forward),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
selectedEvents.length == 1
|
||||
? selectedEvents.first.status > 0
|
||||
? Container(
|
||||
height: 56,
|
||||
child: FlatButton(
|
||||
onPressed: () => replyAction(),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
L10n.of(context).reply),
|
||||
Icon(Icons
|
||||
.keyboard_arrow_right),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: 56,
|
||||
child: FlatButton(
|
||||
onPressed: () =>
|
||||
sendAgainAction(),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Text(L10n.of(context)
|
||||
.tryToSendAgain),
|
||||
SizedBox(width: 4),
|
||||
Icon(Icons.send, size: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
]
|
||||
: <Widget>[
|
||||
if (!kIsWeb && inputText.isEmpty)
|
||||
PopupMenuButton<String>(
|
||||
icon: Icon(Icons.add),
|
||||
onSelected: (String choice) async {
|
||||
if (choice == 'file') {
|
||||
sendFileAction(context);
|
||||
} else if (choice == 'image') {
|
||||
sendImageAction(context);
|
||||
}
|
||||
if (choice == 'camera') {
|
||||
openCameraAction(context);
|
||||
}
|
||||
if (choice == 'voice') {
|
||||
voiceMessageAction(context);
|
||||
}
|
||||
},
|
||||
itemBuilder: (BuildContext context) =>
|
||||
<PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'file',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.green,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.attachment),
|
||||
),
|
||||
title:
|
||||
Text(L10n.of(context).sendFile),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'image',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.image),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).sendImage),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'camera',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.purple,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.camera_alt),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).openCamera),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'voice',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.mic),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).voiceMessage),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
thickness: 1,
|
||||
),
|
||||
room.canSendDefaultMessages && room.membership == Membership.join
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Theme.of(context).backgroundColor.withOpacity(0.8),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: selectMode
|
||||
? <Widget>[
|
||||
Container(
|
||||
height: 56,
|
||||
child: FlatButton(
|
||||
onPressed: () =>
|
||||
forwardEventsAction(context),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.keyboard_arrow_left),
|
||||
Text(L10n.of(context).forward),
|
||||
],
|
||||
),
|
||||
EncryptionButton(room),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4.0),
|
||||
child: InputBar(
|
||||
room: room,
|
||||
minLines: 1,
|
||||
maxLines: kIsWeb ? 1 : 8,
|
||||
keyboardType: kIsWeb
|
||||
? TextInputType.text
|
||||
: TextInputType.multiline,
|
||||
onSubmitted: (String text) {
|
||||
send();
|
||||
FocusScope.of(context)
|
||||
.requestFocus(inputFocus);
|
||||
},
|
||||
focusNode: inputFocus,
|
||||
controller: sendController,
|
||||
decoration: InputDecoration(
|
||||
hintText:
|
||||
L10n.of(context).writeAMessage,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
selectedEvents.length == 1
|
||||
? selectedEvents.first.status > 0
|
||||
? Container(
|
||||
height: 56,
|
||||
child: FlatButton(
|
||||
onPressed: () => replyAction(),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Text(L10n.of(context).reply),
|
||||
Icon(Icons
|
||||
.keyboard_arrow_right),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: 56,
|
||||
child: FlatButton(
|
||||
onPressed: () =>
|
||||
sendAgainAction(),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Text(L10n.of(context)
|
||||
.tryToSendAgain),
|
||||
SizedBox(width: 4),
|
||||
Icon(Icons.send, size: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
]
|
||||
: <Widget>[
|
||||
if (!kIsWeb && inputText.isEmpty)
|
||||
PopupMenuButton<String>(
|
||||
icon: Icon(Icons.add),
|
||||
onSelected: (String choice) async {
|
||||
if (choice == 'file') {
|
||||
sendFileAction(context);
|
||||
} else if (choice == 'image') {
|
||||
sendImageAction(context);
|
||||
}
|
||||
if (choice == 'camera') {
|
||||
openCameraAction(context);
|
||||
}
|
||||
if (choice == 'voice') {
|
||||
voiceMessageAction(context);
|
||||
}
|
||||
},
|
||||
itemBuilder: (BuildContext context) =>
|
||||
<PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'file',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.green,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.attachment),
|
||||
),
|
||||
title:
|
||||
Text(L10n.of(context).sendFile),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
onChanged: (String text) {
|
||||
typingCoolDown?.cancel();
|
||||
typingCoolDown =
|
||||
Timer(Duration(seconds: 2), () {
|
||||
typingCoolDown = null;
|
||||
currentlyTyping = false;
|
||||
room.sendTypingInfo(false);
|
||||
});
|
||||
typingTimeout ??=
|
||||
Timer(Duration(seconds: 30), () {
|
||||
typingTimeout = null;
|
||||
currentlyTyping = false;
|
||||
});
|
||||
if (!currentlyTyping) {
|
||||
currentlyTyping = true;
|
||||
room.sendTypingInfo(true,
|
||||
timeout: Duration(seconds: 30)
|
||||
.inMilliseconds);
|
||||
}
|
||||
setState(() => inputText = text);
|
||||
},
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'image',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.image),
|
||||
),
|
||||
title:
|
||||
Text(L10n.of(context).sendImage),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'camera',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.purple,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.camera_alt),
|
||||
),
|
||||
title:
|
||||
Text(L10n.of(context).openCamera),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'voice',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.mic),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).voiceMessage),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
EncryptionButton(room),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4.0),
|
||||
child: InputBar(
|
||||
room: room,
|
||||
minLines: 1,
|
||||
maxLines: kIsWeb ? 1 : 8,
|
||||
keyboardType: kIsWeb
|
||||
? TextInputType.text
|
||||
: TextInputType.multiline,
|
||||
onSubmitted: (String text) {
|
||||
send();
|
||||
FocusScope.of(context)
|
||||
.requestFocus(inputFocus);
|
||||
},
|
||||
focusNode: inputFocus,
|
||||
controller: sendController,
|
||||
decoration: InputDecoration(
|
||||
hintText:
|
||||
L10n.of(context).writeAMessage,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
onChanged: (String text) {
|
||||
typingCoolDown?.cancel();
|
||||
typingCoolDown =
|
||||
Timer(Duration(seconds: 2), () {
|
||||
typingCoolDown = null;
|
||||
currentlyTyping = false;
|
||||
room.sendTypingInfo(false);
|
||||
});
|
||||
typingTimeout ??=
|
||||
Timer(Duration(seconds: 30), () {
|
||||
typingTimeout = null;
|
||||
currentlyTyping = false;
|
||||
});
|
||||
if (!currentlyTyping) {
|
||||
currentlyTyping = true;
|
||||
room.sendTypingInfo(true,
|
||||
timeout: Duration(seconds: 30)
|
||||
.inMilliseconds);
|
||||
}
|
||||
setState(() => inputText = text);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (!kIsWeb && inputText.isEmpty)
|
||||
IconButton(
|
||||
icon: Icon(Icons.mic),
|
||||
onPressed: () =>
|
||||
voiceMessageAction(context),
|
||||
),
|
||||
if (kIsWeb || inputText.isNotEmpty)
|
||||
IconButton(
|
||||
icon: Icon(Icons.send),
|
||||
onPressed: () => send(),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!kIsWeb && inputText.isEmpty)
|
||||
IconButton(
|
||||
icon: Icon(Icons.mic),
|
||||
onPressed: () =>
|
||||
voiceMessageAction(context),
|
||||
),
|
||||
if (kIsWeb || inputText.isNotEmpty)
|
||||
IconButton(
|
||||
icon: Icon(Icons.send),
|
||||
onPressed: () => send(),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -298,34 +298,61 @@ class _ChatListState extends State<ChatList> {
|
|||
onPressed: () =>
|
||||
Matrix.of(context).shareContent = null,
|
||||
),
|
||||
automaticallyImplyLeading: false,
|
||||
titleSpacing: 0,
|
||||
title: selectMode == SelectMode.share
|
||||
? Text(L10n.of(context).share)
|
||||
: Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
height: 42,
|
||||
margin: EdgeInsets.only(right: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
),
|
||||
child: TextField(
|
||||
autocorrect: false,
|
||||
controller: searchController,
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: loadingPublicRooms
|
||||
? Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(),
|
||||
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Material(
|
||||
elevation: 5,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8),
|
||||
child: Row(
|
||||
children: [
|
||||
Builder(
|
||||
builder: (context) => IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: Icon(Icons.menu),
|
||||
onPressed: () =>
|
||||
Scaffold.of(context).openDrawer(),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
autocorrect: false,
|
||||
controller: searchController,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.all(9),
|
||||
border: InputBorder.none,
|
||||
hintText:
|
||||
L10n.of(context).searchForAChat,
|
||||
),
|
||||
)
|
||||
: Icon(Icons.search),
|
||||
contentPadding: EdgeInsets.all(9),
|
||||
border: InputBorder.none,
|
||||
hintText: L10n.of(context).searchForAChat,
|
||||
),
|
||||
),
|
||||
loadingPublicRooms
|
||||
? Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child:
|
||||
CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: Icon(Icons.account_circle),
|
||||
onPressed: () =>
|
||||
Navigator.of(context).push(
|
||||
AppRoute.defaultRoute(
|
||||
context,
|
||||
SettingsView())),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -433,9 +460,9 @@ class _ChatListState extends State<ChatList> {
|
|||
? Container()
|
||||
: PreferredSize(
|
||||
preferredSize:
|
||||
Size.fromHeight(89),
|
||||
Size.fromHeight(90),
|
||||
child: Container(
|
||||
height: 81,
|
||||
height: 82,
|
||||
child: ListView.builder(
|
||||
scrollDirection:
|
||||
Axis.horizontal,
|
||||
|
|
37
pubspec.lock
37
pubspec.lock
|
@ -71,6 +71,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -129,12 +136,19 @@ packages:
|
|||
url: "https://github.com/simolus3/moor.git"
|
||||
source: git
|
||||
version: "1.0.0"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
famedlysdk:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: "857775cf37804440717ce797e0ed63fd39066904"
|
||||
resolved-ref: "857775cf37804440717ce797e0ed63fd39066904"
|
||||
ref: b8c6decafc52cbf5c09288c6c6dde62b62ae978f
|
||||
resolved-ref: b8c6decafc52cbf5c09288c6c6dde62b62ae978f
|
||||
url: "https://gitlab.com/famedly/famedlysdk.git"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
|
@ -469,7 +483,7 @@ packages:
|
|||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.9.3"
|
||||
package_resolver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -483,7 +497,7 @@ packages:
|
|||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
version: "1.7.0"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -561,13 +575,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.2"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
random_string:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -628,7 +635,7 @@ packages:
|
|||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.5"
|
||||
version: "2.0.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -705,21 +712,21 @@ packages:
|
|||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.13.0"
|
||||
version: "1.14.7"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.15"
|
||||
version: "0.2.16"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.1"
|
||||
version: "0.3.7"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -27,7 +27,7 @@ dependencies:
|
|||
famedlysdk:
|
||||
git:
|
||||
url: https://gitlab.com/famedly/famedlysdk.git
|
||||
ref: 857775cf37804440717ce797e0ed63fd39066904
|
||||
ref: b8c6decafc52cbf5c09288c6c6dde62b62ae978f
|
||||
|
||||
localstorage: ^3.0.1+4
|
||||
bubble: ^1.1.9+1
|
||||
|
|
Loading…
Reference in a new issue