merged to origin/devlop
This commit is contained in:
@ -35,7 +35,7 @@ class _ChatInfoState extends State<ChatInfo> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isGroup = widget.room.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
var isGroup = widget.room.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.room.displayName),
|
||||
|
@ -13,20 +13,16 @@ class ParticipantsListView extends StatefulWidget {
|
||||
|
||||
class _ParticipantsListViewState extends State<ParticipantsListView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Teilnehmende'),
|
||||
),
|
||||
body: ListView(
|
||||
children: widget.participantsResponse.data.map((participant) {
|
||||
return ListTile(
|
||||
children: widget.participantsResponse.data.map((participant) => ListTile(
|
||||
leading: UserAvatar(id: participant.actorId),
|
||||
title: Text(participant.displayName),
|
||||
subtitle: participant.statusMessage != null ? Text(participant.statusMessage!) : null,
|
||||
);
|
||||
}).toList(),
|
||||
)).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -119,14 +119,14 @@ class _ChatListState extends State<ChatList> {
|
||||
|
||||
if(data.primaryLoading()) return const LoadingSpinner();
|
||||
latestData = data;
|
||||
List<ChatTile> chats = [];
|
||||
var chats = <ChatTile>[];
|
||||
for (var chatRoom in data.getRoomsResponse.sortBy(
|
||||
lastActivity: true,
|
||||
favoritesToTop: Provider.of<SettingsProvider>(context).val().talkSettings.sortFavoritesToTop,
|
||||
unreadToTop: Provider.of<SettingsProvider>(context).val().talkSettings.sortUnreadToTop,
|
||||
)
|
||||
) {
|
||||
bool hasDraft = settings.val().talkSettings.drafts.containsKey(chatRoom.token);
|
||||
var hasDraft = settings.val().talkSettings.drafts.containsKey(chatRoom.token);
|
||||
chats.add(ChatTile(data: chatRoom, query: _query, hasDraft: hasDraft));
|
||||
}
|
||||
|
||||
@ -146,4 +146,4 @@ class _ChatListState extends State<ChatList> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,19 +40,18 @@ class _ChatViewState extends State<ChatView> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<ChatProps>(
|
||||
Widget build(BuildContext context) => Consumer<ChatProps>(
|
||||
builder: (context, data, child) {
|
||||
List<Widget> messages = List<Widget>.empty(growable: true);
|
||||
var messages = List<Widget>.empty(growable: true);
|
||||
|
||||
if(!data.primaryLoading()) {
|
||||
|
||||
DateTime lastDate = DateTime.now();
|
||||
var lastDate = DateTime.now();
|
||||
data.getChatResponse.sortByTimestamp().forEach((element) {
|
||||
DateTime elementDate = DateTime.fromMillisecondsSinceEpoch(element.timestamp * 1000);
|
||||
var elementDate = DateTime.fromMillisecondsSinceEpoch(element.timestamp * 1000);
|
||||
|
||||
if(element.systemMessage.contains('reaction')) return;
|
||||
int commonRead = int.parse(data.getChatResponse.headers?['x-chat-last-common-read'] ?? '0');
|
||||
var commonRead = int.parse(data.getChatResponse.headers?['x-chat-last-common-read'] ?? '0');
|
||||
|
||||
if(!elementDate.isSameDay(lastDate)) {
|
||||
lastDate = elementDate;
|
||||
@ -140,5 +139,4 @@ class _ChatViewState extends State<ChatView> {
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -51,15 +51,13 @@ class ChatBubble extends StatefulWidget {
|
||||
|
||||
class _ChatBubbleState extends State<ChatBubble> {
|
||||
|
||||
BubbleStyle getSystemStyle() {
|
||||
return BubbleStyle(
|
||||
BubbleStyle getSystemStyle() => BubbleStyle(
|
||||
color: AppTheme.isDarkMode(context) ? const Color(0xff182229) : Colors.white,
|
||||
borderWidth: 1,
|
||||
elevation: 2,
|
||||
margin: const BubbleEdges.only(bottom: 20, top: 10),
|
||||
alignment: Alignment.center,
|
||||
);
|
||||
}
|
||||
|
||||
BubbleStyle getRemoteStyle(bool seamless) {
|
||||
var color = AppTheme.isDarkMode(context) ? const Color(0xff202c33) : Colors.white;
|
||||
@ -105,17 +103,17 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
message = ChatMessage(originalMessage: widget.bubbleData.message, originalData: widget.bubbleData.messageParameters);
|
||||
bool showActorDisplayName = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
bool showBubbleTime = widget.bubbleData.messageType != GetRoomResponseObjectMessageType.system;
|
||||
var showActorDisplayName = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
var showBubbleTime = widget.bubbleData.messageType != GetRoomResponseObjectMessageType.system;
|
||||
|
||||
Text actorText = Text(
|
||||
var actorText = Text(
|
||||
widget.bubbleData.actorDisplayName,
|
||||
textAlign: TextAlign.start,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold),
|
||||
);
|
||||
|
||||
Text timeText = Text(
|
||||
var timeText = Text(
|
||||
Jiffy.parseFromMillisecondsSinceEpoch(widget.bubbleData.timestamp * 1000).format(pattern: 'HH:mm'),
|
||||
textAlign: TextAlign.end,
|
||||
style: TextStyle(color: widget.timeIconColor, fontSize: widget.timeIconSize),
|
||||
@ -186,8 +184,8 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
),
|
||||
onLongPress: () {
|
||||
showDialog(context: context, builder: (context) {
|
||||
List<String> commonReactions = ['👍', '👎', '😆', '❤️', '👀'];
|
||||
bool canReact = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
|
||||
var commonReactions = <String>['👍', '👎', '😆', '❤️', '👀'];
|
||||
var canReact = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
|
||||
return SimpleDialog(
|
||||
children: [
|
||||
Visibility(
|
||||
@ -217,8 +215,7 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
showDialog(context: context, builder: (context) {
|
||||
return AlertDialog(
|
||||
showDialog(context: context, builder: (context) => AlertDialog(
|
||||
contentPadding: const EdgeInsets.all(15),
|
||||
titlePadding: const EdgeInsets.only(left: 6, top: 15),
|
||||
title: Row(
|
||||
@ -278,8 +275,7 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
));
|
||||
},
|
||||
style: IconButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
@ -350,8 +346,7 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
if(message.file == null) return;
|
||||
|
||||
if(downloadProgress > 0) {
|
||||
showDialog(context: context, builder: (context) {
|
||||
return AlertDialog(
|
||||
showDialog(context: context, builder: (context) => AlertDialog(
|
||||
title: const Text('Download abbrechen?'),
|
||||
content: const Text('Möchtest du den Download abbrechen?'),
|
||||
actions: [
|
||||
@ -369,8 +364,7 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
});
|
||||
}, child: const Text('Ja, Abbrechen'))
|
||||
],
|
||||
);
|
||||
});
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -388,11 +382,9 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
});
|
||||
|
||||
if(result.type != ResultType.done) {
|
||||
showDialog(context: context, builder: (context) {
|
||||
return AlertDialog(
|
||||
showDialog(context: context, builder: (context) => AlertDialog(
|
||||
content: Text(result.message),
|
||||
);
|
||||
});
|
||||
));
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -408,7 +400,7 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
alignment: widget.isSender ? WrapAlignment.end : WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
children: widget.bubbleData.reactions?.entries.map<Widget>((e) {
|
||||
bool hasSelfReacted = widget.bubbleData.reactionsSelf?.contains(e.key) ?? false;
|
||||
var hasSelfReacted = widget.bubbleData.reactionsSelf?.contains(e.key) ?? false;
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(right: 2.5, left: 2.5),
|
||||
child: ActionChip(
|
||||
|
@ -37,8 +37,7 @@ class ChatMessage {
|
||||
}
|
||||
|
||||
return CachedNetworkImage(
|
||||
errorWidget: (context, url, error) {
|
||||
return Padding(padding: const EdgeInsets.only(top: 10), child: Row(
|
||||
errorWidget: (context, url, error) => Padding(padding: const EdgeInsets.only(top: 10), child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
@ -47,12 +46,9 @@ class ChatMessage {
|
||||
Flexible(child: Text(file!.name, maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.bold))),
|
||||
const SizedBox(width: 10),
|
||||
],
|
||||
));
|
||||
},
|
||||
)),
|
||||
alignment: Alignment.center,
|
||||
placeholder: (context, url) {
|
||||
return const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator());
|
||||
},
|
||||
placeholder: (context, url) => const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator()),
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
errorListener: (value) {},
|
||||
@ -60,9 +56,9 @@ class ChatMessage {
|
||||
);
|
||||
}
|
||||
|
||||
void onOpen(LinkableElement link) async {
|
||||
Future<void> onOpen(LinkableElement link) async {
|
||||
if(await canLaunchUrlString(link.url)) {
|
||||
await launchUrlString(link.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,6 @@ class _ChatTextfieldState extends State<ChatTextfield> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void setDraft(String text) {
|
||||
if(text.isNotEmpty) {
|
||||
settings.val(write: true).talkSettings.drafts[widget.sendToToken] = text;
|
||||
@ -96,8 +95,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
showDialog(context: context, builder: (context) {
|
||||
return SimpleDialog(
|
||||
showDialog(context: context, builder: (context) => SimpleDialog(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.file_open),
|
||||
@ -121,8 +119,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
));
|
||||
},
|
||||
child: Material(
|
||||
elevation: 5,
|
||||
|
@ -40,7 +40,7 @@ class _ChatTileState extends State<ChatTile> {
|
||||
username = value.getString('username')!
|
||||
});
|
||||
|
||||
bool isGroup = widget.data.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
var isGroup = widget.data.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
circleAvatar = UserAvatar(id: isGroup ? widget.data.token : widget.data.name, isGroup: isGroup);
|
||||
}
|
||||
|
||||
@ -56,10 +56,7 @@ class _ChatTileState extends State<ChatTile> {
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Consumer<ChatProps>(builder: (context, chatData, child) {
|
||||
return ListTile(
|
||||
Widget build(BuildContext context) => Consumer<ChatProps>(builder: (context, chatData, child) => ListTile(
|
||||
style: ListTileStyle.list,
|
||||
tileColor: chatData.currentToken() == widget.data.token && TalkNavigator.isSecondaryVisible(context)
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
@ -120,7 +117,7 @@ class _ChatTileState extends State<ChatTile> {
|
||||
),
|
||||
onTap: () async {
|
||||
setCurrentAsRead();
|
||||
ChatView view = ChatView(room: widget.data, selfId: username, avatar: circleAvatar);
|
||||
var view = ChatView(room: widget.data, selfId: username, avatar: circleAvatar);
|
||||
TalkNavigator.pushSplitView(context, view, overrideToSingleSubScreen: true);
|
||||
Provider.of<ChatProps>(context, listen: false).setQueryToken(widget.data.token);
|
||||
},
|
||||
@ -185,7 +182,5 @@ class _ChatTileState extends State<ChatTile> {
|
||||
],
|
||||
));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ class SplitViewPlaceholder extends StatelessWidget {
|
||||
const SplitViewPlaceholder({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(),
|
||||
body: Center(
|
||||
child: Column(
|
||||
@ -25,5 +24,4 @@ class SplitViewPlaceholder extends StatelessWidget {
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ class JoinChat extends SearchDelegate<String> {
|
||||
CancelableOperation<AutocompleteResponse>? future;
|
||||
|
||||
@override
|
||||
List<Widget>? buildActions(BuildContext context) {
|
||||
return [
|
||||
List<Widget>? buildActions(BuildContext context) => [
|
||||
if(future != null && query.isNotEmpty) FutureBuilder(
|
||||
future: future!.value,
|
||||
builder: (context, snapshot) {
|
||||
@ -35,12 +34,9 @@ class JoinChat extends SearchDelegate<String> {
|
||||
),
|
||||
if(query.isNotEmpty) IconButton(onPressed: () => query = '', icon: const Icon(Icons.delete)),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget? buildLeading(BuildContext context) {
|
||||
return null;
|
||||
}
|
||||
Widget? buildLeading(BuildContext context) => null;
|
||||
|
||||
@override
|
||||
Widget buildResults(BuildContext context) {
|
||||
@ -61,8 +57,8 @@ class JoinChat extends SearchDelegate<String> {
|
||||
return ListView.builder(
|
||||
itemCount: snapshot.data!.data.length,
|
||||
itemBuilder: (context, index) {
|
||||
AutocompleteResponseObject object = snapshot.data!.data[index];
|
||||
CircleAvatar circleAvatar = CircleAvatar(
|
||||
var object = snapshot.data!.data[index];
|
||||
var circleAvatar = CircleAvatar(
|
||||
foregroundImage: Image.network('https://${EndpointData().nextcloud().full()}/avatar/${object.id}/128').image,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
foregroundColor: Colors.white,
|
||||
@ -89,8 +85,6 @@ class JoinChat extends SearchDelegate<String> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildSuggestions(BuildContext context) {
|
||||
return buildResults(context);
|
||||
}
|
||||
Widget buildSuggestions(BuildContext context) => buildResults(context);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,7 @@ class _MessageReactionsState extends State<MessageReactions> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Reaktionen'),
|
||||
),
|
||||
@ -42,8 +41,7 @@ class _MessageReactionsState extends State<MessageReactions> {
|
||||
if(snapshot.data == null) return const PlaceholderView(icon: Icons.search_off_outlined, text: 'Keine Reaktionen gefunden!');
|
||||
return ListView(
|
||||
children: [
|
||||
...snapshot.data!.data.entries.map<Widget>((entry) {
|
||||
return ExpansionTile(
|
||||
...snapshot.data!.data.entries.map<Widget>((entry) => ExpansionTile(
|
||||
textColor: Theme.of(context).colorScheme.onSurface,
|
||||
collapsedTextColor: Theme.of(context).colorScheme.onSurface,
|
||||
iconColor: Theme.of(context).colorScheme.onSurface,
|
||||
@ -53,7 +51,7 @@ class _MessageReactionsState extends State<MessageReactions> {
|
||||
leading: CenteredLeading(Text(entry.key)),
|
||||
title: Text('${entry.value.length} mal reagiert'),
|
||||
children: entry.value.map((e) {
|
||||
bool isSelf = AccountData().getUsername() == e.actorId;
|
||||
var isSelf = AccountData().getUsername() == e.actorId;
|
||||
return ListTile(
|
||||
leading: UserAvatar(id: e.actorId, isGroup: false),
|
||||
title: Text(e.actorDisplayName),
|
||||
@ -71,12 +69,10 @@ class _MessageReactionsState extends State<MessageReactions> {
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
})
|
||||
))
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,12 @@ class SearchChat extends SearchDelegate {
|
||||
SearchChat(this.chats);
|
||||
|
||||
@override
|
||||
List<Widget>? buildActions(BuildContext context) {
|
||||
return [
|
||||
List<Widget>? buildActions(BuildContext context) => [
|
||||
if(query.isNotEmpty) IconButton(onPressed: () => query = '', icon: const Icon(Icons.delete)),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget? buildLeading(BuildContext context) {
|
||||
return null;
|
||||
}
|
||||
Widget? buildLeading(BuildContext context) => null;
|
||||
|
||||
@override
|
||||
Widget buildResults(BuildContext context) {
|
||||
@ -35,7 +31,5 @@ class SearchChat extends SearchDelegate {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildSuggestions(BuildContext context) {
|
||||
return buildResults(context);
|
||||
}
|
||||
}
|
||||
Widget buildSuggestions(BuildContext context) => buildResults(context);
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ class TalkNavigator {
|
||||
|
||||
static void pushSplitView(BuildContext context, Widget view, {bool overrideToSingleSubScreen = false}) {
|
||||
if(isSecondaryVisible(context)) {
|
||||
SplitViewState splitView = SplitView.of(context);
|
||||
var splitView = SplitView.of(context);
|
||||
overrideToSingleSubScreen ? splitView.setSecondary(view) : splitView.push(view);
|
||||
} else {
|
||||
pushScreen(context, screen: view, withNavBar: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user