Compare commits

..

3 Commits

Author SHA1 Message Date
Darshan
4298f4d32b fix: spacing. 2025-03-18 13:46:59 +05:30
Darshan
43de5c17f1 Merge remote-tracking branch 'origin/env-support' into env-support 2025-03-18 13:10:27 +05:30
Darshan
2dea779758 design fixes. 2025-03-18 13:10:17 +05:30
18 changed files with 287 additions and 353 deletions

3
.env.example Normal file
View File

@ -0,0 +1,3 @@
APPWRITE_PROJECT_ID=
APPWRITE_PROJECT_NAME=
APPWRITE_PUBLIC_ENDPOINT=

View File

@ -24,39 +24,16 @@ Alternatively, open the repository URL in `Android Studio` to clone it directly.
## 🛠️ Development Guide ## 🛠️ Development Guide
1. **Configure Appwrite** 1. **Configure Appwrite**
Open `lib/config/environment.dart` and update the values with your Appwrite project credentials: Navigate to `lib/data/repository/appwrite_repository.dart` and update the values to match your
```dart Appwrite project credentials.
class Environment {
static const String appwritePublicEndpoint = '[appwritePublicEndpoint]';
static const String appwriteProjectId = '[appwriteProjectId]';
static const String appwriteProjectName = '[appwriteProjectName]';
}
```
2. **Customize as Needed** 2. **Customize as Needed**
Modify the starter kit to suit your app's requirements. Adjust UI, features, or backend Modify the starter kit to suit your app's requirements. Adjust UI, features, or backend
integrations as per your needs. integrations as per your needs.
3. **Run the App** 3. **Run the App**
Select a target device and run the app: Select a target device (emulator or a connected physical device) in `Android Studio`, and
```bash click **Run** to start the app.
# List available devices
flutter devices
# Run on a specific device (replace 'device-id' with actual device)
flutter run -d device-id
# Examples:
flutter run -d chrome # Web
flutter run -d "iPhone 15" # iOS Simulator
flutter run -d emulator-5554 # Android Emulator
flutter run -d macos # macOS Desktop
```
**Build for Web:**
```bash
flutter build web
```
--- ---
@ -69,5 +46,5 @@ production : https://docs.flutter.dev/deployment
## 💡 Additional Notes ## 💡 Additional Notes
- This starter project is designed to streamline your Flutter development with Appwrite. - This starter project is designed to streamline your Android development with Appwrite.
- Refer to the [Appwrite Documentation](https://appwrite.io/docs) for detailed integration guidance. - Refer to the [Appwrite Documentation](https://appwrite.io/docs) for detailed integration guidance.

View File

@ -1,19 +0,0 @@
import 'package:appwrite_flutter_starter_kit/home.dart';
import 'package:flutter/material.dart';
class AppwriteApp extends StatelessWidget {
const AppwriteApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Appwrite StarterKit',
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const AppwriteStarterKit(),
);
}
}

View File

@ -1,5 +0,0 @@
class Environment {
static const String appwritePublicEndpoint = '[appwritePublicEndpoint]';
static const String appwriteProjectId = '[appwriteProjectId]';
static const String appwriteProjectName = '[appwriteProjectName]';
}

View File

@ -2,16 +2,15 @@ import 'package:intl/intl.dart';
import 'package:appwrite/appwrite.dart'; import 'package:appwrite/appwrite.dart';
import 'package:appwrite_flutter_starter_kit/data/models/log.dart'; import 'package:appwrite_flutter_starter_kit/data/models/log.dart';
import 'package:appwrite_flutter_starter_kit/data/models/project_info.dart'; import 'package:appwrite_flutter_starter_kit/data/models/project_info.dart';
import 'package:appwrite_flutter_starter_kit/config/environment.dart';
/// A repository responsible for handling network interactions with the Appwrite server. /// A repository responsible for handling network interactions with the Appwrite server.
/// ///
/// It provides a helper method to ping the server. /// It provides a helper method to ping the server.
class AppwriteRepository { class AppwriteRepository {
static const String pingPath = "/ping"; static const String pingPath = "/ping";
static const String appwriteProjectId = Environment.appwriteProjectId; static const String appwriteProjectId = String.fromEnvironment('APPWRITE_PROJECT_ID');
static const String appwriteProjectName = Environment.appwriteProjectName; static const String appwriteProjectName = String.fromEnvironment('APPWRITE_PROJECT_NAME');
static const String appwritePublicEndpoint = Environment.appwritePublicEndpoint; static const String appwritePublicEndpoint = String.fromEnvironment('APPWRITE_PUBLIC_ENDPOINT');
final Client _client = Client() final Client _client = Client()
.setProject(appwriteProjectId) .setProject(appwriteProjectId)

View File

@ -1,80 +0,0 @@
import 'package:appwrite_flutter_starter_kit/data/models/log.dart';
import 'package:appwrite_flutter_starter_kit/data/models/status.dart';
import 'package:appwrite_flutter_starter_kit/data/repository/appwrite_repository.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/checkered_background.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/collapsible_bottomsheet.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/connection_status_view.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/getting_started_cards.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/top_platform_view.dart';
import 'package:appwrite_flutter_starter_kit/utils/extensions/build_context.dart';
import 'package:flutter/material.dart';
class AppwriteStarterKit extends StatefulWidget {
const AppwriteStarterKit({super.key});
@override
State<AppwriteStarterKit> createState() => _AppwriteStarterKit();
}
class _AppwriteStarterKit extends State<AppwriteStarterKit> {
final List<Log> _logs = [];
Status _status = Status.idle;
final AppwriteRepository _repository = AppwriteRepository();
@override
Widget build(BuildContext context) {
return Scaffold(
body: CheckeredBackground(
child: SafeArea(
minimum: EdgeInsets.only(
top: context.isExtraWideScreen
? 156
: context.isLargeScreen
? 24
: 32),
child: Stack(
children: [
SingleChildScrollView(
child: Column(
spacing: 16,
children: [
TopPlatformView(status: _status),
ConnectionStatusView(
status: _status,
onButtonClick: () async {
setState(() => _status = Status.loading);
final log = await _repository.ping();
_logs.add(log);
await Future.delayed(
const Duration(milliseconds: 1250),
);
setState(
() => _status =
(200 <= log.status && log.status <= 399)
? Status.success
: Status.error,
);
},
),
GettingStartedCards()
],
),
),
// bottomsheet
Align(
alignment: Alignment.bottomCenter,
child: CollapsibleBottomSheet(
logs: _logs,
projectInfo: _repository.getProjectInfo(),
),
),
],
),
),
),
);
}
}

View File

@ -1,8 +1,98 @@
import 'package:appwrite_flutter_starter_kit/app.dart'; import 'package:appwrite_flutter_starter_kit/data/models/log.dart';
import 'package:appwrite_flutter_starter_kit/data/models/status.dart';
import 'package:appwrite_flutter_starter_kit/data/repository/appwrite_repository.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/checkered_background.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/collapsible_bottomsheet.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/connection_status_view.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/getting_started_cards.dart';
import 'package:appwrite_flutter_starter_kit/ui/components/top_platform_view.dart';
import 'package:appwrite_flutter_starter_kit/utils/app_initializer.dart'; import 'package:appwrite_flutter_starter_kit/utils/app_initializer.dart';
import 'package:appwrite_flutter_starter_kit/utils/extensions/build_context.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
void main() async { void main() async {
await AppInitializer.initialize(); await AppInitializer.initialize();
runApp(AppwriteApp()); runApp(AppwriteApp());
} }
class AppwriteApp extends StatelessWidget {
const AppwriteApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Appwrite StarterKit',
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const AppwriteStarterKit(),
);
}
}
class AppwriteStarterKit extends StatefulWidget {
const AppwriteStarterKit({super.key});
@override
State<AppwriteStarterKit> createState() => _AppwriteStarterKit();
}
class _AppwriteStarterKit extends State<AppwriteStarterKit> {
final List<Log> _logs = [];
Status _status = Status.idle;
final AppwriteRepository _repository = AppwriteRepository();
@override
Widget build(BuildContext context) {
return Scaffold(
body: CheckeredBackground(
child: SafeArea(
minimum: EdgeInsets.only(top: context.isLargeScreen ? 24 : 16),
child: Stack(
children: [
SingleChildScrollView(
child: Column(
spacing: context.isLargeScreen ? 64 : 32,
children: [
TopPlatformView(status: _status),
ConnectionStatusView(
status: _status,
onButtonClick: () async {
setState(() => _status = Status.loading);
final log = await _repository.ping();
_logs.add(log);
await Future.delayed(
const Duration(milliseconds: 1250),
);
setState(
() => _status =
(200 <= log.status && log.status <= 399)
? Status.success
: Status.error,
);
},
),
GettingStartedCards()
],
),
),
// bottomsheet
Align(
alignment: Alignment.bottomCenter,
child: CollapsibleBottomSheet(
logs: _logs,
projectInfo: _repository.getProjectInfo(),
),
),
],
),
),
),
);
}
}

View File

@ -491,7 +491,7 @@ class LogsTableRow extends StatelessWidget {
child: MouseRegion( child: MouseRegion(
cursor: SystemMouseCursors.click, cursor: SystemMouseCursors.click,
child: Text( child: Text(
response.length >= 50 ? response.substring(0, 50) : response, response.length > 50 ? response.substring(0, 50) : response,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: const TextStyle(

View File

@ -15,7 +15,7 @@ class ConnectionLine extends StatelessWidget {
return SizedBox( return SizedBox(
width: context.widthFactor( width: context.widthFactor(
mobileFactor: 0.25, mobileFactor: 0.25,
largeScreenFactor: 0.1, largeScreenFactor: 0.125,
), ),
child: Flex( child: Flex(
direction: Axis.horizontal, direction: Axis.horizontal,

View File

@ -1,93 +1,59 @@
import 'package:appwrite_flutter_starter_kit/ui/components/responsive_layout.dart';
import 'package:appwrite_flutter_starter_kit/utils/extensions/build_context.dart'; import 'package:appwrite_flutter_starter_kit/utils/extensions/build_context.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
const cardWidgets = [
GeneralInfoCard(
title: "Edit your app",
link: null,
subtitle: HighlightedText(),
),
GeneralInfoCard(
title: "Head to Appwrite Cloud",
link: "https://cloud.appwrite.io",
subtitle: Text(
"Start managing your project from the Appwrite console",
style: TextStyle(fontSize: 14, color: Color(0xFF56565C)),
),
),
GeneralInfoCard(
title: "Explore docs",
link: "https://appwrite.io/docs",
subtitle: Text(
"Discover the full power of Appwrite by diving into our documentation",
style: TextStyle(fontSize: 14, color: Color(0xFF56565C)),
),
),
];
/// A widget that contains a list of informational cards displayed vertically. /// A widget that contains a list of informational cards displayed vertically.
class GettingStartedCards extends StatelessWidget { class GettingStartedCards extends StatelessWidget {
const GettingStartedCards({super.key}); const GettingStartedCards({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ResponsiveLayout( return Padding(
smallDeviceLayout: Padding( padding: const EdgeInsets.all(16.0),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), child: context.isLargeScreen
child: Column( ? Wrap(
mainAxisSize: MainAxisSize.min,
children: [
GeneralInfoCard(
title: "Edit your app",
link: null,
subtitle: const HighlightedText(),
),
GeneralInfoCard(
title: "Head to Appwrite Cloud",
link: "https://cloud.appwrite.io",
subtitle: const Text(
"Start managing your project from the Appwrite console",
style: TextStyle(
fontSize: 14,
color: Color(0xFF56565C),
),
),
),
GeneralInfoCard(
title: "Explore docs",
link: "https://appwrite.io/docs",
subtitle: const Text(
"Discover the full power of Appwrite by diving into our documentation",
style: TextStyle(
fontSize: 14,
color: Color(0xFF56565C),
),
),
),
],
),
),
largeDeviceLayout: Padding(
padding: EdgeInsets.symmetric(
horizontal: context.isExtraWideScreen ? 64 : 16.0, vertical: 16.0),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
spacing: 16, spacing: 16,
children: [ runSpacing: 16,
Flexible( alignment: WrapAlignment.center,
child: GeneralInfoCard( children: cardWidgets
title: "Edit your app", .map((card) => SizedBox(
link: null, width: 350,
subtitle: const HighlightedText(), child: card,
), ))
), .toList(),
Flexible( )
child: GeneralInfoCard( : Column(
title: "Head to Appwrite Cloud", mainAxisSize: MainAxisSize.min,
link: "https://cloud.appwrite.io", children: cardWidgets
subtitle: const Text( .map((card) => Padding(
"Start managing your project from the Appwrite console", padding: const EdgeInsets.only(bottom: 16),
style: TextStyle( child: card,
fontSize: 14, ))
color: Color(0xFF56565C), .toList(),
),
),
),
),
Flexible(
child: GeneralInfoCard(
title: "Explore docs",
link: "https://appwrite.io/docs",
subtitle: const Text(
"Discover the full power of Appwrite by diving into our documentation",
style: TextStyle(
fontSize: 14,
color: Color(0xFF56565C),
),
),
),
),
],
),
), ),
); );
} }
@ -115,12 +81,9 @@ class GeneralInfoCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) { return LayoutBuilder(builder: (context, constraints) {
final double cardWidth = context.isExtraWideScreen
? constraints.maxWidth.clamp(0, 350)
: constraints.maxWidth;
return SizedBox( return SizedBox(
width: cardWidth, // `1` because we already have padding on sides.
width: constraints.maxWidth * (context.isExtraWideScreen ? 0.55 : 1),
child: Card( child: Card(
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(

View File

@ -19,19 +19,24 @@ class TopPlatformView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Padding(
// web has extra padding on top.
padding:
context.isLargeScreen ? EdgeInsets.only(top: 85) : EdgeInsets.zero,
child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
PlatformIcon( PlatformIcon(
size: context.isExtraWideScreen ? 142 : 100, size: context.isLargeScreen ? 185 : 100,
child: FlutterLogo(size: context.isExtraWideScreen ? 56 : 40), child: FlutterLogo(size: context.isLargeScreen ? 100 : 40),
), ),
ConnectionLine(show: status == Status.success), ConnectionLine(show: status == Status.success),
PlatformIcon( PlatformIcon(
size: context.isExtraWideScreen ? 142 : 100, size: context.isLargeScreen ? 185 : 100,
child: AppwriteIcon(size: context.isExtraWideScreen ? 56 : 40), child: AppwriteIcon(size: context.isLargeScreen ? 100 : 40),
), ),
], ],
),
); );
} }
} }
@ -58,7 +63,7 @@ class PlatformIcon extends StatelessWidget {
height: size, height: size,
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFFAFAFD), color: const Color(0xFFFAFAFD),
borderRadius: BorderRadius.circular(context.isExtraWideScreen ? size * 0.2 : 24), borderRadius: BorderRadius.circular(context.isLargeScreen ? 44 : 24),
border: Border.all(color: const Color(0x0A19191C), width: 1), border: Border.all(color: const Color(0x0A19191C), width: 1),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
@ -72,10 +77,9 @@ class PlatformIcon extends StatelessWidget {
child: Container( child: Container(
width: size * 0.86, width: size * 0.86,
height: size * 0.86, height: size * 0.86,
margin: context.isExtraWideScreen ? EdgeInsets.all(8) : null,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(context.isExtraWideScreen ? size * 0.2: 16), borderRadius: BorderRadius.circular(context.isLargeScreen ? 32 : 16),
border: Border.all(color: const Color(0xFFFAFAFB), width: 1), border: Border.all(color: const Color(0xFFFAFAFB), width: 1),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppwriteIcon extends StatelessWidget { class AppwriteIcon extends StatelessWidget {
final double size; // Desired width, height scales accordingly final double size;
final Color color; final Color color;
const AppwriteIcon({ const AppwriteIcon({

View File

@ -1,13 +0,0 @@
#!/bin/sh
set -e
# Script used during deployment on Appwrite Sites
# Replace [appwritePublicEndpoint] with APPWRITE_PUBLIC_ENDPOINT in environment file
sed -i "s|\[appwritePublicEndpoint\]|$APPWRITE_PUBLIC_ENDPOINT|g" lib/config/environment.dart
# Replace [appwriteProjectId] with APPWRITE_PROJECT_ID in environment file
sed -i "s|\[appwriteProjectId\]|$APPWRITE_PROJECT_ID|g" lib/config/environment.dart
# Replace [appwriteProjectName] with APPWRITE_PROJECT_NAME in environment file
sed -i "s|\[appwriteProjectName\]|$APPWRITE_PROJECT_NAME|g" lib/config/environment.dart

View File

@ -45,10 +45,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.4.0"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -77,10 +77,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.19.0" version: "1.19.1"
cookie_jar: cookie_jar:
dependency: transitive dependency: transitive
description: description:
@ -271,10 +271,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.15.0" version: "1.16.0"
package_info_plus: package_info_plus:
dependency: transitive dependency: transitive
description: description:
@ -625,5 +625,5 @@ packages:
source: hosted source: hosted
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.6.0 <4.0.0" dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.27.0" flutter: ">=3.27.0"

View File

@ -5,7 +5,7 @@ publish_to: 'none'
version: 1.0.0 version: 1.0.0
environment: environment:
sdk: ^3.5.4 sdk: ^3.6.0
dependencies: dependencies:
flutter: flutter:

BIN
web/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

View File

@ -1,8 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M24.4429 16.4322V21.9096H10.7519C6.76318 21.9096 3.28044 19.7067 1.4171 16.4322C1.14622 15.9561 0.909137 15.4567 0.710264 14.9383C0.319864 13.9225 0.0744552 12.8325 0 11.6952V10.2143C0.0161646 9.96089 0.0416361 9.70942 0.0749451 9.46095C0.143032 8.95105 0.245898 8.45211 0.381093 7.96711C1.66006 3.36909 5.81877 0 10.7519 0C15.6851 0 19.8433 3.36909 21.1223 7.96711H15.2682C14.3072 6.4683 12.6437 5.4774 10.7519 5.4774C8.86017 5.4774 7.19668 6.4683 6.23562 7.96711C5.9427 8.42274 5.71542 8.92516 5.56651 9.46095C5.43425 9.93599 5.36371 10.4369 5.36371 10.9548C5.36371 12.5248 6.01324 13.94 7.05463 14.9383C8.01961 15.865 9.32061 16.4322 10.7519 16.4322H24.4429Z"
fill="#FD366E" />
<path
d="M24.4429 9.46094V14.9383H14.4492C15.4906 13.94 16.1401 12.5248 16.1401 10.9548C16.1401 10.4369 16.0696 9.93598 15.9373 9.46094H24.4429Z"
fill="#FD366E" />
</svg>

Before

Width:  |  Height:  |  Size: 1012 B

View File

@ -1,6 +1,4 @@
<!DOCTYPE html> <!DOCTYPE html><html><head>
<html>
<head>
<!-- <!--
If you are serving your web app in a path other than the root, change the If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from. href value below to reflect the base path you are serving from.
@ -27,31 +25,61 @@
<link rel="apple-touch-icon" href="icons/Icon-192.png"> <link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon --> <!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.svg"> <link rel="icon" type="image/png" href="favicon.png">
<title>AppwriteStarterKit</title> <title>AppwriteStarterKit</title>
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
name="viewport"> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
<style id="splash-screen-style"> <style id="splash-screen-style">
html, body { html {
height: 100%; height: 100%
}
body {
margin: 0; margin: 0;
min-height: 100%;
background-color: #EDEDF0; background-color: #EDEDF0;
background-size: 100% 100%;
} }
.center { .center {
margin: 0;
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: 64px; }
height: 64px;
display: flex; .contain {
align-items: center; display:block;
justify-content: center; width:100%; height:100%;
object-fit: contain;
}
.stretch {
display:block;
width:100%; height:100%;
}
.cover {
display:block;
width:100%; height:100%;
object-fit: cover;
} }
.bottom { .bottom {
@ -59,23 +87,20 @@
bottom: 0; bottom: 0;
left: 50%; left: 50%;
padding-bottom: 24px; padding-bottom: 24px;
transform: translateX(-50%); -ms-transform: translate(-50%, 0);
transform: translate(-50%, 0);
} }
@keyframes rotate { .bottomLeft {
from { position: absolute;
transform: rotate(0deg); bottom: 0;
} left: 0;
to {
transform: rotate(360deg);
}
} }
.rotate { .bottomRight {
width: 100%; position: absolute;
height: 100%; bottom: 0;
transform-origin: center center; right: 0;
animation: rotate 1.5s infinite linear;
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
@ -83,14 +108,7 @@
background-color: #19191D; background-color: #19191D;
} }
} }
@media (prefers-reduced-motion: reduce) {
.rotate {
animation: none;
}
}
</style> </style>
<script id="splash-screen-script"> <script id="splash-screen-script">
function removeSplashFromWeb() { function removeSplashFromWeb() {
document.getElementById("splash")?.remove(); document.getElementById("splash")?.remove();
@ -100,25 +118,30 @@
</script> </script>
</head> </head>
<body> <body>
<picture id="splash-branding">
<picture id="splash-branding"> <source srcset="splash/img/branding-1x.png 1x, splash/img/branding-2x.png 2x, splash/img/branding-3x.png 3x, splash/img/branding-4x.png 4x" media="(prefers-color-scheme: light)">
<source srcset="splash/img/branding-1x.png 1x, splash/img/branding-2x.png 2x, splash/img/branding-3x.png 3x, splash/img/branding-4x.png 4x" <source srcset="splash/img/branding-dark-1x.png 1x, splash/img/branding-dark-2x.png 2x, splash/img/branding-dark-3x.png 3x, splash/img/branding-dark-4x.png 4x" media="(prefers-color-scheme: dark)">
media="(prefers-color-scheme: light)">
<source srcset="splash/img/branding-dark-1x.png 1x, splash/img/branding-dark-2x.png 2x, splash/img/branding-dark-3x.png 3x, splash/img/branding-dark-4x.png 4x"
media="(prefers-color-scheme: dark)">
<img class="bottom" aria-hidden="true" src="splash/img/branding-1x.png" alt=""> <img class="bottom" aria-hidden="true" src="splash/img/branding-1x.png" alt="">
</picture> </picture>
<picture id="splash">
<source srcset="splash/img/light-1x.png 1x, splash/img/light-2x.png 2x, splash/img/light-3x.png 3x, splash/img/light-4x.png 4x" media="(prefers-color-scheme: light)">
<source srcset="splash/img/dark-1x.png 1x, splash/img/dark-2x.png 2x, splash/img/dark-3x.png 3x, splash/img/dark-4x.png 4x" media="(prefers-color-scheme: dark)">
<img class="center" aria-hidden="true" src="splash/img/light-1x.png" alt="">
</picture>
<div id="splash" class="center">
<svg class="rotate" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
<path opacity="0.2"
d="M24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM2.4 12C2.4 17.3019 6.69807 21.6 12 21.6C17.3019 21.6 21.6 17.3019 21.6 12C21.6 6.69807 17.3019 2.4 12 2.4C6.69807 2.4 2.4 6.69807 2.4 12Z"
fill="#56565C"/>
<path d="M5.11708 2.17017C6.66833 1.08398 8.45463 0.380338 10.3299 0.116783C12.2052 -0.146772 14.1163 0.0372409 15.9068 0.653778C17.6974 1.27031 19.3166 2.30187 20.6321 3.6641C21.9476 5.02633 22.922 6.68056 23.4757 8.49154C24.0293 10.3025 24.1465 12.2188 23.8177 14.0838C23.4888 15.9487 22.7233 17.7094 21.5836 19.2218C20.444 20.7342 18.9625 21.9554 17.2605 22.7855C15.5584 23.6157 13.684 24.0312 11.7906 23.9982L11.8325 21.5985C13.3472 21.625 14.8467 21.2925 16.2084 20.6284C17.57 19.9643 18.7552 18.9873 19.6669 17.7774C20.5786 16.5675 21.1911 15.159 21.4542 13.667C21.7172 12.1751 21.6235 10.642 21.1805 9.19323C20.7376 7.74445 19.9581 6.42107 18.9057 5.33128C17.8533 4.2415 16.5579 3.41625 15.1255 2.92302C13.693 2.42979 12.1642 2.28258 10.6639 2.49343C9.1637 2.70427 7.73467 3.26718 6.49367 4.13614L5.11708 2.17017Z"
fill="#56565C"/>
</svg>
</div>
<script src="flutter_bootstrap.js" async=""></script> <script src="flutter_bootstrap.js" async=""></script>
</body>
</html>
</body></html>