Merge branch 'main' into fluffychat-merge
This commit is contained in:
commit
a00c8bca8b
16 changed files with 121 additions and 79 deletions
|
|
@ -46,6 +46,7 @@ import '../../widgets/matrix.dart';
|
|||
import 'package:fluffychat/utils/tor_stub.dart'
|
||||
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
|
||||
|
||||
|
||||
enum PopupMenuAction {
|
||||
settings,
|
||||
invite,
|
||||
|
|
@ -587,7 +588,6 @@ class ChatListController extends State<ChatList>
|
|||
if (space != null) {
|
||||
chatListHandleSpaceTap(
|
||||
context,
|
||||
this,
|
||||
space,
|
||||
);
|
||||
}
|
||||
|
|
@ -669,6 +669,10 @@ class ChatListController extends State<ChatList>
|
|||
|
||||
_activeSpaceId =
|
||||
widget.activeSpaceId == 'clear' ? null : widget.activeSpaceId;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_joinInvitedSpaces();
|
||||
});
|
||||
// Pangea#
|
||||
|
||||
super.initState();
|
||||
|
|
@ -685,6 +689,16 @@ class ChatListController extends State<ChatList>
|
|||
: setActiveSpace(widget.activeSpaceId!);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _joinInvitedSpaces() async {
|
||||
final invitedSpaces = Matrix.of(context).client.rooms.where(
|
||||
(r) => r.isSpace && r.membership == Membership.invite,
|
||||
);
|
||||
|
||||
for (final space in invitedSpaces) {
|
||||
await showInviteDialog(space, context);
|
||||
}
|
||||
}
|
||||
// Pangea#
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -87,7 +87,14 @@ class SettingsView extends StatelessWidget {
|
|||
return Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(32.0),
|
||||
// #Pangea
|
||||
// padding: const EdgeInsets.all(32.0),
|
||||
padding: const EdgeInsets.only(
|
||||
top: 32.0,
|
||||
bottom: 32.0,
|
||||
left: 12.0,
|
||||
),
|
||||
// Pangea#
|
||||
child: Stack(
|
||||
children: [
|
||||
Avatar(
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@ import 'package:flutter/material.dart';
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import '../../common/utils/error_handler.dart';
|
||||
|
||||
Future<void> _showInviteDialog(Room room, BuildContext context) async {
|
||||
Future<void> showInviteDialog(Room room, BuildContext context) async {
|
||||
if (room.membership != Membership.invite) return;
|
||||
final acceptInvite = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).youreInvited,
|
||||
|
|
@ -23,7 +22,7 @@ Future<void> _showInviteDialog(Room room, BuildContext context) async {
|
|||
cancelLabel: L10n.of(context).decline,
|
||||
);
|
||||
|
||||
await showFutureLoadingDialog(
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
if (acceptInvite == OkCancelResult.ok) {
|
||||
|
|
@ -31,28 +30,24 @@ Future<void> _showInviteDialog(Room room, BuildContext context) async {
|
|||
context.go(
|
||||
room.isSpace ? "/rooms?spaceId=${room.id}" : "/rooms/${room.id}",
|
||||
);
|
||||
return;
|
||||
return room.id;
|
||||
}
|
||||
await room.leave();
|
||||
},
|
||||
);
|
||||
|
||||
if (!resp.isError && resp.result is String) {
|
||||
context.go("/rooms?spaceId=${resp.result}");
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: curly_braces_in_flow_control_structures
|
||||
void chatListHandleSpaceTap(
|
||||
BuildContext context,
|
||||
ChatListController controller,
|
||||
Room space,
|
||||
) {
|
||||
void setActiveSpaceAndCloseChat() {
|
||||
controller.setActiveSpace(space.id);
|
||||
|
||||
if (FluffyThemes.isColumnMode(context)) {
|
||||
context.go('/rooms/${space.id}');
|
||||
} else if (controller.activeChat != null &&
|
||||
!space.isFirstOrSecondChild(controller.activeChat!)) {
|
||||
context.go("/rooms");
|
||||
}
|
||||
context.go("/rooms?spaceId=${space.id}");
|
||||
}
|
||||
|
||||
void autoJoin(Room space) {
|
||||
|
|
@ -85,7 +80,7 @@ void chatListHandleSpaceTap(
|
|||
justInputtedCode == space.classCode) {
|
||||
// do nothing
|
||||
} else {
|
||||
_showInviteDialog(space, context);
|
||||
showInviteDialog(space, context);
|
||||
}
|
||||
break;
|
||||
case Membership.leave:
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class DeleteSpaceDialogState extends State<DeleteSpaceDialog> {
|
|||
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
Flexible(
|
||||
child: SingleChildScrollView(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
|
|
|
|||
|
|
@ -396,7 +396,15 @@ class PangeaMessageEvent {
|
|||
),
|
||||
);
|
||||
}
|
||||
_representations!.add(sent);
|
||||
|
||||
// If originalSent has no tokens, there is not way to generate a tokens event
|
||||
// and send it as a related event, since original sent has not eventID to set
|
||||
// as parentEventId. In this case, it's better to generate a new representation
|
||||
// with an eventID and send the related tokens event to that representation.
|
||||
// This is a rare situation, and has only been seen with some bot messages.
|
||||
if (sent.tokens != null) {
|
||||
_representations!.add(sent);
|
||||
}
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(
|
||||
m: "error parsing originalSent",
|
||||
|
|
|
|||
16
lib/pangea/extensions/pangea_rooms_chunk_extension.dart
Normal file
16
lib/pangea/extensions/pangea_rooms_chunk_extension.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:matrix/matrix_api_lite/generated/model.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
|
||||
|
||||
extension PangeaRoomsChunk on PublicRoomsChunk {
|
||||
/// Use Random with a seed to get the default
|
||||
/// avatar associated with this space
|
||||
String defaultAvatar() {
|
||||
final int seed = roomId.hashCode;
|
||||
return SpaceConstants.publicSpaceIcons[Random(seed).nextInt(
|
||||
SpaceConstants.publicSpaceIcons.length,
|
||||
)];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/analytics_summary/learning_progress_indicator_button.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_rooms_chunk_extension.dart';
|
||||
import 'package:fluffychat/pangea/public_spaces/public_room_bottom_sheet.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
|
||||
|
|
@ -35,14 +37,26 @@ class PublicSpaceTile extends StatelessWidget {
|
|||
height: isColumnMode ? 80.0 : 58.0,
|
||||
child: Row(
|
||||
children: [
|
||||
Avatar(
|
||||
mxContent: space.avatarUrl,
|
||||
name: space.name,
|
||||
size: isColumnMode ? 80.0 : 58.0,
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
),
|
||||
(space.avatarUrl != null)
|
||||
? Avatar(
|
||||
mxContent: space.avatarUrl,
|
||||
name: space.name,
|
||||
size: isColumnMode ? 80.0 : 58.0,
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
)
|
||||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: space.defaultAvatar(),
|
||||
width: isColumnMode ? 80.0 : 58.0,
|
||||
height: isColumnMode ? 80.0 : 58.0,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
context: context,
|
||||
future: () async => pangeaController.userController.updateProfile(
|
||||
(_) => _profile,
|
||||
waitForDataInSync: true,
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
|
|
|
|||
|
|
@ -80,17 +80,16 @@ class OnboardingController extends State<Onboarding> {
|
|||
Future<void> startChatWithBot() async {
|
||||
final resp = await showFutureLoadingDialog<String>(
|
||||
context: context,
|
||||
future: () => Matrix.of(context).client.createRoom(
|
||||
invite: [BotName.byEnvironment],
|
||||
isDirect: true,
|
||||
preset: CreateRoomPreset.trustedPrivateChat,
|
||||
initialState: [
|
||||
BotOptionsModel(mode: BotMode.directChat).toStateEvent,
|
||||
RoomDefaults.defaultPowerLevels(
|
||||
Matrix.of(context).client.userID!,
|
||||
),
|
||||
],
|
||||
future: () => Matrix.of(context).client.startDirectChat(
|
||||
BotName.byEnvironment,
|
||||
preset: CreateRoomPreset.trustedPrivateChat,
|
||||
initialState: [
|
||||
BotOptionsModel(mode: BotMode.directChat).toStateEvent,
|
||||
RoomDefaults.defaultPowerLevels(
|
||||
Matrix.of(context).client.userID!,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (resp.isError) return;
|
||||
context.go("/rooms/${resp.result}");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
|
@ -9,7 +7,7 @@ import 'package:matrix/matrix.dart';
|
|||
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/common/config/environment.dart';
|
||||
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_rooms_chunk_extension.dart';
|
||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
|
|
@ -212,10 +210,7 @@ class PublicRoomBottomSheetState extends State<PublicRoomBottomSheet> {
|
|||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: SpaceConstants
|
||||
.publicSpaceIcons[Random().nextInt(
|
||||
SpaceConstants.publicSpaceIcons.length,
|
||||
)],
|
||||
imageUrl: chunk!.defaultAvatar(),
|
||||
width: 160.0,
|
||||
height: 160.0,
|
||||
fit: BoxFit.cover,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
|
@ -7,8 +5,8 @@ import 'package:matrix/matrix.dart';
|
|||
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_rooms_chunk_extension.dart';
|
||||
import 'package:fluffychat/pangea/public_spaces/public_room_bottom_sheet.dart';
|
||||
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
|
||||
import 'package:fluffychat/widgets/mxc_image.dart';
|
||||
|
||||
class PublicSpaceCard extends StatelessWidget {
|
||||
|
|
@ -71,10 +69,7 @@ class PublicSpaceCard extends StatelessWidget {
|
|||
fit: BoxFit.cover,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
imageUrl: SpaceConstants
|
||||
.publicSpaceIcons[Random().nextInt(
|
||||
SpaceConstants.publicSpaceIcons.length,
|
||||
)],
|
||||
imageUrl: space.defaultAvatar(),
|
||||
width: width,
|
||||
height: width,
|
||||
fit: BoxFit.cover,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class SubscriptionController extends BaseController {
|
|||
final bool hasSubscription =
|
||||
currentSubscriptionInfo?.currentSubscriptionId != null;
|
||||
|
||||
return hasSubscription;
|
||||
return hasSubscription || _userController.inTrialWindow();
|
||||
}
|
||||
|
||||
bool _isInitializing = false;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dar
|
|||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_representation_event.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_response.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_activity_model.dart';
|
||||
|
|
@ -135,7 +133,11 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
|
||||
RepresentationEvent? repEvent =
|
||||
pangeaMessageEvent?.messageDisplayRepresentation;
|
||||
repEvent ??= await _fetchNewRepEvent();
|
||||
|
||||
if (repEvent == null ||
|
||||
(repEvent.event == null && repEvent.tokens == null)) {
|
||||
repEvent = await _fetchNewRepEvent();
|
||||
}
|
||||
|
||||
if (repEvent?.event != null) {
|
||||
await repEvent!.sendTokensEvent(
|
||||
|
|
@ -145,24 +147,6 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
MatrixState.pangeaController.languageController.userL2!.langCode,
|
||||
);
|
||||
}
|
||||
// If repEvent is originalSent but it's missing tokens, then fetch tokens.
|
||||
// An edge case, but has happened with some bot message.
|
||||
else if (repEvent != null &&
|
||||
repEvent.tokens == null &&
|
||||
repEvent.content.originalSent) {
|
||||
final tokens = await repEvent.tokensGlobal(
|
||||
pangeaMessageEvent!.senderId,
|
||||
pangeaMessageEvent!.event.originServerTs,
|
||||
);
|
||||
await pangeaMessageEvent!.room.pangeaSendTextEvent(
|
||||
pangeaMessageEvent!.messageDisplayText,
|
||||
editEventId: pangeaMessageEvent!.eventId,
|
||||
originalSent: pangeaMessageEvent!.originalSent?.content,
|
||||
originalWritten: pangeaMessageEvent!.originalWritten?.content,
|
||||
tokensSent: PangeaMessageTokens(tokens: tokens),
|
||||
choreo: pangeaMessageEvent!.originalSent?.choreo,
|
||||
);
|
||||
}
|
||||
|
||||
// Get all the lemma infos
|
||||
final messageVocabConstructIds = pangeaMessageEvent!
|
||||
|
|
|
|||
|
|
@ -70,9 +70,11 @@ class OverlayCenterContent extends StatelessWidget {
|
|||
MeasureRenderBox(
|
||||
onChange: onChangeMessageSize,
|
||||
child: OverlayMessage(
|
||||
key: MatrixState.pAnyState
|
||||
.layerLinkAndKey('overlay_message_${event.eventId}')
|
||||
.key,
|
||||
key: isTransitionAnimation
|
||||
? MatrixState.pAnyState
|
||||
.layerLinkAndKey('overlay_message_${event.eventId}')
|
||||
.key
|
||||
: null,
|
||||
event,
|
||||
pangeaMessageEvent: pangeaMessageEvent,
|
||||
immersionMode: chatController.choreographer.immersionMode,
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ class SelectModeButtonsState extends State<SelectModeButtons> {
|
|||
matrix?.audioPlayer?.dispose();
|
||||
matrix?.audioPlayer = AudioPlayer();
|
||||
matrix?.voiceMessageEventId.value =
|
||||
widget.overlayController.pangeaMessageEvent?.eventId;
|
||||
"${widget.overlayController.pangeaMessageEvent?.eventId}_button";
|
||||
|
||||
_onPlayerStateChanged =
|
||||
matrix?.audioPlayer?.playerStateStream.listen((state) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:fluffychat/config/app_config.dart';
|
|||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pages/chat_list/navi_rail_item.dart';
|
||||
import 'package:fluffychat/pangea/chat_list/utils/chat_list_handle_space_tap.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:fluffychat/utils/stream_extension.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
|
|
@ -175,7 +176,20 @@ class SpacesNavigationRail extends StatelessWidget {
|
|||
return NaviRailItem(
|
||||
toolTip: displayname,
|
||||
isSelected: activeSpaceId == space.id,
|
||||
onTap: () => onGoToSpaceId(rootSpaces[i].id),
|
||||
// #Pangea
|
||||
// onTap: () => onGoToSpaceId(rootSpaces[i].id),
|
||||
onTap: () {
|
||||
final room = client.getRoomById(rootSpaces[i].id);
|
||||
if (room != null) {
|
||||
chatListHandleSpaceTap(
|
||||
context,
|
||||
room,
|
||||
);
|
||||
} else {
|
||||
onGoToSpaceId(rootSpaces[i].id);
|
||||
}
|
||||
},
|
||||
// Pangea#
|
||||
unreadBadgeFilter: (room) =>
|
||||
spaceChildrenIds.contains(room.id),
|
||||
icon: Avatar(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue