feat(service): First attempt at handling phone contacts
This commit is contained in:
@@ -121,7 +121,8 @@ class ConversationBloc extends Bloc<ConversationEvent, ConversationState> {
|
||||
state: s.toString().split('.').last,
|
||||
jid: state.conversation!.jid,
|
||||
),
|
||||
awaitable: false,);
|
||||
awaitable: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onInit(InitConversationEvent event, Emitter<ConversationState> emit) async {
|
||||
|
||||
@@ -15,6 +15,9 @@ import 'package:moxxyv2/ui/widgets/avatar.dart';
|
||||
import 'package:moxxyv2/ui/widgets/conversation.dart';
|
||||
import 'package:moxxyv2/ui/widgets/overview_menu.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:moxplatform/moxplatform.dart';
|
||||
import 'package:moxxyv2/shared/commands.dart';
|
||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||
|
||||
enum ConversationsOptions {
|
||||
settings
|
||||
@@ -127,6 +130,7 @@ class ConversationsPageState extends State<ConversationsPage> with TickerProvide
|
||||
itemCount: state.conversations.length,
|
||||
itemBuilder: (_context, index) {
|
||||
final item = state.conversations[index];
|
||||
print('${item.jid} -> ${item.contactId}');
|
||||
final row = ConversationsListRow(
|
||||
maxTextWidth,
|
||||
item,
|
||||
@@ -295,7 +299,16 @@ class ConversationsPageState extends State<ConversationsPage> with TickerProvide
|
||||
children: [
|
||||
SpeedDialChild(
|
||||
child: const Icon(Icons.group),
|
||||
onTap: () => showNotImplementedDialog('groupchat', context),
|
||||
onTap: () async {
|
||||
final r = await FlutterContacts.requestPermission(readonly: true);
|
||||
print(r);
|
||||
if (!r) return;
|
||||
|
||||
await MoxplatformPlugin.handler.getDataSender().sendData(
|
||||
GetContactsCommandDebug(),
|
||||
awaitable: false,
|
||||
);
|
||||
},
|
||||
backgroundColor: primaryColor,
|
||||
// TODO(Unknown): Theme dependent?
|
||||
foregroundColor: Colors.white,
|
||||
|
||||
@@ -124,6 +124,7 @@ class NewConversationPage extends StatelessWidget {
|
||||
false,
|
||||
false,
|
||||
ChatState.gone,
|
||||
contactId: item.contactId,
|
||||
),
|
||||
false,
|
||||
showTimestamp: false,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:moxxyv2/i18n/strings.g.dart';
|
||||
import 'package:moxxyv2/shared/constants.dart';
|
||||
@@ -22,6 +24,7 @@ class ConversationsListRow extends StatefulWidget {
|
||||
this.showLock = false,
|
||||
this.extra,
|
||||
this.avatarOnTap,
|
||||
this.avatarWidget,
|
||||
super.key,
|
||||
}
|
||||
);
|
||||
@@ -31,6 +34,7 @@ class ConversationsListRow extends StatefulWidget {
|
||||
final bool showLock;
|
||||
final bool showTimestamp;
|
||||
final void Function()? avatarOnTap;
|
||||
final Widget? avatarWidget;
|
||||
final Widget? extra;
|
||||
|
||||
@override
|
||||
@@ -83,12 +87,17 @@ class ConversationsListRowState extends State<ConversationsListRow> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget _buildAvatar() {
|
||||
final avatar = AvatarWrapper(
|
||||
radius: 35,
|
||||
avatarUrl: widget.conversation.avatarUrl,
|
||||
altText: widget.conversation.title,
|
||||
);
|
||||
Widget _buildAvatar(Uint8List? data) {
|
||||
final avatar = data != null ?
|
||||
CircleAvatar(
|
||||
radius: 35,
|
||||
backgroundImage: MemoryImage(data),
|
||||
) :
|
||||
AvatarWrapper(
|
||||
radius: 35,
|
||||
avatarUrl: widget.conversation.avatarUrl,
|
||||
altText: widget.conversation.title,
|
||||
);
|
||||
|
||||
if (widget.avatarOnTap != null) {
|
||||
return InkWell(
|
||||
@@ -191,9 +200,8 @@ class ConversationsListRowState extends State<ConversationsListRow> {
|
||||
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
Widget _build(String title, Uint8List? avatar) {
|
||||
final badgeText = widget.conversation.unreadCounter > 99 ?
|
||||
'99+' :
|
||||
widget.conversation.unreadCounter.toString();
|
||||
@@ -205,11 +213,12 @@ class ConversationsListRowState extends State<ConversationsListRow> {
|
||||
final sentBySelf = widget.conversation.lastMessage?.sender == GetIt.I.get<UIDataService>().ownJid!;
|
||||
|
||||
final showBadge = widget.conversation.unreadCounter > 0 && !sentBySelf;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Row(
|
||||
children: [
|
||||
_buildAvatar(),
|
||||
_buildAvatar(avatar),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: LimitedBox(
|
||||
@@ -221,7 +230,7 @@ class ConversationsListRowState extends State<ConversationsListRow> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
widget.conversation.title,
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 17,
|
||||
@@ -294,4 +303,27 @@ class ConversationsListRowState extends State<ConversationsListRow> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.conversation.contactId != null) {
|
||||
return FutureBuilder<Contact?>(
|
||||
future: FlutterContacts.getContact(widget.conversation.contactId!, withThumbnail: true),
|
||||
builder: (_, snapshot) {
|
||||
final hasData = snapshot.hasData && snapshot.data != null;
|
||||
|
||||
if (hasData) {
|
||||
return _build(
|
||||
'${snapshot.data!.name.first} ${snapshot.data!.name.last}',
|
||||
snapshot.data!.thumbnail,
|
||||
);
|
||||
}
|
||||
|
||||
return _build(widget.conversation.title, null);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return _build(widget.conversation.title, null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user