Last active
January 21, 2026 15:42
-
-
Save deminearchiver/aa89bd948d0bfdf617cdaed23119b28a to your computer and use it in GitHub Desktop.
Design suggsetion for ImranR98/Obtainium#2742.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| void main() => runApp(const MyApp()); | |
| class MyApp extends StatelessWidget { | |
| const MyApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Flutter Demo', | |
| debugShowCheckedModeBanner: false, | |
| theme: ThemeData( | |
| colorScheme: ColorScheme.fromSeed( | |
| seedColor: Colors.amber, | |
| dynamicSchemeVariant: .fidelity, | |
| brightness: .dark, | |
| ), | |
| platform: .android, | |
| ), | |
| home: const MyHomePage(title: 'Flutter Demo Home Page'), | |
| ); | |
| } | |
| } | |
| class MyHomePage extends StatefulWidget { | |
| final String title; | |
| const MyHomePage({super.key, required this.title}); | |
| @override | |
| State<MyHomePage> createState() => _MyHomePageState(); | |
| } | |
| class _MyHomePageState extends State<MyHomePage> { | |
| Widget buildRepoRenameWarning({ | |
| required AppInMemory? app, | |
| required AppsProvider appsProvider, | |
| required Future<void> Function(String id) onUpdate, | |
| }) { | |
| if (app?.app.hasPendingRepoRename != true) { | |
| return const SizedBox.shrink(); | |
| } | |
| var appValue = app!; | |
| var pendingUrl = appValue.app.pendingRepoRenameUrl!; | |
| final colorScheme = ColorScheme.of(context); | |
| final textTheme = TextTheme.of(context); | |
| return Column( | |
| mainAxisSize: MainAxisSize.min, | |
| crossAxisAlignment: CrossAxisAlignment.stretch, | |
| spacing: 2, | |
| children: [ | |
| Material( | |
| shape: const RoundedRectangleBorder( | |
| borderRadius: BorderRadius.vertical( | |
| top: Radius.circular(16), | |
| bottom: Radius.circular(4), | |
| ), | |
| ), | |
| color: colorScheme.surfaceContainer, | |
| child: ConstrainedBox( | |
| constraints: const BoxConstraints(minHeight: 48), | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), | |
| child: Row( | |
| spacing: 12, | |
| children: [ | |
| Icon( | |
| Icons.info_outline_rounded, | |
| size: 24, | |
| color: colorScheme.onSurfaceVariant, | |
| ), | |
| Expanded( | |
| child: Column( | |
| mainAxisSize: MainAxisSize.min, | |
| crossAxisAlignment: CrossAxisAlignment.stretch, | |
| children: [ | |
| Text( | |
| tr('repoRenamed'), | |
| style: textTheme.bodyLarge?.copyWith( | |
| fontWeight: FontWeight.w500, | |
| color: colorScheme.onSurface, | |
| ), | |
| ), | |
| Text( | |
| tr('repoRenamedExplanation'), | |
| style: textTheme.bodyMedium?.copyWith( | |
| color: colorScheme.onSurfaceVariant, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| Material( | |
| shape: const RoundedRectangleBorder( | |
| borderRadius: BorderRadius.all(Radius.circular(4)), | |
| ), | |
| color: colorScheme.surfaceContainer, | |
| child: ConstrainedBox( | |
| constraints: const BoxConstraints(minHeight: 48), | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), | |
| child: Row( | |
| spacing: 12, | |
| children: [ | |
| Icon( | |
| Icons.link_rounded, | |
| size: 24, | |
| color: colorScheme.onSurfaceVariant, | |
| ), | |
| Expanded( | |
| child: Column( | |
| mainAxisSize: MainAxisSize.min, | |
| crossAxisAlignment: CrossAxisAlignment.stretch, | |
| children: [ | |
| Text( | |
| tr('newUrl'), | |
| style: textTheme.bodyLarge?.copyWith( | |
| fontWeight: FontWeight.w500, | |
| color: colorScheme.onSurface, | |
| ), | |
| ), | |
| Text( | |
| pendingUrl, | |
| style: textTheme.bodyMedium?.copyWith( | |
| color: colorScheme.onSurfaceVariant, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| Material( | |
| shape: const RoundedRectangleBorder( | |
| borderRadius: BorderRadius.vertical( | |
| top: Radius.circular(4), | |
| bottom: Radius.circular(16), | |
| ), | |
| ), | |
| color: colorScheme.surfaceContainer, | |
| child: ConstrainedBox( | |
| constraints: const BoxConstraints(minHeight: 48), | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric( | |
| horizontal: 16, | |
| // Min tap target has a height of 48dp | |
| vertical: 10 - 4, | |
| ), | |
| child: Row( | |
| spacing: 12, | |
| children: [ | |
| Expanded( | |
| child: OutlinedButton( | |
| style: ButtonStyle( | |
| backgroundColor: WidgetStateProperty.fromMap({ | |
| WidgetState.disabled: colorScheme.onSurface | |
| .withValues(alpha: 0.10), | |
| WidgetState.any: Colors.transparent, | |
| }), | |
| side: WidgetStatePropertyAll( | |
| BorderSide( | |
| width: 1, | |
| strokeAlign: BorderSide.strokeAlignInside, | |
| color: colorScheme.outlineVariant, | |
| ), | |
| ), | |
| elevation: WidgetStatePropertyAll(0), | |
| overlayColor: WidgetStateProperty.fromMap({ | |
| WidgetState.disabled: colorScheme.onSurfaceVariant | |
| .withAlpha(0), | |
| WidgetState.pressed: colorScheme.onSurfaceVariant | |
| .withValues(alpha: 0.10), | |
| WidgetState.focused: colorScheme.onSurfaceVariant | |
| .withValues(alpha: 0.10), | |
| WidgetState.hovered: colorScheme.onSurfaceVariant | |
| .withValues(alpha: 0.08), | |
| WidgetState.any: colorScheme.onSurfaceVariant | |
| .withAlpha(0), | |
| }), | |
| foregroundColor: WidgetStateProperty.fromMap({ | |
| WidgetState.disabled: colorScheme.onSurface | |
| .withValues(alpha: 0.38), | |
| WidgetState.any: colorScheme.onSurfaceVariant, | |
| }), | |
| textStyle: WidgetStatePropertyAll(textTheme.labelLarge), | |
| ), | |
| onPressed: () async { | |
| await appsProvider.updatePendingRepoRename( | |
| appValue.app.id, | |
| null, | |
| ); | |
| }, | |
| child: Text(tr('dismiss')), | |
| ), | |
| ), | |
| Expanded( | |
| child: FilledButton.tonal( | |
| style: ButtonStyle( | |
| elevation: WidgetStatePropertyAll(0), | |
| textStyle: WidgetStatePropertyAll( | |
| textTheme.labelLarge?.copyWith( | |
| fontWeight: FontWeight.w600, | |
| ), | |
| ), | |
| ), | |
| onPressed: () async { | |
| await appsProvider.acceptRepoRename( | |
| appValue.app.id, | |
| pendingUrl, | |
| ); | |
| if (mounted) { | |
| onUpdate(appValue.app.id); | |
| } | |
| }, | |
| child: Text(tr('updateUrl')), | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ], | |
| ); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: Center( | |
| child: buildRepoRenameWarning( | |
| app: AppInMemory(), | |
| appsProvider: AppsProvider(), | |
| onUpdate: (String _) async {}, | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class App { | |
| String get id => "app.id"; | |
| bool? get hasPendingRepoRename => true; | |
| String? get pendingRepoRenameUrl => "https://github.com/foo/bar"; | |
| } | |
| class AppInMemory { | |
| App get app => App(); | |
| } | |
| class AppsProvider { | |
| Future<void> acceptRepoRename(String _, String _) async {} | |
| Future<void> updatePendingRepoRename(String _, String? _) async {} | |
| } | |
| String tr(String key) { | |
| return "tr($key)"; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment