Media viewer details panel, Upload FAB size setting, PDF zoom/viewport fixes, avatar menu account switcher; bump to 1.0.2+5
Build App Bundle / build (push) Successful in 6m2s

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-10-01 18:41:51 -04:00
co-authored by Claude Code
parent 0b7df833f6
commit 4611bc2142
22 changed files with 846 additions and 94 deletions
+15 -4
View File
@@ -101,6 +101,7 @@ class FilesController extends ChangeNotifier
NextcloudUserQuota? _quota;
List<NextcloudActivity> _activities = [];
bool _isLoading = false;
bool _activating = false;
String? _errorMessage;
FilesController(this.session) {
@@ -147,7 +148,10 @@ class FilesController extends ChangeNotifier
CachePolicy get cachePolicy => _cachePolicy;
int get cacheIntervalMinutes => _cacheIntervalMinutes;
@override
bool get isLoading => _isLoading;
// Also true while a freshly activated account is still restoring prefs
// and while the session verifies it, so a switch shows a spinner instead
// of briefly flashing the empty-folder message.
bool get isLoading => _isLoading || _activating || session.isLoading;
@override
String? get errorMessage => _errorMessage;
NextcloudUserQuota? get quota => _quota;
@@ -360,9 +364,16 @@ class FilesController extends ChangeNotifier
}
Future<void> _onAccountActivated() async {
await _restoreDisplayPrefs();
_startCacheRefreshTimerIfNeeded();
await refreshData();
_activating = true;
notifyListeners();
try {
await _restoreDisplayPrefs();
_startCacheRefreshTimerIfNeeded();
await refreshData();
} finally {
_activating = false;
notifyListeners();
}
}
@override
+17 -3
View File
@@ -168,9 +168,9 @@ class ItemOperations {
(c) => choices[c.item.id] == ConflictChoice.keepBoth,
);
final existingNames = needsKeepBoth
? (await files.fetchFolderListing(destFolderPath))
.map((i) => i.name)
.toSet()
? (await files.fetchFolderListing(
destFolderPath,
)).map((i) => i.name).toSet()
: <String>{};
var succeeded = 0;
@@ -303,6 +303,20 @@ class ItemOperations {
}
}
Future<bool> updateSharePermissions(
NextcloudShare share,
int permissions,
) async {
final service = session.service;
if (service == null) return false;
try {
return await service.updateSharePermissions(share.id, permissions);
} catch (e) {
debugPrint('[ItemOperations] updateSharePermissions failed: $e');
return false;
}
}
/// Deletes a share (from the file-details/Share sheet, not the Shares
/// tab itself - see `SharesController.deleteShare` for that one, which
/// additionally patches the tab's own list).
+23
View File
@@ -9,6 +9,11 @@ import '../widgets/noo/nav/noo_nav_style.dart';
/// in Settings.
enum SwipeAction { none, favorite, delete, share }
/// How the Android Upload FAB is sized: [auto] expands on Files/Photos and
/// shrinks to an icon elsewhere, [mini] is always icon-only, [expanded]
/// always shows the label.
enum FabStyle { auto, mini, expanded }
/// Thumb/track presets for the video player's seek bar, matching the four
/// combinations offered by other Material You media players: a Material 3
/// slider-style thumb ([classic]), an animated travelling wave with a round
@@ -31,6 +36,7 @@ class SettingsController extends ChangeNotifier {
static const _prefDefaultTab = 'ui_default_tab';
static const _prefSwipeLeftAction = 'ui_swipe_left_action';
static const _prefSwipeRightAction = 'ui_swipe_right_action';
static const _prefFabStyle = 'ui_fab_style';
static const _prefBottomBarStyle = 'ui_bottom_bar_style';
static const _prefNavMenuStyle = 'ui_nav_menu_style';
static const _prefSearchInBottomBar = 'ui_search_in_bottom_bar';
@@ -61,6 +67,7 @@ class SettingsController extends ChangeNotifier {
SwipeAction _swipeLeftAction = SwipeAction.delete;
SwipeAction _swipeRightAction = SwipeAction.favorite;
FabStyle _fabStyle = FabStyle.auto;
// A one-shot request for the shell to switch its active bottom-nav tab
// (e.g. a search result landing on Files) - consumed and cleared by
@@ -121,6 +128,7 @@ class SettingsController extends ChangeNotifier {
SwipeAction get swipeLeftAction => _swipeLeftAction;
SwipeAction get swipeRightAction => _swipeRightAction;
FabStyle get fabStyle => _fabStyle;
Future<void> _load() async {
try {
@@ -242,6 +250,14 @@ class SettingsController extends ChangeNotifier {
);
}
final fabName = prefs.getString(_prefFabStyle);
if (fabName != null) {
_fabStyle = FabStyle.values.firstWhere(
(f) => f.name == fabName,
orElse: () => _fabStyle,
);
}
notifyListeners();
} catch (e) {
debugPrint('[SettingsController] Preference restore failed: $e');
@@ -404,4 +420,11 @@ class SettingsController extends ChangeNotifier {
notifyListeners();
_prefsFuture.then((p) => p.setString(_prefSwipeRightAction, action.name));
}
void setFabStyle(FabStyle style) {
if (_fabStyle == style) return;
_fabStyle = style;
notifyListeners();
_prefsFuture.then((p) => p.setString(_prefFabStyle, style.name));
}
}