Preclean
This commit is contained in:
@@ -1,68 +0,0 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:imagini/bloc/bloc-prov.dart';
|
||||
|
||||
/// A Flutter [Widget] that merges multiple [BlocProvider] widgets into one widget tree.
|
||||
///
|
||||
/// [BlocProviderTree] improves the readability and eliminates the need
|
||||
/// to nest multiple [BlocProviders].
|
||||
///
|
||||
/// By using [BlocProviderTree] we can go from:
|
||||
///
|
||||
/// ```dart
|
||||
/// BlocProvider<BlocA>(
|
||||
/// bloc: BlocA(),
|
||||
/// child: BlocProvider<BlocB>(
|
||||
/// bloc: BlocB(),
|
||||
/// child: BlocProvider<BlocC>(
|
||||
/// value: BlocC(),
|
||||
/// child: ChildA(),
|
||||
/// )
|
||||
/// )
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// to:
|
||||
///
|
||||
/// ```dart
|
||||
/// BlocProviderTree(
|
||||
/// blocProviders: [
|
||||
/// BlocProvider<BlocA>(bloc: BlocA()),
|
||||
/// BlocProvider<BlocB>(bloc: BlocB()),
|
||||
/// BlocProvider<BlocC>(bloc: BlocC()),
|
||||
/// ],
|
||||
/// child: ChildA(),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// [BlocProviderTree] converts the [BlocProvider] list
|
||||
/// into a tree of nested [BlocProvider] widgets.
|
||||
/// As a result, the only advantage of using [BlocProviderTree] is improved
|
||||
/// readability due to the reduction in nesting and boilerplate.
|
||||
class BlocProviderTree extends StatelessWidget {
|
||||
/// The [BlocProvider] list which is converted into a tree of [BlocProvider] widgets.
|
||||
/// The tree of [BlocProvider] widgets is created in order meaning the first [BlocProvider]
|
||||
/// will be the top-most [BlocProvider] and the last [BlocProvider] will be a direct ancestor
|
||||
/// of the `child` [Widget].
|
||||
final List<BlocProvider> blocProviders;
|
||||
|
||||
/// The [Widget] and its descendants which will have access to every [Bloc] provided by `blocProviders`.
|
||||
/// This [Widget] will be a direct descendent of the last [BlocProvider] in `blocProviders`.
|
||||
final Widget child;
|
||||
|
||||
const BlocProviderTree({
|
||||
Key key,
|
||||
@required this.blocProviders,
|
||||
@required this.child,
|
||||
}) : assert(blocProviders != null),
|
||||
assert(child != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget tree = child;
|
||||
for (final blocProvider in blocProviders.reversed) {
|
||||
tree = blocProvider.copyWith(tree);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:imagini/bloc/bloc.dart';
|
||||
|
||||
/// A Flutter widget which provides a bloc to its children via `BlocProvider.of(context)`.
|
||||
/// It is used as a DI widget so that a single instance of a bloc can be provided
|
||||
/// to multiple widgets within a subtree.
|
||||
class BlocProvider<T extends Bloc> extends InheritedWidget {
|
||||
/// The [Bloc] which is to be made available throughout the subtree
|
||||
final T bloc;
|
||||
|
||||
/// The [Widget] and its descendants which will have access to the [Bloc].
|
||||
final Widget child;
|
||||
|
||||
BlocProvider({
|
||||
Key key,
|
||||
@required this.bloc,
|
||||
this.child,
|
||||
}) : assert(bloc != null),
|
||||
super(key: key, child: child);
|
||||
|
||||
/// Method that allows widgets to access the bloc as long as their `BuildContext`
|
||||
/// contains a `BlocProvider` instance.
|
||||
static T of<T extends Bloc>(BuildContext context) {
|
||||
final type = _typeOf<BlocProvider<T>>();
|
||||
final BlocProvider<T> provider = context
|
||||
.ancestorInheritedElementForWidgetOfExactType(type)
|
||||
?.widget as BlocProvider<T>;
|
||||
|
||||
if (provider == null) {
|
||||
throw FlutterError(
|
||||
"""
|
||||
BlocProvider.of() called with a context that does not contain a Bloc of type $T.
|
||||
No ancestor could be found starting from the context that was passed to BlocProvider.of<$T>().
|
||||
This can happen if the context you use comes from a widget above the BlocProvider.
|
||||
This can also happen if you used BlocProviderTree and didn\'t explicity provide
|
||||
the BlocProvider types: BlocProvider(bloc: $T()) instead of BlocProvider<$T>(bloc: $T()).
|
||||
The context used was: $context
|
||||
""",
|
||||
);
|
||||
}
|
||||
return provider?.bloc;
|
||||
}
|
||||
|
||||
/// Clone the current [BlocProvider] with a new child [Widget].
|
||||
/// All other values, including [Key] and [Bloc] are preserved.
|
||||
BlocProvider<T> copyWith(Widget child) {
|
||||
return BlocProvider<T>(
|
||||
key: key,
|
||||
bloc: bloc,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
/// Necessary to obtain generic [Type]
|
||||
/// https://github.com/dart-lang/sdk/issues/11923
|
||||
static Type _typeOf<T>() => T;
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(BlocProvider oldWidget) => false;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
abstract class Bloc {}
|
||||
@@ -1,5 +0,0 @@
|
||||
import 'package:imagini/bloc/bloc.dart';
|
||||
|
||||
class AuthBloc extends Bloc {
|
||||
AuthBloc();
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export 'auth-bloc.dart';
|
||||
export 'pref-bloc.dart';
|
||||
42
web_native/lib/blocs/login/bloc.dart
Normal file
42
web_native/lib/blocs/login/bloc.dart
Normal file
@@ -0,0 +1,42 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:imagini/blocs/login/events.dart';
|
||||
import 'package:imagini/blocs/login/states.dart';
|
||||
import 'package:imagini/services/api/api.dart';
|
||||
import 'package:imagini/services/api/exceptions.dart';
|
||||
|
||||
class LoginBloc extends Bloc<LoginEvents, LoginState> {
|
||||
final ImaginiAPI imaginiAPI;
|
||||
Map<String, String> loginResult;
|
||||
String exampleResult;
|
||||
|
||||
LoginBloc({ this.imaginiAPI }) : super(LoginInitState());
|
||||
|
||||
@override
|
||||
Stream<LoginState> mapEventToState(LoginEvents event) async* {
|
||||
switch (event) {
|
||||
case LoginEvents.loginResult:
|
||||
yield LoginLoading();
|
||||
try {
|
||||
// exampleResult = await imaginiAPI.exampleApi();
|
||||
loginResult = await imaginiAPI.loginAPI("admin", "admin");
|
||||
yield LoginSuccess();
|
||||
} on SocketException {
|
||||
yield LoginFailed(
|
||||
error: ConnectionRefusedException('No Internet'),
|
||||
);
|
||||
} on FormatException {
|
||||
yield LoginFailed(
|
||||
error: InvalidFormatException('Invalid Response Format'),
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
yield LoginFailed(
|
||||
error: UnknownException('Unknown Error'),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
web_native/lib/blocs/login/events.dart
Normal file
3
web_native/lib/blocs/login/events.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
enum LoginEvents {
|
||||
loginResult,
|
||||
}
|
||||
28
web_native/lib/blocs/login/states.dart
Normal file
28
web_native/lib/blocs/login/states.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
// import 'package:equatable/equatable.dart';
|
||||
//
|
||||
// abstract class LoginState extends Equatable {
|
||||
// @override
|
||||
// List<Object> get props => [];
|
||||
// }
|
||||
|
||||
abstract class LoginState {}
|
||||
|
||||
class LoginInitState extends LoginState {}
|
||||
|
||||
class LoginLoading extends LoginState {}
|
||||
|
||||
class LoginSuccess extends LoginState {}
|
||||
|
||||
class LoginNeeded extends LoginState {}
|
||||
|
||||
class LoginFailed extends LoginState {
|
||||
final error;
|
||||
LoginFailed({this.error});
|
||||
}
|
||||
|
||||
class LoginLoaded extends LoginState {}
|
||||
|
||||
class LoginListError extends LoginState {
|
||||
final error;
|
||||
LoginListError({this.error});
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import 'package:imagini/bloc/bloc.dart';
|
||||
|
||||
class PrefBloc extends Bloc {
|
||||
PrefBloc();
|
||||
}
|
||||
23
web_native/lib/blocs/theme/bloc.dart
Normal file
23
web_native/lib/blocs/theme/bloc.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:imagini/blocs/theme/events.dart';
|
||||
import 'package:imagini/blocs/theme/state.dart';
|
||||
import 'package:imagini/settings/app_themes.dart';
|
||||
|
||||
class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
|
||||
//
|
||||
ThemeBloc()
|
||||
: super(
|
||||
ThemeState(
|
||||
themeData: AppThemes.appThemeData[AppTheme.lightTheme],
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Stream<ThemeState> mapEventToState(ThemeEvent event) async* {
|
||||
if (event is ThemeEvent) {
|
||||
yield ThemeState(
|
||||
themeData: AppThemes.appThemeData[event.appTheme],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
6
web_native/lib/blocs/theme/events.dart
Normal file
6
web_native/lib/blocs/theme/events.dart
Normal file
@@ -0,0 +1,6 @@
|
||||
import 'package:imagini/settings/app_themes.dart';
|
||||
|
||||
class ThemeEvent {
|
||||
final AppTheme appTheme;
|
||||
ThemeEvent({this.appTheme});
|
||||
}
|
||||
6
web_native/lib/blocs/theme/state.dart
Normal file
6
web_native/lib/blocs/theme/state.dart
Normal file
@@ -0,0 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ThemeState {
|
||||
final ThemeData themeData;
|
||||
ThemeState({this.themeData});
|
||||
}
|
||||
@@ -1,27 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:imagini/theme/style.dart';
|
||||
import 'package:imagini/routes.dart';
|
||||
import 'package:imagini/bloc/bloc-prov-tree.dart';
|
||||
import 'package:imagini/bloc/bloc-prov.dart';
|
||||
import 'package:imagini/blocs/blocs.dart';
|
||||
import 'blocs/blocs.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
void main() {
|
||||
runApp(ExampleApp());
|
||||
import 'package:imagini/services/api/api.dart';
|
||||
import 'package:imagini/screens/login.dart';
|
||||
import 'package:imagini/blocs/login/bloc.dart';
|
||||
|
||||
import 'package:imagini/settings/preferences.dart';
|
||||
import 'package:imagini/blocs/theme/bloc.dart';
|
||||
import 'package:imagini/blocs/theme/state.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await Preferences.init();
|
||||
runApp(ImaginiApp());
|
||||
}
|
||||
class ExampleApp extends StatelessWidget {
|
||||
|
||||
class ImaginiApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProviderTree(
|
||||
blocProviders: <BlocProvider>[
|
||||
BlocProvider<AuthBloc>(bloc: AuthBloc()),
|
||||
BlocProvider<PrefBloc>(bloc: PrefBloc()),
|
||||
],
|
||||
child: MaterialApp(
|
||||
title: 'ExampleApp',
|
||||
theme: appTheme(),
|
||||
initialRoute: '/',
|
||||
routes: routes,
|
||||
return BlocProvider(
|
||||
create: (context) => ThemeBloc(),
|
||||
child: BlocBuilder<ThemeBloc, ThemeState>(builder: (BuildContext context, ThemeState themeState) {
|
||||
return MaterialApp(
|
||||
title: 'Imagini',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: themeState.themeData,
|
||||
home: BlocProvider(
|
||||
// create: (context) => LoginBloc(albumsRepo: AlbumServices()),
|
||||
create: (context) => LoginBloc(imaginiAPI: ImaginiAPI()),
|
||||
child: LoginScreen(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
70
web_native/lib/screens/login.dart
Normal file
70
web_native/lib/screens/login.dart
Normal file
@@ -0,0 +1,70 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:imagini/blocs/login/bloc.dart';
|
||||
import 'package:imagini/blocs/login/states.dart';
|
||||
import 'package:imagini/blocs/login/events.dart';
|
||||
import 'package:imagini/blocs/theme/bloc.dart';
|
||||
import 'package:imagini/blocs/theme/events.dart';
|
||||
import 'package:imagini/settings/preferences.dart';
|
||||
import 'package:imagini/settings/app_themes.dart';
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
@override
|
||||
_LoginScreenState createState() => _LoginScreenState();
|
||||
}
|
||||
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadTheme();
|
||||
_loadLogin();
|
||||
}
|
||||
|
||||
_loadTheme() async {
|
||||
context.read<ThemeBloc>().add(ThemeEvent(appTheme: Preferences.getTheme()));
|
||||
}
|
||||
|
||||
_loadLogin() async {
|
||||
context.read<LoginBloc>().add(LoginEvents.loginResult);
|
||||
}
|
||||
|
||||
_setTheme(bool darkTheme) async {
|
||||
AppTheme selectedTheme =
|
||||
darkTheme ? AppTheme.lightTheme : AppTheme.darkTheme;
|
||||
context.read<ThemeBloc>().add(ThemeEvent(appTheme: selectedTheme));
|
||||
Preferences.saveTheme(selectedTheme);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: _body(),
|
||||
);
|
||||
}
|
||||
|
||||
_body() {
|
||||
return BlocBuilder<LoginBloc, LoginState>(builder: (BuildContext context, LoginState state) {
|
||||
|
||||
// Set Theme
|
||||
_setTheme(true);
|
||||
|
||||
if (state is LoginNeeded) {
|
||||
// TODO: Load Login Form
|
||||
return Center( child: Text("Login Needed") );
|
||||
}
|
||||
if (state is LoginFailed) {
|
||||
// TODO: Update Form Failed
|
||||
return Center( child: Text("Login Failed: ${state.error.message.toString()}") );
|
||||
}
|
||||
if (state is LoginSuccess) {
|
||||
// TODO: Navigate to /Gallery
|
||||
return Center( child: Text("Login Success") );
|
||||
}
|
||||
|
||||
// TODO: Login Screen
|
||||
return Center( child: Text("Login Loading") );
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Body extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: RaisedButton(
|
||||
onPressed: () {
|
||||
// Go to Login Screen
|
||||
Navigator.pushNamed(context, '/Gallery');
|
||||
},
|
||||
child: Text('Login'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ class _GalleryScreenState extends State<GalleryScreen> {
|
||||
bloc: exampleBloc,
|
||||
child: PlatformScaffold(
|
||||
appBar: PlatformAppBar(
|
||||
title: Text('Gallerys'),
|
||||
title: Text('Gallery'),
|
||||
cupertino: (_, __) => CupertinoNavigationBarData(
|
||||
// Issue with cupertino where a bar with no transparency
|
||||
// will push the list down. Adding some alpha value fixes it (in a hacky way)
|
||||
59
web_native/lib/screens/old/login/components/body.dart
Normal file
59
web_native/lib/screens/old/login/components/body.dart
Normal file
@@ -0,0 +1,59 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Body extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Container(
|
||||
margin: EdgeInsets.fromLTRB(50, 0, 50, 0),
|
||||
height: 500,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: FittedBox(
|
||||
fit: BoxFit.contain,
|
||||
child: const FlutterLogo(),
|
||||
),
|
||||
width: 175,
|
||||
margin: EdgeInsets.fromLTRB(0, 0, 0, 50),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Server Address'
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Username / Email'
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
obscureText: true,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Password'
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
child: RaisedButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, '/Gallery');
|
||||
},
|
||||
child: Text('Login')
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,9 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||
return BlocProvider(
|
||||
bloc: LoginBloc(),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("Login"),
|
||||
),
|
||||
// appBar: AppBar(
|
||||
// title: Text("Login"),
|
||||
// ),
|
||||
body: Body(),
|
||||
),
|
||||
);
|
||||
@@ -1,38 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:imagini/screens/splash/components/body.dart';
|
||||
import 'package:imagini/screens/splash/splash-bloc.dart';
|
||||
import 'package:imagini/bloc/bloc-prov.dart';
|
||||
|
||||
class SplashScreen extends StatefulWidget {
|
||||
@override
|
||||
_SplashScreenState createState() => _SplashScreenState();
|
||||
}
|
||||
|
||||
class _SplashScreenState extends State<SplashScreen> {
|
||||
SplashBloc splashBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
splashBloc = SplashBloc();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
splashBloc.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
bloc: SplashBloc(),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("First Screen"),
|
||||
),
|
||||
body: Body(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
85
web_native/lib/services/api/api.dart
Normal file
85
web_native/lib/services/api/api.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
// import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
// import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
// if(kIsWeb) {
|
||||
// // Use web storage
|
||||
// } else {
|
||||
// // Use flutter_secure_storage
|
||||
// }
|
||||
|
||||
// final _storage = FlutterSecureStorage();
|
||||
|
||||
class ImaginiAPI {
|
||||
static const _baseUrl = "http://10.0.20.170:8484";
|
||||
// static const String _GET_ALBUMS = '/albums';
|
||||
|
||||
Future<String> exampleApi() async {
|
||||
http.Response response = await http.get(
|
||||
Uri.encodeFull("https://www.example.com/api"),
|
||||
);
|
||||
print("Status: ${response.statusCode.toString()}");
|
||||
print("Respone: ${response.body.toString()}");
|
||||
return response.body;
|
||||
}
|
||||
|
||||
Future<Map<String, String>> loginAPI(String user, String password) async {
|
||||
http.Response response = await http.post(
|
||||
Uri.encodeFull(_baseUrl + "/api/v1/Login"),
|
||||
body: jsonEncode(<String, String>{
|
||||
'user': user,
|
||||
'password': password,
|
||||
}),
|
||||
).timeout(Duration(seconds: 10));
|
||||
|
||||
|
||||
|
||||
// TODO:
|
||||
// - StatusCode:
|
||||
// - 405 (StatusMethodNotAllowed)
|
||||
// - 400 (StatusBadRequest)
|
||||
// - 401 (StatusUnauthorized)
|
||||
// -
|
||||
// -
|
||||
// -
|
||||
|
||||
String setCookieVal = response.headers["set-cookie"];
|
||||
List<Cookie> allCookies = setCookieVal.split(',')
|
||||
.map((cookie) => Cookie.fromSetCookieValue(cookie)).toList();
|
||||
|
||||
Cookie accessToken = allCookies.firstWhere((cookie) => cookie.name == "AccessToken");
|
||||
Cookie refreshToken = allCookies.firstWhere((cookie) => cookie.name == "RefreshToken");
|
||||
|
||||
print("Status: ${response.statusCode.toString()}");
|
||||
print("Body: ${response.body.toString()}");
|
||||
print("AccessToken: ${accessToken.toString()}");
|
||||
print("RefreshToken: ${refreshToken.toString()}");
|
||||
return response.headers;
|
||||
}
|
||||
|
||||
Future<String> mediaItemsAPI(String albumID, String tagID) async {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String> tagsAPI() async {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String> albumsAPI() async {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String> meAPI() async {
|
||||
return null;
|
||||
}
|
||||
|
||||
// API Calls:
|
||||
// - Login
|
||||
// - MediaItems
|
||||
// - Tags
|
||||
// - Albums
|
||||
// - Me
|
||||
}
|
||||
19
web_native/lib/services/api/exceptions.dart
Normal file
19
web_native/lib/services/api/exceptions.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
class ConnectionRefusedException {
|
||||
var message;
|
||||
ConnectionRefusedException(this.message);
|
||||
}
|
||||
|
||||
class NoServiceFoundException {
|
||||
var message;
|
||||
NoServiceFoundException(this.message);
|
||||
}
|
||||
|
||||
class InvalidFormatException {
|
||||
var message;
|
||||
InvalidFormatException(this.message);
|
||||
}
|
||||
|
||||
class UnknownException {
|
||||
var message;
|
||||
UnknownException(this.message);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
Future<String> exampleApi(String orgid) async {
|
||||
http.Response response = await http.get(
|
||||
Uri.encodeFull("https://www.example.com/api"),
|
||||
);
|
||||
print("Respone ${response.body.toString()}");
|
||||
//Returns 'true' or 'false' as a String
|
||||
return response.body;
|
||||
}
|
||||
31
web_native/lib/settings/app_themes.dart
Normal file
31
web_native/lib/settings/app_themes.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppThemes {
|
||||
static final appThemeData = {
|
||||
AppTheme.lightTheme: ThemeData(
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
primarySwatch: Colors.blue,
|
||||
backgroundColor: Colors.white,
|
||||
textTheme: TextTheme(
|
||||
bodyText1: TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
AppTheme.darkTheme: ThemeData(
|
||||
scaffoldBackgroundColor: Colors.black,
|
||||
primarySwatch: Colors.teal,
|
||||
backgroundColor: Colors.black,
|
||||
textTheme: TextTheme(
|
||||
bodyText1: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
enum AppTheme {
|
||||
lightTheme,
|
||||
darkTheme,
|
||||
}
|
||||
39
web_native/lib/settings/preferences.dart
Normal file
39
web_native/lib/settings/preferences.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:imagini/settings/app_themes.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class Preferences {
|
||||
//
|
||||
static SharedPreferences preferences;
|
||||
static const String KEY_SELECTED_THEME = 'key_selected_theme';
|
||||
|
||||
static init() async {
|
||||
preferences = await SharedPreferences.getInstance();
|
||||
}
|
||||
|
||||
static void saveTheme(AppTheme selectedTheme) async {
|
||||
if (null == selectedTheme) {
|
||||
selectedTheme = AppTheme.lightTheme;
|
||||
}
|
||||
String theme = jsonEncode(selectedTheme.toString());
|
||||
preferences.setString(KEY_SELECTED_THEME, theme);
|
||||
}
|
||||
|
||||
static AppTheme getTheme() {
|
||||
String theme = preferences.getString(KEY_SELECTED_THEME);
|
||||
if (null == theme) {
|
||||
return AppTheme.lightTheme;
|
||||
}
|
||||
return getThemeFromString(jsonDecode(theme));
|
||||
}
|
||||
|
||||
static AppTheme getThemeFromString(String themeString) {
|
||||
for (AppTheme theme in AppTheme.values) {
|
||||
if (theme.toString() == themeString) {
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user