fluffychat merge

This commit is contained in:
ggurdin 2026-02-05 16:18:09 -05:00
commit b627eaaab2
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
13 changed files with 67 additions and 165 deletions

View file

@ -1,2 +1,2 @@
FLUTTER_VERSION=3.38.3
FLUTTER_VERSION=3.38.4
JAVA_VERSION=17

View file

@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
import 'package:collection/collection.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:file_picker/file_picker.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:just_audio/just_audio.dart';
@ -338,9 +339,14 @@ class ChatController extends State<ChatPageWithRoom>
final timeline = this.timeline;
if (timeline == null) return;
Logs().v('Requesting future...');
final mostRecentEventId = timeline.events.first.eventId;
final mostRecentEvent = timeline.events.filterByVisibleInGui().firstOrNull;
await timeline.requestFuture(historyCount: _loadHistoryCount);
setReadMarker(eventId: mostRecentEventId);
if (mostRecentEvent != null) {
setReadMarker(eventId: mostRecentEvent.eventId);
}
}
void _updateScrollController() {
@ -357,11 +363,6 @@ class ChatController extends State<ChatPageWithRoom>
// setReadMarker();
// }
// Pangea#
if (scrollController.position.pixels == 0 ||
scrollController.position.pixels == 64) {
requestFuture();
}
}
void _loadDraft() async {
@ -679,7 +680,7 @@ class ChatController extends State<ChatPageWithRoom>
void onInsert(int i) {
// setState will be called by updateView() anyway
animateInEventIndex = i;
if (i <= 5) animateInEventIndex = i;
}
// #Pangea
@ -1099,7 +1100,7 @@ class ChatController extends State<ChatPageWithRoom>
// Pangea#
}
void sendFileAction({FileSelectorType type = FileSelectorType.any}) async {
void sendFileAction({FileType type = FileType.any}) async {
final files = await selectFiles(context, allowMultiple: true, type: type);
if (files.isEmpty) return;
await showAdaptiveDialog(
@ -1811,10 +1812,10 @@ class ChatController extends State<ChatPageWithRoom>
switch (choice) {
case AddPopupMenuActions.image:
sendFileAction(type: FileSelectorType.images);
sendFileAction(type: FileType.image);
return;
case AddPopupMenuActions.video:
sendFileAction(type: FileSelectorType.videos);
sendFileAction(type: FileType.video);
return;
case AddPopupMenuActions.file:
sendFileAction();

View file

@ -5,6 +5,7 @@ import 'package:collection/collection.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/events/message.dart';
import 'package:fluffychat/pages/chat/seen_by_row.dart';
@ -76,16 +77,16 @@ class ChatEventList extends StatelessWidget {
(BuildContext context, int i) {
// Footer to display typing indicator and read receipts:
if (i == 0) {
if (timeline.isRequestingFuture) {
return const Center(
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
);
}
if (timeline.canRequestFuture) {
return Center(
child: IconButton(
onPressed: controller.requestFuture,
icon: const Icon(Icons.refresh_outlined),
child: TextButton.icon(
onPressed: timeline.isRequestingFuture
? null
: controller.requestFuture,
icon: timeline.isRequestingFuture
? CircularProgressIndicator.adaptive(strokeWidth: 2)
: const Icon(Icons.arrow_downward_outlined),
label: Text(L10n.of(context).loadMore),
),
);
}
@ -125,16 +126,14 @@ class ChatEventList extends StatelessWidget {
}
}
return Center(
child: AnimatedSwitcher(
duration: FluffyThemes.animationDuration,
child: timeline.canRequestHistory
? IconButton(
onPressed: controller.requestHistory,
icon: const Icon(Icons.refresh_outlined),
)
: const CircularProgressIndicator.adaptive(
strokeWidth: 2,
),
child: TextButton.icon(
onPressed: timeline.isRequestingHistory
? null
: controller.requestHistory,
icon: timeline.isRequestingHistory
? CircularProgressIndicator.adaptive(strokeWidth: 2)
: const Icon(Icons.arrow_upward_outlined),
label: Text(L10n.of(context).loadMore),
),
);
},

View file

@ -368,8 +368,6 @@ class ChatView extends StatelessWidget {
),
),
// #Pangea
// floatingActionButtonLocation:
// FloatingActionButtonLocation.miniCenterFloat,
// floatingActionButton:
// controller.showScrollDownButton &&
// controller.selectedEvents.isEmpty

View file

@ -1146,22 +1146,27 @@ class MatrixPill extends StatelessWidget {
],
),
),
// child: Row(
// mainAxisSize: .min,
// children: [
// Avatar(mxContent: avatar, name: name, size: 16),
// const SizedBox(width: 6),
// Text(
// name,
// style: TextStyle(
// color: color,
// decorationColor: color,
// decoration: TextDecoration.underline,
// fontSize: fontSize,
// height: 1.25,
// child: Text.rich(
// TextSpan(
// children: [
// WidgetSpan(
// child: Padding(
// padding: const EdgeInsets.only(right: 4.0),
// child: Avatar(mxContent: avatar, name: name, size: 16),
// ),
// ),
// ),
// ],
// TextSpan(
// text: name,
// style: TextStyle(
// color: color,
// decorationColor: color,
// decoration: TextDecoration.underline,
// fontSize: fontSize,
// height: 1.25,
// ),
// ),
// ],
// ),
// ),
// Pangea#
);

View file

@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
@ -215,7 +216,7 @@ class ChatDetailsController extends State<ChatDetails>
final picked = await selectFiles(
context,
allowMultiple: false,
type: FileSelectorType.images,
type: FileType.image,
);
final pickedFile = picked.firstOrNull;
if (pickedFile == null) return;

View file

@ -2,6 +2,7 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
@ -49,7 +50,7 @@ class NewGroupController extends State<NewGroup> {
void selectPhoto() async {
final photo = await selectFiles(
context,
type: FileSelectorType.images,
type: FileType.image,
allowMultiple: false,
);
final bytes = await photo.singleOrNull?.readAsBytes();

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
@ -134,7 +135,7 @@ class SettingsController extends State<Settings> {
if (result == null) return;
file = MatrixFile(bytes: await result.readAsBytes(), name: result.path);
} else {
final result = await selectFiles(context, type: FileSelectorType.images);
final result = await selectFiles(context, type: FileType.image);
final pickedFile = result.firstOrNull;
if (pickedFile == null) return;
file = MatrixFile(

View file

@ -4,6 +4,7 @@ import 'package:archive/archive.dart'
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:http/http.dart' hide Client;
import 'package:matrix/matrix.dart';
@ -294,7 +295,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
void createStickers() async {
final pickedFiles = await selectFiles(
context,
type: FileSelectorType.images,
type: FileType.image,
allowMultiple: true,
);
if (pickedFiles.isEmpty) return;
@ -353,7 +354,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
}
Future<void> importEmojiZip() async {
final result = await selectFiles(context, type: FileSelectorType.zip);
final result = await selectFiles(context, type: FileType.any);
if (result.isEmpty) return;

View file

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/account_config.dart';
@ -26,7 +28,7 @@ class SettingsStyleController extends State<SettingsStyle> {
void setWallpaper() async {
final client = Matrix.of(context).client;
final picked = await selectFiles(context, type: FileSelectorType.images);
final picked = await selectFiles(context, type: FileType.image);
final pickedFile = picked.firstOrNull;
if (pickedFile == null) return;

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
@ -150,7 +151,7 @@ class EditCourseController extends State<EditCourse> {
final picked = await selectFiles(
context,
allowMultiple: false,
type: FileSelectorType.images,
type: FileType.image,
);
final pickedFile = picked.firstOrNull;
if (pickedFile == null) return;

View file

@ -9,7 +9,7 @@ import 'package:fluffychat/widgets/future_loading_dialog.dart';
Future<List<XFile>> selectFiles(
BuildContext context, {
String? title,
FileSelectorType type = FileSelectorType.any,
FileType type = FileType.any,
bool allowMultiple = false,
}) async {
final result = await AppLock.of(context).pauseWhile(
@ -18,117 +18,9 @@ Future<List<XFile>> selectFiles(
future: () => FilePicker.platform.pickFiles(
compressionQuality: 0,
allowMultiple: allowMultiple,
type: type.filePickerType,
allowedExtensions: type.extensions,
type: type,
),
),
);
return result.result?.xFiles ?? [];
}
enum FileSelectorType {
any([], FileType.any, null),
images(
[
XTypeGroup(
label: 'Images',
extensions: <String>[
'jpg',
'JPG',
'jpeg',
'JPEG',
'png',
'PNG',
'webp',
'WebP',
'WEBP',
'gif',
'GIF',
'bmp',
'BMP',
'tiff',
'TIFF',
'tif',
'TIF',
'heic',
'HEIC',
'svg',
'SVG',
],
),
XTypeGroup(
label: 'JPG',
extensions: <String>['jpg', 'JPG', 'jpeg', 'JPEG'],
),
XTypeGroup(label: 'PNG', extensions: <String>['png', 'PNG']),
XTypeGroup(label: 'WebP', extensions: <String>['webp', 'WebP', 'WEBP']),
XTypeGroup(label: 'GIF', extensions: <String>['gif', 'GIF']),
XTypeGroup(label: 'BMP', extensions: <String>['bmp', 'BMP']),
XTypeGroup(
label: 'TIFF',
extensions: <String>['tiff', 'TIFF', 'tif', 'TIF'],
),
XTypeGroup(label: 'HEIC', extensions: <String>['heic', 'HEIC']),
XTypeGroup(label: 'SVG', extensions: <String>['svg', 'SVG']),
],
FileType.image,
null,
),
videos(
[
XTypeGroup(
label: 'Videos',
extensions: <String>[
'mp4',
'MP4',
'avi',
'AVI',
'webm',
'WebM',
'WEBM',
'mov',
'MOV',
'mkv',
'MKV',
'wmv',
'WMV',
'flv',
'FLV',
'mpeg',
'MPEG',
'3gp',
'3GP',
'ogg',
'OGG',
],
),
XTypeGroup(label: 'MP4', extensions: <String>['mp4', 'MP4']),
XTypeGroup(label: 'WebM', extensions: <String>['webm', 'WebM', 'WEBM']),
XTypeGroup(label: 'AVI', extensions: <String>['avi', 'AVI']),
XTypeGroup(label: 'MOV', extensions: <String>['mov', 'MOV']),
XTypeGroup(label: 'MKV', extensions: <String>['mkv', 'MKV']),
XTypeGroup(label: 'WMV', extensions: <String>['wmv', 'WMV']),
XTypeGroup(label: 'FLV', extensions: <String>['flv', 'FLV']),
XTypeGroup(label: 'MPEG', extensions: <String>['mpeg', 'MPEG']),
XTypeGroup(label: '3GP', extensions: <String>['3gp', '3GP']),
XTypeGroup(label: 'OGG', extensions: <String>['ogg', 'OGG']),
],
FileType.video,
null,
),
zip(
[
XTypeGroup(label: 'ZIP', extensions: <String>['zip', 'ZIP']),
],
FileType.custom,
['zip', 'ZIP'],
),
// #Pangea
media([], FileType.media, null);
// Pangea#
const FileSelectorType(this.groups, this.filePickerType, this.extensions);
final List<XTypeGroup> groups;
final FileType filePickerType;
final List<String>? extensions;
}

View file

@ -53,7 +53,7 @@ platforms:
parts:
flutter-git:
source: https://github.com/flutter/flutter.git
source-tag: 3.38.1
source-tag: 3.38.4
source-depth: 1
plugin: nil
override-build: |