Created onboarding
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 2
|
||||
/// Strings: 8 (4 per locale)
|
||||
/// Strings: 30 (15 per locale)
|
||||
///
|
||||
/// Built on 2024-02-21 at 23:50 UTC
|
||||
/// Built on 2024-02-22 at 01:09 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
@@ -148,8 +148,28 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
||||
late final Translations _root = this; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
late final _StringsOnboardingEn onboarding = _StringsOnboardingEn._(_root);
|
||||
late final _StringsConnectEn connect = _StringsConnectEn._(_root);
|
||||
late final _StringsLinksEn links = _StringsLinksEn._(_root);
|
||||
late final _StringsSettingsEn settings = _StringsSettingsEn._(_root);
|
||||
}
|
||||
|
||||
// Path: onboarding
|
||||
class _StringsOnboardingEn {
|
||||
_StringsOnboardingEn._(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
String get title => 'Welcome to My Linkding';
|
||||
String get subtitle => 'An application to manage your bookmarks.';
|
||||
String get start => 'Start';
|
||||
String get next => 'Next';
|
||||
String get previous => 'Previous';
|
||||
String get serverRequired => 'Servidor requerido';
|
||||
String get serverRequiredDescription => 'My Linkding it\'s not an standalone app, it requires the Linkding server to work.\nIn order to use this application, you must deploy Linkding on your home server, VPS or any other computer.';
|
||||
String get installationInstructions => 'Check the installation instructions on the official GitHub repository.';
|
||||
String get serverRunningConfirmation => 'I confirm that I have an instance of the Linkding server already running.';
|
||||
}
|
||||
|
||||
// Path: connect
|
||||
@@ -174,6 +194,17 @@ class _StringsLinksEn {
|
||||
String get links => 'Links';
|
||||
}
|
||||
|
||||
// Path: settings
|
||||
class _StringsSettingsEn {
|
||||
_StringsSettingsEn._(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
String get settings => 'Settings';
|
||||
String get disconnectFromServer => 'Disconnect from server';
|
||||
}
|
||||
|
||||
// Path: <root>
|
||||
class _StringsEs implements Translations {
|
||||
/// You can call this constructor and build your own translation instance of this locale.
|
||||
@@ -198,8 +229,28 @@ class _StringsEs implements Translations {
|
||||
@override late final _StringsEs _root = this; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override late final _StringsOnboardingEs onboarding = _StringsOnboardingEs._(_root);
|
||||
@override late final _StringsConnectEs connect = _StringsConnectEs._(_root);
|
||||
@override late final _StringsLinksEs links = _StringsLinksEs._(_root);
|
||||
@override late final _StringsSettingsEs settings = _StringsSettingsEs._(_root);
|
||||
}
|
||||
|
||||
// Path: onboarding
|
||||
class _StringsOnboardingEs implements _StringsOnboardingEn {
|
||||
_StringsOnboardingEs._(this._root);
|
||||
|
||||
@override final _StringsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Bienvenido a My Linkding';
|
||||
@override String get subtitle => 'Una aplicación para gestionar tus enlaces favoritos.';
|
||||
@override String get start => 'Comenzar';
|
||||
@override String get next => 'Siguiente';
|
||||
@override String get previous => 'Anterior';
|
||||
@override String get serverRequired => 'Servidor requerido';
|
||||
@override String get serverRequiredDescription => 'My Linkding no es una aplicación independiente, requiere el servidor Linkding para funcionar.\nPara utilizar esta aplicación, debe instalar Linkding en su servidor doméstico, VPS o cualquier otro ordenador.';
|
||||
@override String get installationInstructions => 'Mira las instrucciones de instalación en el repositorio oficial en GitHub.';
|
||||
@override String get serverRunningConfirmation => 'Confirmo que tengo una instancia del servidor Linkding ya en funcionamiento.';
|
||||
}
|
||||
|
||||
// Path: connect
|
||||
@@ -224,16 +275,38 @@ class _StringsLinksEs implements _StringsLinksEn {
|
||||
@override String get links => 'Enlaces';
|
||||
}
|
||||
|
||||
// Path: settings
|
||||
class _StringsSettingsEs implements _StringsSettingsEn {
|
||||
_StringsSettingsEs._(this._root);
|
||||
|
||||
@override final _StringsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get settings => 'Ajustes';
|
||||
@override String get disconnectFromServer => 'Desconectar del servidor';
|
||||
}
|
||||
|
||||
/// Flat map(s) containing all translations.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
|
||||
extension on Translations {
|
||||
dynamic _flatMapFunction(String path) {
|
||||
switch (path) {
|
||||
case 'onboarding.title': return 'Welcome to My Linkding';
|
||||
case 'onboarding.subtitle': return 'An application to manage your bookmarks.';
|
||||
case 'onboarding.start': return 'Start';
|
||||
case 'onboarding.next': return 'Next';
|
||||
case 'onboarding.previous': return 'Previous';
|
||||
case 'onboarding.serverRequired': return 'Servidor requerido';
|
||||
case 'onboarding.serverRequiredDescription': return 'My Linkding it\'s not an standalone app, it requires the Linkding server to work.\nIn order to use this application, you must deploy Linkding on your home server, VPS or any other computer.';
|
||||
case 'onboarding.installationInstructions': return 'Check the installation instructions on the official GitHub repository.';
|
||||
case 'onboarding.serverRunningConfirmation': return 'I confirm that I have an instance of the Linkding server already running.';
|
||||
case 'connect.connect': return 'Connect';
|
||||
case 'connect.connecting': return 'Connecting...';
|
||||
case 'connect.cannotConnectToServer': return 'Cannot connect to the server.';
|
||||
case 'links.links': return 'Links';
|
||||
case 'settings.settings': return 'Settings';
|
||||
case 'settings.disconnectFromServer': return 'Disconnect from server';
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
@@ -242,10 +315,21 @@ extension on Translations {
|
||||
extension on _StringsEs {
|
||||
dynamic _flatMapFunction(String path) {
|
||||
switch (path) {
|
||||
case 'onboarding.title': return 'Bienvenido a My Linkding';
|
||||
case 'onboarding.subtitle': return 'Una aplicación para gestionar tus enlaces favoritos.';
|
||||
case 'onboarding.start': return 'Comenzar';
|
||||
case 'onboarding.next': return 'Siguiente';
|
||||
case 'onboarding.previous': return 'Anterior';
|
||||
case 'onboarding.serverRequired': return 'Servidor requerido';
|
||||
case 'onboarding.serverRequiredDescription': return 'My Linkding no es una aplicación independiente, requiere el servidor Linkding para funcionar.\nPara utilizar esta aplicación, debe instalar Linkding en su servidor doméstico, VPS o cualquier otro ordenador.';
|
||||
case 'onboarding.installationInstructions': return 'Mira las instrucciones de instalación en el repositorio oficial en GitHub.';
|
||||
case 'onboarding.serverRunningConfirmation': return 'Confirmo que tengo una instancia del servidor Linkding ya en funcionamiento.';
|
||||
case 'connect.connect': return 'Conectar';
|
||||
case 'connect.connecting': return 'Conectando...';
|
||||
case 'connect.cannotConnectToServer': return 'No se puede conectar con el servidor.';
|
||||
case 'links.links': return 'Enlaces';
|
||||
case 'settings.settings': return 'Ajustes';
|
||||
case 'settings.disconnectFromServer': return 'Desconectar del servidor';
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
{
|
||||
"onboarding": {
|
||||
"title": "Welcome to My Linkding",
|
||||
"subtitle": "An application to manage your bookmarks.",
|
||||
"start": "Start",
|
||||
"next": "Next",
|
||||
"previous": "Previous",
|
||||
"serverRequired": "Servidor requerido",
|
||||
"serverRequiredDescription": "My Linkding it's not an standalone app, it requires the Linkding server to work.\nIn order to use this application, you must deploy Linkding on your home server, VPS or any other computer.",
|
||||
"installationInstructions": "Check the installation instructions on the official GitHub repository.",
|
||||
"serverRunningConfirmation": "I confirm that I have an instance of the Linkding server already running."
|
||||
},
|
||||
"connect": {
|
||||
"connect": "Connect",
|
||||
"connecting": "Connecting...",
|
||||
@@ -6,5 +17,9 @@
|
||||
},
|
||||
"links": {
|
||||
"links": "Links"
|
||||
},
|
||||
"settings": {
|
||||
"settings": "Settings",
|
||||
"disconnectFromServer": "Disconnect from server"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,15 @@
|
||||
{
|
||||
"onboarding": {
|
||||
"title": "Bienvenido a My Linkding",
|
||||
"subtitle": "Una aplicación para gestionar tus enlaces favoritos.",
|
||||
"start": "Comenzar",
|
||||
"next": "Siguiente",
|
||||
"previous": "Anterior",
|
||||
"serverRequired": "Servidor requerido",
|
||||
"serverRequiredDescription": "My Linkding no es una aplicación independiente, requiere el servidor Linkding para funcionar.\nPara utilizar esta aplicación, debe instalar Linkding en su servidor doméstico, VPS o cualquier otro ordenador.",
|
||||
"installationInstructions": "Mira las instrucciones de instalación en el repositorio oficial en GitHub.",
|
||||
"serverRunningConfirmation": "Confirmo que tengo una instancia del servidor Linkding ya en funcionamiento."
|
||||
},
|
||||
"connect": {
|
||||
"connect": "Conectar",
|
||||
"connecting": "Conectando...",
|
||||
@@ -6,5 +17,9 @@
|
||||
},
|
||||
"links": {
|
||||
"links": "Enlaces"
|
||||
},
|
||||
"settings": {
|
||||
"settings": "Ajustes",
|
||||
"disconnectFromServer": "Desconectar del servidor"
|
||||
}
|
||||
}
|
||||
@@ -18,4 +18,9 @@ class ApiClientProvider extends _$ApiClientProvider {
|
||||
void setApiClient(ApiClient client) {
|
||||
state = client;
|
||||
}
|
||||
|
||||
void disconnectApiClient() {
|
||||
state = null;
|
||||
ref.read(serverInstancesProvider.notifier).removeServerInstances();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'api_client_provider.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$apiClientProviderHash() => r'eff6aeacbfe369f2204d77f4884cc9d78ecf1e27';
|
||||
String _$apiClientProviderHash() => r'8c44873c4e0758acfcd64b181134b80a43327f46';
|
||||
|
||||
/// See also [ApiClientProvider].
|
||||
@ProviderFor(ApiClientProvider)
|
||||
|
||||
@@ -12,7 +12,7 @@ GoRouter router(RouterRef ref) {
|
||||
return GoRouter(
|
||||
redirect: (context, state) {
|
||||
if (ref.watch(apiClientProviderProvider) == null) {
|
||||
return RoutesPaths.connect;
|
||||
return RoutesPaths.onboarding;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'router_provider.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$routerHash() => r'47e3f3d747dcb7b2543c73209f8a2f5561eb6ff7';
|
||||
String _$routerHash() => r'78eb4c32cddebb29e3029e0eeaeb0f4c40d77012';
|
||||
|
||||
/// See also [router].
|
||||
@ProviderFor(router)
|
||||
|
||||
@@ -4,8 +4,6 @@ import 'package:my_linkding/config/shared_preferences_keys.dart';
|
||||
import 'package:my_linkding/providers/shared_preferences_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import 'package:my_linkding/services/api_client.dart';
|
||||
import 'package:my_linkding/providers/api_client_provider.dart';
|
||||
import 'package:my_linkding/models/server_instance.dart';
|
||||
|
||||
part 'server_instances_provider.g.dart';
|
||||
@@ -45,4 +43,9 @@ class ServerInstances extends _$ServerInstances {
|
||||
final stringList = instances.map((i) => jsonEncode(i.toJson())).toList();
|
||||
ref.read(sharedPreferencesProvider).setStringList(SharedPreferencesKeys.serversInstances, stringList);
|
||||
}
|
||||
|
||||
void removeServerInstances() {
|
||||
state = [];
|
||||
ref.read(sharedPreferencesProvider).remove(SharedPreferencesKeys.serversInstances);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'server_instances_provider.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$serverInstancesHash() => r'82b7d3367afbe5c19ad0238977e5df35fac3499b';
|
||||
String _$serverInstancesHash() => r'ee41f5a717b9f779aa4319cc711b479a47c1c9ef';
|
||||
|
||||
/// See also [ServerInstances].
|
||||
@ProviderFor(ServerInstances)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class RoutesPaths {
|
||||
static const connect = "/connect";
|
||||
static const onboarding = "/onboarding";
|
||||
static const links = "/links";
|
||||
static const search = "/search";
|
||||
static const settings = "/settings";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:my_linkding/screens/connect/ui/connect.dart';
|
||||
import 'package:my_linkding/screens/links/ui/links.dart';
|
||||
import 'package:my_linkding/screens/onboarding/ui/onboarding.dart';
|
||||
import 'package:my_linkding/screens/search/ui/search.dart';
|
||||
import 'package:my_linkding/screens/settings/ui/settings.dart';
|
||||
import 'package:my_linkding/widgets/layout.dart';
|
||||
@@ -16,8 +16,8 @@ final settingsNavigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
final List<RouteBase> appRoutes = [
|
||||
GoRoute(
|
||||
path: RoutesPaths.connect,
|
||||
builder: (context, state) => const Connect(),
|
||||
path: RoutesPaths.onboarding,
|
||||
builder: (context, state) => const Onboarding(),
|
||||
),
|
||||
StatefulShellRoute.indexedStack(
|
||||
builder: (context, state, navigationShell) => Layout(
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'connect_provider.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$connectToServerHash() => r'af66fee9a4bf26aba08b27ff5a7fe4643215117a';
|
||||
String _$connectToServerHash() => r'c40898fd5dd6dd7507140c7a69a6f336a56e30c0';
|
||||
|
||||
/// See also [connectToServer].
|
||||
@ProviderFor(connectToServer)
|
||||
|
||||
16
lib/screens/onboarding/model/onboarding.model.dart
Normal file
16
lib/screens/onboarding/model/onboarding.model.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OnboardingModel {
|
||||
final PageController pageController;
|
||||
final bool confirmServerRunning;
|
||||
|
||||
OnboardingModel({
|
||||
required this.pageController,
|
||||
required this.confirmServerRunning,
|
||||
});
|
||||
|
||||
OnboardingModel toggleConfirmServerRunning(bool newValue) => OnboardingModel(
|
||||
pageController: pageController,
|
||||
confirmServerRunning: newValue,
|
||||
);
|
||||
}
|
||||
35
lib/screens/onboarding/provider/onboarding.provider.dart
Normal file
35
lib/screens/onboarding/provider/onboarding.provider.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import 'package:my_linkding/screens/onboarding/model/onboarding.model.dart';
|
||||
|
||||
part 'onboarding.provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
class Onboarding extends _$Onboarding {
|
||||
@override
|
||||
OnboardingModel build() {
|
||||
return OnboardingModel(
|
||||
pageController: PageController(),
|
||||
confirmServerRunning: false,
|
||||
);
|
||||
}
|
||||
|
||||
void nextPage() {
|
||||
state.pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.ease,
|
||||
);
|
||||
}
|
||||
|
||||
void previousPage() {
|
||||
state.pageController.previousPage(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.ease,
|
||||
);
|
||||
}
|
||||
|
||||
void confirmServerRunning() {
|
||||
state = state.toggleConfirmServerRunning(!state.confirmServerRunning);
|
||||
}
|
||||
}
|
||||
25
lib/screens/onboarding/provider/onboarding.provider.g.dart
Normal file
25
lib/screens/onboarding/provider/onboarding.provider.g.dart
Normal file
@@ -0,0 +1,25 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'onboarding.provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$onboardingHash() => r'5c876d53acbca92ab15630516099700609aa4f89';
|
||||
|
||||
/// See also [Onboarding].
|
||||
@ProviderFor(Onboarding)
|
||||
final onboardingProvider =
|
||||
AutoDisposeNotifierProvider<Onboarding, OnboardingModel>.internal(
|
||||
Onboarding.new,
|
||||
name: r'onboardingProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$onboardingHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$Onboarding = AutoDisposeNotifier<OnboardingModel>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
29
lib/screens/onboarding/ui/onboarding.dart
Normal file
29
lib/screens/onboarding/ui/onboarding.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:my_linkding/screens/onboarding/provider/onboarding.provider.dart';
|
||||
import 'package:my_linkding/screens/onboarding/ui/server_required.dart';
|
||||
import 'package:my_linkding/screens/onboarding/ui/welcome.dart';
|
||||
import 'package:my_linkding/widgets/system_overlay_style.dart';
|
||||
|
||||
class Onboarding extends ConsumerWidget {
|
||||
const Onboarding({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return OverlayStyle(
|
||||
child: Scaffold(
|
||||
body: SafeArea(
|
||||
child: PageView(
|
||||
controller: ref.watch(onboardingProvider).pageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: const [
|
||||
OnboardingWelcome(),
|
||||
OnboardingServerRequired(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
132
lib/screens/onboarding/ui/server_required.dart
Normal file
132
lib/screens/onboarding/ui/server_required.dart
Normal file
@@ -0,0 +1,132 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
import 'package:my_linkding/screens/onboarding/provider/onboarding.provider.dart';
|
||||
|
||||
import 'package:my_linkding/i18n/strings.g.dart';
|
||||
|
||||
class OnboardingServerRequired extends ConsumerWidget {
|
||||
const OnboardingServerRequired({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.dns_rounded,
|
||||
size: 50,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
t.onboarding.serverRequired,
|
||||
style: const TextStyle(fontSize: 28),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
t.onboarding.serverRequiredDescription,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(height: 24),
|
||||
Card(
|
||||
child: InkWell(
|
||||
onTap: () => {},
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/resources/github.svg',
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
const SizedBox(width: 24),
|
||||
Flexible(
|
||||
child: Text(
|
||||
t.onboarding.installationInstructions,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
ListTile(
|
||||
contentPadding: const EdgeInsets.all(8),
|
||||
leading: Checkbox(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
value: ref.watch(onboardingProvider).confirmServerRunning,
|
||||
onChanged: (_) => ref.read(onboardingProvider.notifier).confirmServerRunning(),
|
||||
),
|
||||
title: Text(
|
||||
t.onboarding.serverRunningConfirmation,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
onTap: () => ref.read(onboardingProvider.notifier).confirmServerRunning(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
FilledButton(
|
||||
onPressed: () => ref.read(onboardingProvider.notifier).previousPage(),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.arrow_back_rounded),
|
||||
const SizedBox(width: 8),
|
||||
Text(t.onboarding.previous),
|
||||
],
|
||||
),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: ref.watch(onboardingProvider).confirmServerRunning == true
|
||||
? () => ref.read(onboardingProvider.notifier).nextPage()
|
||||
: null,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(t.onboarding.next),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.arrow_forward_rounded),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
79
lib/screens/onboarding/ui/welcome.dart
Normal file
79
lib/screens/onboarding/ui/welcome.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:my_linkding/i18n/strings.g.dart';
|
||||
import 'package:my_linkding/screens/onboarding/provider/onboarding.provider.dart';
|
||||
|
||||
class OnboardingWelcome extends ConsumerWidget {
|
||||
const OnboardingWelcome({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
final height = MediaQuery.of(context).size.height;
|
||||
|
||||
final iconSize = width > height ? height : width;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
color: Colors.red,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
t.onboarding.title,
|
||||
style: const TextStyle(fontSize: 28),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
t.onboarding.subtitle,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const SizedBox(),
|
||||
FilledButton(
|
||||
onPressed: () => ref.read(onboardingProvider.notifier).nextPage(),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(t.onboarding.start),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.arrow_forward_rounded),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Center(
|
||||
child: Transform.rotate(
|
||||
angle: 0.7,
|
||||
child: Icon(
|
||||
Icons.link_rounded,
|
||||
size: iconSize - 48,
|
||||
color: Theme.of(context).colorScheme.secondary.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
class Settings extends StatelessWidget {
|
||||
import 'package:my_linkding/i18n/strings.g.dart';
|
||||
import 'package:my_linkding/providers/api_client_provider.dart';
|
||||
|
||||
class Settings extends ConsumerWidget {
|
||||
const Settings({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: NestedScrollView(
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) => [
|
||||
SliverOverlapAbsorber(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
sliver: SliverAppBar.large(
|
||||
pinned: true,
|
||||
floating: true,
|
||||
centerTitle: false,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
title: Text("Settings"),
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(t.settings.settings),
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
FilledButton.icon(
|
||||
onPressed: () => ref.read(apiClientProviderProvider.notifier).disconnectApiClient(),
|
||||
icon: const Icon(Icons.clear_rounded),
|
||||
label: Text(
|
||||
t.settings.disconnectFromServer,
|
||||
),
|
||||
),
|
||||
],
|
||||
body: SafeArea(
|
||||
top: false,
|
||||
bottom: false,
|
||||
child: Builder(
|
||||
builder: (context) => CustomScrollView(
|
||||
slivers: [
|
||||
SliverOverlapInjector(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user