implemented a comprehensive client-side demo mode triggered by a "demo@" username prefix, serving curated fixture data for all app modules

This commit is contained in:
2026-07-07 20:24:16 +02:00
parent 2668b111f1
commit 9b74c9fd81
45 changed files with 1409 additions and 43 deletions
@@ -11,6 +11,7 @@ import '../../../../state/app/modules/nextcloud_capabilities/bloc/nextcloud_capa
import '../../../../utils/clipboard_helper.dart';
import '../../../../widget/centered_leading.dart';
import '../../../../widget/confirm_dialog.dart';
import '../../../../widget/demo_restricted.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/info_dialog.dart';
import 'share_password_sheet.dart';
@@ -35,6 +36,7 @@ void showShareOptionsSheet(
Share share, {
required VoidCallback onChanged,
}) {
if (guardDemoAction(context)) return;
showDetailsBottomSheet(
context,
header: ListTile(
@@ -13,6 +13,7 @@ import '../../../../state/app/modules/nextcloud_capabilities/bloc/nextcloud_capa
import '../../../../utils/clipboard_helper.dart';
import '../../../../widget/app_progress_indicator.dart';
import '../../../../widget/centered_leading.dart';
import '../../../../widget/demo_restricted.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/info_dialog.dart';
import '../widgets/file_leading.dart';
@@ -23,6 +24,7 @@ import 'share_password_sheet.dart';
/// gated actions to create new ones (public link, user/group). Capability
/// gating mirrors the Nextcloud web UI.
void showShareSheet(BuildContext context, CacheableFile file) {
if (guardDemoAction(context)) return;
showDetailsBottomSheet(
context,
header: ListTile(
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../../../state/app/modules/files/bloc/files_bloc.dart';
import '../../../../widget/async_action_button.dart';
import '../../../../widget/demo_restricted.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/file_pick.dart';
@@ -13,6 +14,7 @@ void showAddFileSheet(
required FilesBloc bloc,
required Future<void> Function(List<String>? paths) onPickedFiles,
}) {
if (guardDemoAction(context)) return;
showDetailsBottomSheet(
context,
children: (sheetCtx) => [
@@ -15,6 +15,7 @@ import '../../../../utils/file_clipboard.dart';
import '../../../../utils/haptics.dart';
import '../../../../widget/centered_leading.dart';
import '../../../../widget/confirm_dialog.dart';
import '../../../../widget/demo_restricted.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/downloads/download_trigger.dart';
import '../../../../widget/info_dialog.dart';
@@ -105,6 +106,7 @@ class _FileElementState extends State<FileElement>
);
return;
}
if (guardDemoAction(context)) return;
if (EndpointData().getEndpointMode() == EndpointMode.stage) {
InfoDialog.show(
context,
@@ -135,6 +137,7 @@ class _FileElementState extends State<FileElement>
isDirectory ? '$folder$name/' : '$folder$name';
Future<void> _rename() async {
if (guardDemoAction(context)) return;
final controller = TextEditingController(text: widget.file.name);
try {
final newName = await showDialog<String>(
@@ -182,6 +185,7 @@ class _FileElementState extends State<FileElement>
}
void _putOnClipboard({required bool copy}) {
if (guardDemoAction(context)) return;
if (copy) {
FileClipboard.instance.copy([widget.file]);
} else {
@@ -198,6 +202,7 @@ class _FileElementState extends State<FileElement>
}
Future<void> _delete() async {
if (guardDemoAction(context)) return;
await showDialog<void>(
context: context,
builder: (context) => ConfirmDialog(
@@ -269,6 +274,7 @@ class _FileElementState extends State<FileElement>
title: const Text('Im Talk-Chat versenden'),
onTap: () {
Navigator.of(sheetCtx).pop();
if (guardDemoAction(context)) return;
AppRoutes.openInternalShareToChat(
context,
RemoteFileRef.fromCacheable(widget.file),