refactor settings

This commit is contained in:
zoe 2022-08-12 19:00:09 +02:00
parent 2ca8c6b83e
commit 2a1511ab9a
8 changed files with 100 additions and 143 deletions

View File

@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../global.dart' as global; import '../../global.dart' as global;
import '../../business_logic/settings.dart' as settings;
import 'package:shelf/shelf.dart'; import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:shelf/shelf_io.dart' as shelf_io;
@ -29,7 +28,7 @@ class App {
redirectUri: json["redirect_uri"].toString(), redirectUri: json["redirect_uri"].toString(),
clientId: json["client_id"].toString(), clientId: json["client_id"].toString(),
clientSecret: json["client_secret"].toString()); clientSecret: json["client_secret"].toString());
settings.saveApp(app); global.settings!.saveApp(app);
return app; return app;
} }
} }
@ -38,7 +37,7 @@ Response readAuthcode(Request request) {
Map<String, String> params = request.url.queryParameters; Map<String, String> params = request.url.queryParameters;
if (params.containsKey("code") && params["code"] != null) { if (params.containsKey("code") && params["code"] != null) {
String code = params["code"].toString(); String code = params["code"].toString();
settings.saveAuthCode(code); global.settings!.saveAuthCode(code);
} }
return Response(308, return Response(308,
headers: {"Content-Type": "text/html; charset=UTF-8"}, headers: {"Content-Type": "text/html; charset=UTF-8"},
@ -54,7 +53,7 @@ Future<int> handleFullOauth() async {
return response.statusCode; return response.statusCode;
} }
await settings.saveAuthCode(""); await global.settings!.saveAuthCode("");
var handler = const Pipeline().addHandler(readAuthcode); var handler = const Pipeline().addHandler(readAuthcode);
var server = await shelf_io.serve(handler, 'localhost', 1312); var server = await shelf_io.serve(handler, 'localhost', 1312);
await pollCode(); await pollCode();
@ -70,13 +69,13 @@ Future<String> pollCode() async {
String code = ""; String code = "";
while (code == "") { while (code == "") {
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
code = await settings.loadAuthCode(); code = global.settings!.authCode;
} }
return code; return code;
} }
Future<http.Response> doOauthFlow() async { Future<http.Response> doOauthFlow() async {
String url = await settings.loadInstanceUrl(); String url = global.settings!.instanceUrl;
try { try {
http.Response response = await registerApp(url); http.Response response = await registerApp(url);
openBrowserForAuthCode(url, App.fromJson(jsonDecode(response.body))); openBrowserForAuthCode(url, App.fromJson(jsonDecode(response.body)));
@ -121,10 +120,10 @@ void openBrowserForAuthCode(String baseurl, App app) {
} }
Future<int> refreshToken() async { Future<int> refreshToken() async {
final authCode = await settings.loadAuthCode(); final authCode = global.settings!.authCode;
final appId = await settings.loadClientId(); final appId = global.settings!.clientId;
final clientSecret = await settings.loadClientSecret(); final clientSecret = global.settings!.clientSecret;
final baseurl = await settings.loadInstanceUrl(); final baseurl = global.settings!.instanceUrl;
Uri url = Uri.https(baseurl, "/oauth/token"); Uri url = Uri.https(baseurl, "/oauth/token");
final response = await http.post( final response = await http.post(
@ -142,7 +141,7 @@ Future<int> refreshToken() async {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final dec = jsonDecode(response.body); final dec = jsonDecode(response.body);
final accessToken = dec["access_token"]!; final accessToken = dec["access_token"]!;
await settings.saveToken(accessToken); await global.settings!.saveToken(accessToken);
} }
return response.statusCode; return response.statusCode;
} }

View File

@ -1,112 +1,74 @@
import 'package:flutter/painting.dart'; 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;
import '../business_logic/auth/oauth.dart' as oauth; import '../business_logic/auth/oauth.dart' as oauth;
enum Settings { class Settings {
instanceUrl, late String instanceUrl;
username, static const String instanceUrlKey = "instance-url";
} late String authCode;
static const String authCodeKey = "authcode";
late Locale locale;
static const localeKey = "active-locale";
late String clientSecret;
static const clientSecretKey = "client-secret";
late String clientId;
static const clientIdKey = "client-id";
late String token;
static const tokenKey = "access-token";
late int batchSize;
static const batchSizeKey = "post-batch-size";
late SharedPreferences prefs;
Future<bool> saveInstanceUrl(String url) async { Settings._create();
final prefs = await SharedPreferences.getInstance();
return await prefs.setString("instance-url", url);
}
Future<String> loadInstanceUrl() async { static Future<Settings> create() async {
final prefs = await SharedPreferences.getInstance(); Settings settings = Settings._create();
String? possibleReturn = prefs.getString("instance-url");
if (possibleReturn == null) {
return "example.com";
} else {
return possibleReturn;
}
}
Future<bool> saveUsername(String username) async { settings.prefs = await SharedPreferences.getInstance();
final prefs = await SharedPreferences.getInstance(); settings.instanceUrl =
return await prefs.setString("username", username); settings.prefs.getString(instanceUrlKey) ?? "example.com";
} settings.authCode = settings.prefs.getString(authCodeKey) ?? "";
settings.locale = Locale(settings.prefs.getString(localeKey) ?? "en");
Future<bool> saveAuthCode(String code) async { settings.clientSecret = settings.prefs.getString(clientSecretKey) ?? "";
final prefs = await SharedPreferences.getInstance(); settings.clientId = settings.prefs.getString(clientIdKey) ?? "";
return await prefs.setString("authcode", code); settings.token = settings.prefs.getString(tokenKey) ?? "";
} settings.batchSize = settings.prefs.getInt(batchSizeKey) ?? 20;
if (settings.batchSize < 5) {
Future<String> loadAuthCode() async { settings.batchSize = 5;
final prefs = await SharedPreferences.getInstance();
String? code = prefs.getString("authcode");
if (code == null) {
return "";
}
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 settings;
} }
return Locale(locale);
}
Future<void> saveApp(oauth.App app) async { Future<bool> saveInstanceUrl(String url) async {
final prefs = await SharedPreferences.getInstance(); instanceUrl = url;
prefs.setString("client-secret", app.clientSecret); return await prefs.setString(instanceUrlKey, url);
prefs.setString("client-id", app.clientId); }
}
Future<String> loadClientSecret() async { Future<bool> saveAuthCode(String code) async {
final prefs = await SharedPreferences.getInstance(); authCode = code;
final secret = prefs.getString("client-secret"); return await prefs.setString(authCodeKey, code);
if (secret == null) { }
return "";
} else { Future<bool> saveLocale(String locale) async {
return secret; this.locale = Locale(locale);
return await prefs.setString(localeKey, locale);
}
Future<void> saveApp(oauth.App app) async {
clientId = app.clientId;
clientSecret = clientSecret;
prefs.setString(clientSecretKey, app.clientSecret);
prefs.setString(clientIdKey, app.clientId);
}
Future<bool> saveToken(String token) async {
this.token = token;
return await prefs.setString(tokenKey, token);
}
Future<bool> saveBatchSize(int size) async {
batchSize = size;
return await prefs.setInt(batchSizeKey, size);
} }
} }
Future<String> loadClientId() async {
final prefs = await SharedPreferences.getInstance();
final id = prefs.getString("client-id");
if (id == null) {
return "";
} else {
return id;
}
}
Future<bool> saveToken(String token) async {
final prefs = await SharedPreferences.getInstance();
return await prefs.setString("access-token", token);
}
Future<String> loadToken() async {
final prefs = await SharedPreferences.getInstance();
final id = prefs.getString("access-token");
if (id == null) {
return "";
} else {
return id;
}
}
Future<bool> saveBatchSize(int size) async {
final prefs = await SharedPreferences.getInstance();
return await prefs.setInt("post-batch-size", size);
}
Future<int> loadBatchSize() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getInt("post-batch-size") ?? 20;
}

View File

@ -2,7 +2,6 @@ import 'dart:convert';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:loris/business_logic/account/account.dart'; import 'package:loris/business_logic/account/account.dart';
import 'package:loris/business_logic/timeline/media.dart'; import 'package:loris/business_logic/timeline/media.dart';
import '../settings.dart' as settings;
import '../../global.dart' as global; import '../../global.dart' as global;
class TimelinePartModel { class TimelinePartModel {
@ -62,8 +61,8 @@ class PostModel implements Comparable {
} }
Future<ThreadModel> getThread() async { Future<ThreadModel> getThread() async {
final token = await settings.loadToken(); final token = global.settings!.token;
final baseUrl = await settings.loadInstanceUrl(); final baseUrl = global.settings!.instanceUrl;
Map<String, String> headers = {"Authorization": "Bearer $token"}; Map<String, String> headers = {"Authorization": "Bearer $token"};
headers.addAll(global.defaultHeaders); headers.addAll(global.defaultHeaders);
String currentId = reblogId ?? id; String currentId = reblogId ?? id;
@ -99,15 +98,15 @@ class ThreadModel {
} }
Future<List<ThreadModel>> getTimelineFromServer(String? index) async { Future<List<ThreadModel>> getTimelineFromServer(String? index) async {
final limit = await settings.loadBatchSize(); final limit = global.settings!.batchSize;
final token = await settings.loadToken(); final token = global.settings!.token;
Map<String, String> query = {"limit": limit.toString()}; Map<String, String> query = {"limit": limit.toString()};
if (index != null) { if (index != null) {
query.addAll({"max_id": index}); query.addAll({"max_id": index});
} }
final baseUrl = await settings.loadInstanceUrl(); final baseUrl = global.settings!.instanceUrl;
final url = Uri( final url = Uri(
scheme: "https", scheme: "https",
host: baseUrl, host: baseUrl,

View File

@ -1,4 +1,5 @@
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:loris/business_logic/settings.dart';
const String name = "loris"; const String name = "loris";
const String version = "v0.1 'is this thing on'"; const String version = "v0.1 'is this thing on'";
@ -14,3 +15,5 @@ const Map<String, String> defaultHeaders = {
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")]; const List<Locale> availableLocales = [Locale("en"), Locale("de")];
Settings? settings;

View File

@ -15,11 +15,11 @@ Locale activeLocale = const Locale("en");
void main() async { void main() async {
Intl.defaultLocale = "en"; Intl.defaultLocale = "en";
await settings.saveLocale("en"); global.settings = await settings.Settings.create();
activeLocale = await settings.loadLocale(); activeLocale = global.settings!.locale;
// check if all information is available // check if all information is available
if (await settings.loadAuthCode() == "") { if (global.settings!.authCode == "") {
_initRoute = "/login"; _initRoute = "/login";
} else { } else {
await oauth.refreshToken(); await oauth.refreshToken();

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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 '../global.dart' as global;
class Login extends StatefulWidget { class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key); const Login({Key? key}) : super(key: key);
@ -45,7 +45,7 @@ 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.saveInstanceUrl(value!); await global.settings!.saveInstanceUrl(value!);
}, },
decoration: InputDecoration( decoration: InputDecoration(
labelText: "instance-url".i18n(), labelText: "instance-url".i18n(),

View File

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:localization/localization.dart'; import 'package:localization/localization.dart';
import '../../business_logic/settings.dart' as settings; import '../../global.dart' as global;
class AccountSettings extends StatelessWidget { class AccountSettings extends StatelessWidget {
const AccountSettings({Key? key}) : super(key: key); const AccountSettings({Key? key}) : super(key: key);
@ -20,19 +20,15 @@ class LogoutButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String url;
if (global.settings!.instanceUrl.isEmpty) {
url = "no-instance".i18n();
} else {
url = global.settings!.instanceUrl;
}
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
FutureBuilder<String>( Text(url),
future: settings.loadInstanceUrl(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data ?? "no-instance".i18n());
} else {
return const CircularProgressIndicator();
}
},
),
TextButton.icon( TextButton.icon(
onPressed: () { onPressed: () {
logout(); logout();
@ -45,6 +41,6 @@ class LogoutButton extends StatelessWidget {
} }
void logout() async { void logout() async {
await settings.saveAuthCode(""); await global.settings!.saveAuthCode("");
exit(0); exit(0);
} }

View File

@ -1,5 +1,8 @@
// ignore_for_file: unused_import
import 'package:localization/localization.dart'; import 'package:localization/localization.dart';
import '../../business_logic/settings.dart' as settings; import '../../business_logic/settings.dart' as settings;
import '../../global.dart' as global;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppSettings extends StatelessWidget { class AppSettings extends StatelessWidget {
@ -9,14 +12,9 @@ class AppSettings extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
FutureBuilder<int>( PostBatchSlider(
future: settings.loadBatchSize(), initialSize: global.settings!.batchSize,
builder: ((context, snapshot) { )
if (snapshot.hasData) {
return PostBatchSlider(initialSize: snapshot.data ?? 5);
}
return const CircularProgressIndicator.adaptive();
})),
], ],
); );
} }
@ -54,7 +52,7 @@ class _PostBatchSliderState extends State<PostBatchSlider> {
min: 5, min: 5,
max: 100, max: 100,
onChanged: ((value) { onChanged: ((value) {
settings.saveBatchSize(value.toInt()); global.settings!.saveBatchSize(value.toInt());
setState(() { setState(() {
size = value.toInt(); size = value.toInt();
}); });