scaling the timeline

This commit is contained in:
zoe 2022-07-03 15:47:24 +02:00
parent c63f062640
commit ee081de0ab
14 changed files with 202 additions and 63 deletions

View file

@ -1,4 +1,7 @@
import 'package:flutter/painting.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../global.dart' as global;
enum Settings { enum Settings {
instanceUrl, instanceUrl,
@ -38,3 +41,20 @@ Future<String> loadAuthCode() async {
} }
return code; return code;
} }
Future<bool> saveLocale(String locale) async {
final prefs = await SharedPreferences.getInstance();
return await prefs.setString("active-locale", locale);
}
Future<Locale> loadLocale() async {
final prefs = await SharedPreferences.getInstance();
String? locale = prefs.getString("active-locale");
if (locale == null) {
if (global.availableLocales.contains(Locale(Intl.systemLocale))) {
return Locale(Intl.systemLocale);
}
return const Locale("en");
}
return Locale(locale);
}

View file

@ -0,0 +1 @@

View file

@ -1,3 +1,5 @@
import 'package:flutter/painting.dart';
const String name = "slothmu"; const String name = "slothmu";
const String version = "v0.1 'not even alpha'"; const String version = "v0.1 'not even alpha'";
const String useragent = "$name/$version"; const String useragent = "$name/$version";
@ -8,3 +10,4 @@ const Map<String, String> defaultHeaders = {
"Content-Type": "application/json" "Content-Type": "application/json"
}; };
const List<String> bad = ["gab.com", "spinster.xyz", "truthsocial.com"]; const List<String> bad = ["gab.com", "spinster.xyz", "truthsocial.com"];
const List<Locale> availableLocales = [Locale("en"), Locale("de")];

14
lib/i18n/de.json Normal file
View file

@ -0,0 +1,14 @@
{
"greeting": "hallo!",
"instance-url": "anbieter url",
"instance-url-example": "beispiel.de",
"authorize-in-browser": "im browser autorisieren",
"login-failed-snackbar-text": "login fehlgeschlagen!",
"back-button": "zurück",
"confirm-button": "bestätigen",
"timeline" : "timeline",
"chat": "chat",
"notifications": "benachrichtigungen",
"settings": "einstellungen"
}

View file

@ -1,13 +0,0 @@
{
"greeting": "hallo!",
"user-id-not-valid": "hmm... die id sieht nicht ganz richtig aus...",
"user-id": "nutzer id",
"user-id-example": "nutzer@beispiel.de",
"authorize-in-browser": "im browser autorisieren",
"login-failed-snackbar-text": "login fehlgeschlagen!",
"back-button": "zurück",
"confirm-button": "bestätigen",
"copy-code-from-browser": "bitte den code aus dem browser hierhin kopieren.",
"code-hint": "code"
}

14
lib/i18n/en.json Normal file
View file

@ -0,0 +1,14 @@
{
"greeting": "hello!",
"instance-url": "instance url",
"instance-url-example": "example.com",
"authorize-in-browser": "authorize in browser",
"login-failed-snackbar-text": "login failed!",
"back-button": "back",
"confirm-button": "confirm",
"timeline" : "timeline",
"chat": "chat",
"notifications": "notifications",
"settings": "settings"
}

View file

@ -1,13 +0,0 @@
{
"greeting": "hello!",
"user-id-not-valid": "sorry, this user id doesn't look quite right... ",
"user-id": "user id",
"user-id-example": "user@example.com",
"authorize-in-browser": "authorize in browser",
"login-failed-snackbar-text": "login failed!",
"back-button": "back",
"confirm-button": "confirm",
"copy-code-from-browser": "please copy the code from your browser here!",
"code-hint": "code"
}

View file

@ -6,16 +6,20 @@ import 'pages/login.dart';
import 'business_logic/settings.dart' as settings; import 'business_logic/settings.dart' as settings;
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'themes/themes.dart' as themes; import 'themes/themes.dart' as themes;
import 'global.dart' as global;
String _initRoute = "/"; String _initRoute = "/";
ThemeData theme = themes.getTheme(themes.available[0]); ThemeData theme = themes.getTheme(themes.available[0]);
Locale activeLocale = const Locale("en");
void main() async { void main() async {
Intl.defaultLocale = 'en_US'; Intl.defaultLocale = "en";
await settings.saveLocale("en");
activeLocale = await settings.loadLocale();
// check if all information is available // check if all information is available
if (await settings.loadAuthCode() == "") { if (await settings.loadAuthCode() == "") {
_initRoute = "/login"; _initRoute = "/";
} }
runApp(const Slothmu()); runApp(const Slothmu());
} }
@ -28,16 +32,13 @@ class Slothmu extends StatefulWidget {
} }
class _SlothmuState extends State<Slothmu> { class _SlothmuState extends State<Slothmu> {
List<Locale> supported = const [
Locale("en", "US"),
Locale("de", "DE"),
];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
LocalJsonLocalization.delegate.directories = ['lib/i18n']; LocalJsonLocalization.delegate.directories = ['lib/i18n'];
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
supportedLocales: supported, locale: activeLocale,
supportedLocales: global.availableLocales,
localizationsDelegates: [ localizationsDelegates: [
GlobalCupertinoLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,

View file

@ -1,9 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:slothmu/business_logic/user.dart';
import 'package:localization/localization.dart'; import 'package:localization/localization.dart';
import '../business_logic/auth/oauth.dart' as oauth; import '../business_logic/auth/oauth.dart' as oauth;
import '../business_logic/settings.dart' as settings; import '../business_logic/settings.dart' as settings;
import '../business_logic/user.dart' as user;
class Login extends StatefulWidget { class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key); const Login({Key? key}) : super(key: key);
@ -47,23 +45,15 @@ class _LoginFormState extends State<LoginForm> {
Text("greeting".i18n(), style: Theme.of(context).textTheme.headline1), Text("greeting".i18n(), style: Theme.of(context).textTheme.headline1),
TextFormField( TextFormField(
onSaved: (value) async { onSaved: (value) async {
await settings await settings.saveInstanceUrl(value!);
.saveInstanceUrl(user.urlFromUsername(name: value!));
await settings.saveUsername(user.userFromUsername(name: value));
}, },
decoration: InputDecoration( decoration: InputDecoration(
labelText: "user-id".i18n(), labelText: "instance-url".i18n(),
hintText: "user-id-example".i18n(), hintText: "instance-url-example".i18n(),
icon: const Icon(Icons.person), icon: const Icon(Icons.home),
prefixText: "@", prefixText: "https://",
), ),
autofocus: true, autofocus: true,
validator: (value) {
if (value!.isEmpty || !isValidUsername(name: value)) {
return "user-id-not-valid".i18n();
}
return null;
},
), ),
TextButton.icon( TextButton.icon(
onPressed: () { onPressed: () {
@ -76,8 +66,7 @@ class _LoginFormState extends State<LoginForm> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) => const AuthPage(),
const AuthPage(baseurl: "kittycat.homes"),
)); ));
} }
}, },
@ -93,7 +82,7 @@ class _LoginFormState extends State<LoginForm> {
page that handles authenticating user page that handles authenticating user
*/ */
class AuthPage extends StatefulWidget { class AuthPage extends StatefulWidget {
const AuthPage({Key? key, required String baseurl}) : super(key: key); const AuthPage({Key? key}) : super(key: key);
@override @override
State<AuthPage> createState() => _AuthPageState(); State<AuthPage> createState() => _AuthPageState();

View file

@ -1,9 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:slothmu/partials/post.dart';
import 'package:slothmu/partials/thread.dart';
Widget timeline(context) { Widget timeline(context) {
return Padding( return Container(
padding: const EdgeInsets.all(24), child: ListView(
child: Column( padding: const EdgeInsets.fromLTRB(24, 0, 24, 64),
children: [], addAutomaticKeepAlives: false,
)); children: [Thread(), Thread(), Thread()],
),
);
} }

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:localization/localization.dart';
import 'package:slothmu/pages/chat/chat.dart'; import 'package:slothmu/pages/chat/chat.dart';
import 'package:slothmu/pages/notifications/notifications.dart'; import 'package:slothmu/pages/notifications/notifications.dart';
import 'package:slothmu/pages/timeline/timeline.dart'; import 'package:slothmu/pages/timeline/timeline.dart';
@ -47,13 +48,16 @@ class _MainScaffoldState extends State<MainScaffold> {
onDestinationSelected: (index) => onDestinationSelected: (index) =>
setState(() => this.index = index), setState(() => this.index = index),
selectedIndex: index, selectedIndex: index,
destinations: const [ destinations: [
NavigationDestination(icon: Icon(Icons.forum), label: "Timeline"),
NavigationDestination(icon: Icon(Icons.chat), label: "Chat"),
NavigationDestination( NavigationDestination(
icon: Icon(Icons.notifications), label: "Notifications"), icon: const Icon(Icons.forum), label: "timeline".i18n()),
NavigationDestination( NavigationDestination(
icon: Icon(Icons.settings), label: "Settings"), icon: const Icon(Icons.chat), label: "chat".i18n()),
NavigationDestination(
icon: const Icon(Icons.notifications),
label: "notifications".i18n()),
NavigationDestination(
icon: const Icon(Icons.settings), label: "settings".i18n()),
]), ]),
), ),
); );

82
lib/partials/post.dart Normal file
View file

@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
class Post extends StatefulWidget {
const Post({Key? key}) : super(key: key);
@override
State<Post> createState() => _PostState();
}
class _PostState extends State<Post> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
const Icon(
Icons.face,
size: 64,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"first name display last name name",
style: Theme.of(context).textTheme.titleMedium,
),
Text(
"@alice_exampleuser@example.com",
style: Theme.of(context).textTheme.bodySmall,
),
],
),
],
),
postBody(context),
postActionBar(context),
],
);
}
}
Widget postBody(context) {
return Container(
padding: const EdgeInsets.fromLTRB(24, 6, 6, 6),
decoration: BoxDecoration(
border: Border(
left: BorderSide(color: Theme.of(context).colorScheme.onSurface),
),
),
child: RichText(
textAlign: TextAlign.start,
text: const TextSpan(
text:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Risus commodo viverra maecenas accumsan lacus vel facilisis volutpat est. Diam in arcu cursus euismod quis viverra. Elementum sagittis vitae et leo duis."),
),
);
}
Widget postActionBar(context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.reply),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.repeat),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.favorite_outline),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_horiz),
)
],
);
}

35
lib/partials/thread.dart Normal file
View file

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:slothmu/partials/post.dart';
class Thread extends StatefulWidget {
const Thread({Key? key}) : super(key: key);
@override
State<Thread> createState() => _ThreadState();
}
class _ThreadState extends State<Thread> {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(24),
width: MediaQuery.of(context).size.width / 1.2,
constraints: const BoxConstraints(maxWidth: 1000, minWidth: 375),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
border: Border.symmetric(
horizontal: BorderSide(
color: Theme.of(context).colorScheme.background,
width: 12)),
),
child: Column(
children: [Post(), Post(), Post()],
),
),
],
);
}
}

View file

@ -68,8 +68,6 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
assets: assets:
- lib/i18n/ - lib/i18n/
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware # https://flutter.dev/assets-and-images/#resolution-aware