Store assets: landscape tablet screenshots (iPad, Android 7/10-inch)
Captured from the app's real sidebar shell at 1024x768; adds landscape compositions to compose.py and the README upload table. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
11b3d535a9
commit
5837464581
@@ -11,6 +11,10 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:noo/main.dart' show MainShellView;
|
||||
import 'package:noo/providers/recent_controller.dart';
|
||||
import 'package:noo/providers/shares_controller.dart';
|
||||
import 'package:noo/providers/trash_controller.dart';
|
||||
import 'package:noo/models/app_tab.dart';
|
||||
import 'package:noo/theme/design_tokens.dart';
|
||||
import 'package:noo/views/lock_screen_view.dart';
|
||||
@@ -169,10 +173,26 @@ class DemoOps extends ItemOperations {
|
||||
Future<List<NextcloudSharee>> searchSharees(String query) async => [];
|
||||
}
|
||||
|
||||
/// The shell collapses to the Offline tab alone when it thinks there is no
|
||||
/// network, so the landscape (full shell) captures report an online device.
|
||||
class DemoConnectivity extends ConnectivityController {
|
||||
@override
|
||||
bool get isOffline => false;
|
||||
}
|
||||
|
||||
class DemoFiles extends FilesController {
|
||||
DemoFiles(super.session, {this.external = false});
|
||||
final bool external;
|
||||
@override
|
||||
NextcloudUserQuota? get quota => const NextcloudUserQuota(
|
||||
usedBytes: 46000000000,
|
||||
totalBytes: 107374182400,
|
||||
usagePercentage: 0.43,
|
||||
userName: 'alex',
|
||||
email: 'alex@cloud.example.com',
|
||||
serverVersion: '31.0.0',
|
||||
);
|
||||
@override
|
||||
StorageScope get storageScope =>
|
||||
external ? StorageScope.all : StorageScope.cloud;
|
||||
@override
|
||||
@@ -329,12 +349,31 @@ void main() {
|
||||
MockStreamHandler.inline(onListen: (arguments, events) {}),
|
||||
);
|
||||
}
|
||||
// The shell listens for share/pick intents; none ever arrive here.
|
||||
for (final name in [
|
||||
'dev.ayushya.noo/share_intent/new',
|
||||
'dev.ayushya.noo/pick_intent/new',
|
||||
]) {
|
||||
messenger.setMockStreamHandler(
|
||||
EventChannel(name),
|
||||
MockStreamHandler.inline(onListen: (arguments, events) {}),
|
||||
);
|
||||
}
|
||||
messenger.setMockStreamHandler(
|
||||
const EventChannel('dev.fluttercommunity.plus/connectivity_status'),
|
||||
MockStreamHandler.inline(onListen: (arguments, events) {}),
|
||||
);
|
||||
});
|
||||
for (final device in ['android', 'atablet', 'iphone', 'ipad']) {
|
||||
// `ipadl` / `atabletl` are the landscape tablet captures, which render the
|
||||
// app's real shell (sidebar + toolbar) instead of the single-screen widgets.
|
||||
for (final device in [
|
||||
'android',
|
||||
'atablet',
|
||||
'atabletl',
|
||||
'iphone',
|
||||
'ipad',
|
||||
'ipadl',
|
||||
]) {
|
||||
for (final screen in [
|
||||
'accounts',
|
||||
'lock',
|
||||
@@ -353,17 +392,27 @@ void main() {
|
||||
'ui_lock_account_switching': true,
|
||||
'ui_lock_hidden_files': true,
|
||||
'ui_use_dynamic_color': false,
|
||||
// Skips the shell's one-time notification-permission prompt.
|
||||
'notification_permission_asked': true,
|
||||
});
|
||||
final tablet = device == 'ipad' || device == 'atablet';
|
||||
final android = device == 'android' || device == 'atablet';
|
||||
final size = tablet
|
||||
final landscape = device == 'ipadl' || device == 'atabletl';
|
||||
final tablet = landscape || device == 'ipad' || device == 'atablet';
|
||||
final android =
|
||||
device == 'android' ||
|
||||
device == 'atablet' ||
|
||||
device == 'atabletl';
|
||||
final size = landscape
|
||||
? const Size(1024, 768)
|
||||
: tablet
|
||||
? const Size(768, 1024)
|
||||
: (android ? const Size(430, 800) : const Size(430, 932));
|
||||
tester.view.devicePixelRatio = 1;
|
||||
tester.view.physicalSize = size;
|
||||
await tester.binding.setSurfaceSize(size);
|
||||
final key = GlobalKey();
|
||||
final connectivity = ConnectivityController();
|
||||
final connectivity = landscape
|
||||
? DemoConnectivity()
|
||||
: ConnectivityController();
|
||||
final session = DemoSession(connectivity);
|
||||
final files = DemoFiles(session, external: screen == 'external');
|
||||
final settings = SettingsController();
|
||||
@@ -378,6 +427,12 @@ void main() {
|
||||
photos: photos,
|
||||
favorites: favorites,
|
||||
);
|
||||
final trash = TrashController(session);
|
||||
final shares = SharesController(session);
|
||||
final recent = RecentController(session);
|
||||
if (landscape && screen == 'offline') {
|
||||
settings.requestTab(AppTab.offline);
|
||||
}
|
||||
final scroll = ScrollController();
|
||||
final style = android ? NooNavStyle.android : NooNavStyle.ios;
|
||||
final browsing = const {
|
||||
@@ -412,6 +467,12 @@ void main() {
|
||||
ChangeNotifierProvider<OfflineController>.value(value: offline),
|
||||
ChangeNotifierProvider<PickController>.value(value: pick),
|
||||
ChangeNotifierProvider<PhotosController>.value(value: photos),
|
||||
ChangeNotifierProvider<FavoritesController>.value(
|
||||
value: favorites,
|
||||
),
|
||||
ChangeNotifierProvider<TrashController>.value(value: trash),
|
||||
ChangeNotifierProvider<SharesController>.value(value: shares),
|
||||
ChangeNotifierProvider<RecentController>.value(value: recent),
|
||||
Provider<ItemOperations>.value(value: ops),
|
||||
],
|
||||
child: MaterialApp(
|
||||
@@ -423,6 +484,8 @@ void main() {
|
||||
card ? child! : RepaintBoundary(key: key, child: child),
|
||||
home: screen == 'lock'
|
||||
? const LockScreenView()
|
||||
: landscape && browsing
|
||||
? const MainShellView()
|
||||
: Scaffold(
|
||||
body: browsing
|
||||
? FilesView(
|
||||
@@ -438,16 +501,27 @@ void main() {
|
||||
)
|
||||
: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Builder(
|
||||
builder: (context) => RepaintBoundary(
|
||||
key: key,
|
||||
child: ColoredBox(
|
||||
color: context.nooColors.bg,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: screen == 'security'
|
||||
? const SettingsSecuritySection()
|
||||
: const SettingsFileSyncSection(),
|
||||
child: ConstrainedBox(
|
||||
// Landscape tablets would stretch the card
|
||||
// across the whole window; keep it phone-like.
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: landscape ? 520 : double.infinity,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (context) => RepaintBoundary(
|
||||
key: key,
|
||||
child: ColoredBox(
|
||||
color: context.nooColors.bg,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
// The desktop-style card fills its
|
||||
// height, so size it to its content.
|
||||
child: IntrinsicHeight(
|
||||
child: screen == 'security'
|
||||
? const SettingsSecuritySection()
|
||||
: const SettingsFileSyncSection(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -514,6 +588,9 @@ void main() {
|
||||
});
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
scroll.dispose();
|
||||
trash.dispose();
|
||||
shares.dispose();
|
||||
recent.dispose();
|
||||
pick.dispose();
|
||||
offline.dispose();
|
||||
sync.dispose();
|
||||
|
||||
Reference in New Issue
Block a user