diff --git a/assets/logos/pg_logo_v2.svg b/assets/logos/pg_logo_v2.svg
new file mode 100644
index 0000000..33e3e95
--- /dev/null
+++ b/assets/logos/pg_logo_v2.svg
@@ -0,0 +1,27 @@
+
+
+
+
diff --git a/lib/components/login/login.dart b/lib/components/login/login.dart
index 759e9b2..4cf759f 100644
--- a/lib/components/login/login.dart
+++ b/lib/components/login/login.dart
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:mileograph_flutter/services/authservice.dart';
import 'package:mileograph_flutter/components/pages/settings.dart';
@@ -41,71 +43,99 @@ class _LoginScreenState extends State {
resizeToAvoidBottomInset: true,
body: Container(
color: Theme.of(context).scaffoldBackgroundColor,
- child: Center(
+ child: SafeArea(
child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
children: [
- Text.rich(
- TextSpan(
- children: [
- TextSpan(
- text: "Mile",
- style: TextStyle(
- color: Theme.of(context).textTheme.bodyLarge?.color,
+ Expanded(
+ child: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ LayoutBuilder(
+ builder: (context, constraints) {
+ return SizedBox(
+ width: constraints.maxWidth,
+ child: FittedBox(
+ fit: BoxFit.scaleDown,
+ child: Text.rich(
+ TextSpan(
+ children: [
+ TextSpan(
+ text: "Mile",
+ style: TextStyle(
+ color: Theme.of(
+ context,
+ ).textTheme.bodyLarge?.color,
+ ),
+ ),
+ const TextSpan(
+ text: "O",
+ style: TextStyle(color: Colors.red),
+ ),
+ TextSpan(
+ text: "graph",
+ style: TextStyle(
+ color: Theme.of(
+ context,
+ ).textTheme.bodyLarge?.color,
+ ),
+ ),
+ ],
+ style: const TextStyle(
+ decoration: TextDecoration.none,
+ color: Colors.white,
+ fontFamily: "Tomatoes",
+ fontSize: 50,
+ ),
+ ),
+ softWrap: false,
+ overflow: TextOverflow.visible,
+ ),
+ ),
+ );
+ },
),
- ),
- const TextSpan(
- text: "O",
- style: TextStyle(color: Colors.red),
- ),
- TextSpan(
- text: "graph",
- style: TextStyle(
- color: Theme.of(context).textTheme.bodyLarge?.color,
+ const SizedBox(height: 50),
+ const LoginPanel(),
+ const SizedBox(height: 16),
+ IconButton(
+ icon: const Icon(Icons.settings, color: Colors.grey),
+ tooltip: 'Settings',
+ onPressed: () {
+ Navigator.of(context).push(
+ MaterialPageRoute(
+ fullscreenDialog: true,
+ builder: (_) => const SettingsPage(),
+ ),
+ );
+ },
),
- ),
- ],
- style: const TextStyle(
- decoration: TextDecoration.none,
- color: Colors.white,
- fontFamily: "Tomatoes",
- fontSize: 50,
+ if (_checkingSession) ...[
+ const SizedBox(height: 12),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const SizedBox(
+ height: 24,
+ width: 24,
+ child: CircularProgressIndicator(strokeWidth: 2),
+ ),
+ const SizedBox(width: 8),
+ Text(
+ 'Trying to log in',
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ ],
+ ),
+ ],
+ ],
),
),
),
- const SizedBox(height: 50),
- const LoginPanel(),
- const SizedBox(height: 16),
- IconButton(
- icon: const Icon(Icons.settings, color: Colors.grey),
- tooltip: 'Settings',
- onPressed: () {
- Navigator.of(context).push(
- MaterialPageRoute(
- fullscreenDialog: true,
- builder: (_) => const SettingsPage(),
- ),
- );
- },
+ const Padding(
+ padding: EdgeInsets.only(bottom: 12),
+ child: _LoginLogo(),
),
- if (_checkingSession) ...[
- const SizedBox(height: 12),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- const SizedBox(
- height: 24,
- width: 24,
- child: CircularProgressIndicator(strokeWidth: 2),
- ),
- const SizedBox(width: 8),
- Text(
- 'Trying to log in',
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- ],
- ),
- ],
],
),
),
@@ -114,6 +144,57 @@ class _LoginScreenState extends State {
}
}
+class _LoginLogo extends StatefulWidget {
+ const _LoginLogo();
+
+ @override
+ State<_LoginLogo> createState() => _LoginLogoState();
+}
+
+class _LoginLogoState extends State<_LoginLogo> {
+ late final Future _svgFuture;
+
+ @override
+ void initState() {
+ super.initState();
+ _svgFuture = rootBundle.loadString('assets/logos/pg_logo_v2.svg');
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final accent = Theme.of(context).colorScheme.primary;
+ final grey = const Color(0xFF999999);
+ return SizedBox(
+ height: 42,
+ child: Opacity(
+ opacity: 0.75,
+ child: FutureBuilder(
+ future: _svgFuture,
+ builder: (context, snapshot) {
+ final svg = snapshot.data;
+ if (svg == null) {
+ return const SizedBox.shrink();
+ }
+ final tinted = svg
+ .replaceAll('#00b7fd', _colorToHex(accent))
+ .replaceAll('#999999', _colorToHex(grey));
+ return SvgPicture.string(
+ tinted,
+ fit: BoxFit.contain,
+ semanticsLabel: 'Mileograph logo',
+ );
+ },
+ ),
+ ),
+ );
+ }
+
+ String _colorToHex(Color color) {
+ final hex = color.value.toRadixString(16).padLeft(8, '0');
+ return '#${hex.substring(2)}';
+ }
+}
+
class LoginPanel extends StatefulWidget {
const LoginPanel({super.key});
diff --git a/pubspec.lock b/pubspec.lock
index 03a531f..ddf1f3e 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -262,6 +262,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.0"
+ flutter_svg:
+ dependency: "direct main"
+ description:
+ name: flutter_svg
+ sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.3"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -400,6 +408,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
path_provider:
dependency: transitive
description:
@@ -605,6 +621,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.19"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.13"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.19"
vector_math:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 1ca4a7c..1e2978c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -42,6 +42,7 @@ dependencies:
file_selector_macos: ^0.9.4
file_selector_windows: ^0.9.3
file_selector_web: ^0.9.4
+ flutter_svg: ^2.0.10
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
@@ -73,6 +74,8 @@ flutter:
- family: Tomatoes
fonts:
- asset: lib/assets/fonts/Tomatoes-O8L8.ttf
+ assets:
+ - assets/logos/pg_logo_v2.svg
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg