Documentation, Basic Login Workflow
This commit is contained in:
parent
fec590b16e
commit
5212d7bf70
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
|
imagini.db
|
||||||
|
media/
|
||||||
notes
|
notes
|
||||||
web/node_modules/
|
web/node_modules/
|
||||||
web/dist/
|
web/dist/
|
||||||
|
34
README.md
34
README.md
@ -1,22 +1,32 @@
|
|||||||
#uImagini
|
# Imagini
|
||||||
|
A self hosted photo library with user management & authentication. Cross platform Client supporting Android, iOS, and Web.
|
||||||
|
|
||||||
## Running Server
|
## Server
|
||||||
# cd ./cmd/
|
### Running
|
||||||
CONFIG_PATH=$(pwd) DATA_PATH=$(pwd) go run main.go serve
|
|
||||||
|
|
||||||
## Generate GraphQL Models
|
CONFIG_PATH=$(pwd) DATA_PATH=$(pwd) go run cmd/main.go serve
|
||||||
# cd ./cmd/
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
# Generate GraphQL Models
|
||||||
go run github.com/99designs/gqlgen generate
|
go run github.com/99designs/gqlgen generate
|
||||||
go run main.go generate
|
go run cmd/main.go generate
|
||||||
|
|
||||||
## Generate GraphQL Documentation
|
# Generate GraphQL Documentation
|
||||||
# From app root
|
|
||||||
graphdoc -e http://localhost:8484/query -o ./docs/schema
|
graphdoc -e http://localhost:8484/query -o ./docs/schema
|
||||||
|
|
||||||
## Server Build
|
## Client
|
||||||
|
See `web_native` subfolder.
|
||||||
|
### Running
|
||||||
|
|
||||||
## Flutter Build
|
# Chrome
|
||||||
|
flutter run -d chrome
|
||||||
|
|
||||||
|
# Simulator
|
||||||
|
open -a Simulator
|
||||||
flutter run
|
flutter run
|
||||||
|
|
||||||
## Generate GraphQL Flutter Models
|
### Building
|
||||||
|
|
||||||
|
# Generate GraphQL Flutter Models
|
||||||
flutter pub run build_runner build
|
flutter pub run build_runner build
|
||||||
|
@ -41,35 +41,46 @@ func (api *API) refreshTokens(refreshToken jwt.Token) (string, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update Access Token
|
// Update Access Token
|
||||||
accessTokenCookie, err := api.Auth.CreateJWTAccessToken(user, device)
|
accessToken, err := api.Auth.CreateJWTAccessToken(user, device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return accessTokenCookie, "", err
|
return accessToken, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) validateTokens(w *http.ResponseWriter, r *http.Request) (jwt.Token, error) {
|
func (api *API) validateTokens(w *http.ResponseWriter, r *http.Request) (jwt.Token, error) {
|
||||||
// TODO: Check from X-Imagini-AccessToken
|
accessTokenHeader := r.Header.Get("X-Imagini-AccessToken")
|
||||||
// TODO: Check from X-Imagini-RefreshToken
|
if accessTokenHeader != "" {
|
||||||
|
accessToken, err := api.Auth.ValidateJWTAccessToken(accessTokenHeader)
|
||||||
// Validate Access Token
|
|
||||||
accessCookie, _ := r.Cookie("AccessToken")
|
|
||||||
if accessCookie != nil {
|
|
||||||
accessToken, err := api.Auth.ValidateJWTAccessToken(accessCookie.Value)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return accessToken, nil
|
return accessToken, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate Refresh Cookie Exists
|
refreshTokenHeader := r.Header.Get("X-Imagini-RefreshToken")
|
||||||
refreshCookie, _ := r.Cookie("RefreshToken")
|
if refreshTokenHeader == "" {
|
||||||
if refreshCookie == nil {
|
|
||||||
return nil, errors.New("Tokens Invalid")
|
return nil, errors.New("Tokens Invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate Access Token
|
||||||
|
// accessCookie, _ := r.Cookie("AccessToken")
|
||||||
|
// if accessCookie != nil {
|
||||||
|
// accessToken, err := api.Auth.ValidateJWTAccessToken(accessCookie.Value)
|
||||||
|
// if err == nil {
|
||||||
|
// return accessToken, nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Validate Refresh Cookie Exists
|
||||||
|
// refreshCookie, _ := r.Cookie("RefreshToken")
|
||||||
|
// if refreshCookie == nil {
|
||||||
|
// return nil, errors.New("Tokens Invalid")
|
||||||
|
// }
|
||||||
|
|
||||||
// Validate Refresh Token
|
// Validate Refresh Token
|
||||||
refreshToken, err := api.Auth.ValidateJWTRefreshToken(refreshCookie.Value)
|
// refreshToken, err := api.Auth.ValidateJWTRefreshToken(refreshCookie.Value)
|
||||||
|
refreshToken, err := api.Auth.ValidateJWTRefreshToken(refreshTokenHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Tokens Invalid")
|
return nil, errors.New("Tokens Invalid")
|
||||||
}
|
}
|
||||||
@ -81,21 +92,21 @@ func (api *API) validateTokens(w *http.ResponseWriter, r *http.Request) (jwt.Tok
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Actually Refresh Refresh Token
|
// TODO: Actually Refresh Refresh Token
|
||||||
newRefreshToken = refreshCookie.Value
|
// newRefreshToken = refreshCookie.Value
|
||||||
|
newRefreshToken = refreshTokenHeader
|
||||||
|
|
||||||
// Set appropriate cookies (TODO: Only for web!)
|
// Set appropriate cookies (TODO: Only for web!)
|
||||||
|
|
||||||
// Update Access & Refresh Cookies
|
// Update Access & Refresh Cookies
|
||||||
http.SetCookie(*w, &http.Cookie{
|
// http.SetCookie(*w, &http.Cookie{
|
||||||
Name: "AccessToken",
|
// Name: "AccessToken",
|
||||||
Value: newAccessToken,
|
// Value: newAccessToken,
|
||||||
})
|
// })
|
||||||
http.SetCookie(*w, &http.Cookie{
|
// http.SetCookie(*w, &http.Cookie{
|
||||||
Name: "RefreshToken",
|
// Name: "RefreshToken",
|
||||||
Value: newRefreshToken,
|
// Value: newRefreshToken,
|
||||||
})
|
// })
|
||||||
|
|
||||||
// Only for iOS & Android (TODO: Remove for web! Only cause affected by CORS during development)
|
|
||||||
(*w).Header().Set("X-Imagini-AccessToken", newAccessToken)
|
(*w).Header().Set("X-Imagini-AccessToken", newAccessToken)
|
||||||
(*w).Header().Set("X-Imagini-RefreshToken", newRefreshToken)
|
(*w).Header().Set("X-Imagini-RefreshToken", newRefreshToken)
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
# imagini
|
# Imagini Client
|
||||||
|
A cross platform (iOS, Android, & Web) client used with the Imagini server.
|
||||||
|
|
||||||
A new Flutter project.
|
## Running
|
||||||
|
|
||||||
## Getting Started
|
# Chrome
|
||||||
|
flutter run -d chrome
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
# Simulator
|
||||||
|
open -a Simulator
|
||||||
|
flutter run
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
## Building
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
# Generate GraphQL Flutter Models
|
||||||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
flutter pub run build_runner build
|
||||||
|
|
||||||
For help getting started with Flutter, view our
|
|
||||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
||||||
|
18
web_native/graphql/mediaItems.graphql
Normal file
18
web_native/graphql/mediaItems.graphql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
query mediaItems($order: Order, $page: Page, $filter: MediaItemFilter) {
|
||||||
|
mediaItems(filter: $filter, page: $page, order: $order) {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
fileName
|
||||||
|
latitude
|
||||||
|
longitude
|
||||||
|
isVideo
|
||||||
|
origName
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
page {
|
||||||
|
size
|
||||||
|
page
|
||||||
|
total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
PODS:
|
PODS:
|
||||||
|
- connectivity (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- Reachability
|
||||||
- DKImagePickerController/Core (4.3.2):
|
- DKImagePickerController/Core (4.3.2):
|
||||||
- DKImagePickerController/ImageDataManager
|
- DKImagePickerController/ImageDataManager
|
||||||
- DKImagePickerController/Resource
|
- DKImagePickerController/Resource
|
||||||
@ -38,6 +41,9 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- integration_test (0.0.1):
|
- integration_test (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- path_provider (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- Reachability (3.2)
|
||||||
- SDWebImage (5.10.2):
|
- SDWebImage (5.10.2):
|
||||||
- SDWebImage/Core (= 5.10.2)
|
- SDWebImage/Core (= 5.10.2)
|
||||||
- SDWebImage/Core (5.10.2)
|
- SDWebImage/Core (5.10.2)
|
||||||
@ -48,10 +54,12 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- connectivity (from `.symlinks/plugins/connectivity/ios`)
|
||||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||||
|
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||||
|
|
||||||
@ -59,10 +67,13 @@ SPEC REPOS:
|
|||||||
trunk:
|
trunk:
|
||||||
- DKImagePickerController
|
- DKImagePickerController
|
||||||
- DKPhotoGallery
|
- DKPhotoGallery
|
||||||
|
- Reachability
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
- SwiftyGif
|
- SwiftyGif
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
|
connectivity:
|
||||||
|
:path: ".symlinks/plugins/connectivity/ios"
|
||||||
file_picker:
|
file_picker:
|
||||||
:path: ".symlinks/plugins/file_picker/ios"
|
:path: ".symlinks/plugins/file_picker/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
@ -71,18 +82,23 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||||
integration_test:
|
integration_test:
|
||||||
:path: ".symlinks/plugins/integration_test/ios"
|
:path: ".symlinks/plugins/integration_test/ios"
|
||||||
|
path_provider:
|
||||||
|
:path: ".symlinks/plugins/path_provider/ios"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||||
url_launcher:
|
url_launcher:
|
||||||
:path: ".symlinks/plugins/url_launcher/ios"
|
:path: ".symlinks/plugins/url_launcher/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
|
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
|
||||||
DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d
|
DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d
|
||||||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||||
file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1
|
file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1
|
||||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||||
integration_test: 5ed24a436eb7ec17b6a13046e9bf7ca4a404e59e
|
integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f
|
||||||
|
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||||
|
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||||
SDWebImage: b969dcfc02c40a5da71eac0b03b8f1a0c794a86f
|
SDWebImage: b969dcfc02c40a5da71eac0b03b8f1a0c794a86f
|
||||||
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
||||||
SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40
|
SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
@ -1,61 +1,51 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
// ignore: uri_does_not_exist
|
import 'package:imagini/api/cookie_client/cookie_client.dart'
|
||||||
import 'cookie_client_stub.dart'
|
if (dart.library.html) 'package:imagini/api/cookie_client/browser_cookie_client.dart'
|
||||||
// ignore: uri_does_not_exist
|
if (dart.library.io) 'package:imagini/api/cookie_client/io_cookie_client.dart';
|
||||||
if (dart.library.html) 'browser_cookie_client.dart'
|
|
||||||
// ignore: uri_does_not_exist
|
|
||||||
if (dart.library.io) 'io_cookie_client.dart';
|
|
||||||
|
|
||||||
import 'package:meta/meta.dart';
|
import 'package:imagini/core/storage_client/base_storage_client.dart';
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
import 'package:imagini/graphql/imagini_graphql.dart';
|
import 'package:imagini/graphql/imagini_graphql.dart';
|
||||||
|
|
||||||
class APIProvider{
|
class APIProvider{
|
||||||
String _server, _accessToken, _refreshToken;
|
|
||||||
|
|
||||||
GraphQLClient _client;
|
|
||||||
HttpLink httpLink;
|
|
||||||
// CookieLink cookieLink;
|
|
||||||
static const String _GRAPHQL_ENDPOINT = "/query";
|
static const String _GRAPHQL_ENDPOINT = "/query";
|
||||||
|
|
||||||
APIProvider({
|
BaseStorageClient _storage;
|
||||||
@required String server,
|
GraphQLClient _client;
|
||||||
String accessToken,
|
HttpLink httpLink;
|
||||||
String refreshToken
|
|
||||||
}) {
|
APIProvider(BaseStorageClient storage) {
|
||||||
_server = server;
|
_storage = storage;
|
||||||
_accessToken = accessToken;
|
init();
|
||||||
_refreshToken = refreshToken;
|
}
|
||||||
|
|
||||||
|
Future<void> init() async {
|
||||||
|
String _server = await _storage.get("server");
|
||||||
|
|
||||||
httpLink = HttpLink(_server + _GRAPHQL_ENDPOINT,
|
httpLink = HttpLink(_server + _GRAPHQL_ENDPOINT,
|
||||||
httpClient: getCookieClient(),
|
httpClient: getCookieClient(_storage),
|
||||||
);
|
);
|
||||||
|
|
||||||
// cookieLink = CookieLink(_updateAccessToken, _updateRefreshToken);
|
|
||||||
_client = GraphQLClient(
|
_client = GraphQLClient(
|
||||||
cache: GraphQLCache(),
|
cache: GraphQLCache(),
|
||||||
link: httpLink,
|
link: httpLink,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void _updateAccessToken(_accessToken) {
|
Future<QueryResult> login(
|
||||||
// print("Updating Access Token: $_accessToken");
|
|
||||||
// this._accessToken = _accessToken;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void _updateRefreshToken(_refreshToken) {
|
|
||||||
// print("Updating Refresh Token: $_accessToken");
|
|
||||||
// this._refreshToken = _refreshToken;
|
|
||||||
// }
|
|
||||||
|
|
||||||
Future<Login$Query$AuthResponse> login([
|
|
||||||
String username,
|
String username,
|
||||||
String password,
|
String password,
|
||||||
]) async {
|
String server,
|
||||||
|
) async {
|
||||||
assert(
|
assert(
|
||||||
(username != null && password != null)
|
(username != null && password != null && server != null)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Initialize Connection
|
||||||
|
await _storage.set("server", server);
|
||||||
|
await init();
|
||||||
|
|
||||||
QueryResult response = await _client.query(
|
QueryResult response = await _client.query(
|
||||||
QueryOptions(
|
QueryOptions(
|
||||||
document: LoginQuery().document,
|
document: LoginQuery().document,
|
||||||
@ -65,79 +55,27 @@ class APIProvider{
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
return response;
|
||||||
final loginResponse = Login$Query.fromJson(response.data);
|
|
||||||
return loginResponse.login;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Me$Query$User> me() async {
|
Future<QueryResult> me() async {
|
||||||
QueryResult response = await _client.query(
|
QueryResult response = await _client.query(
|
||||||
QueryOptions(
|
QueryOptions(
|
||||||
document: MeQuery().document,
|
document: MeQuery().document,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
return response;
|
||||||
final meResponse = Me$Query.fromJson(response.data);
|
|
||||||
return meResponse.me;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> mediaItems([
|
Future<QueryResult> mediaItems() async {
|
||||||
String startDate,
|
QueryResult response = await _client.query(
|
||||||
String endDate,
|
QueryOptions(
|
||||||
String albumID,
|
document: MediaItemsQuery().document,
|
||||||
List<String> tagID,
|
)
|
||||||
String type, // TODO: Make enum
|
);
|
||||||
int page,
|
|
||||||
]) async {
|
|
||||||
// Query:
|
|
||||||
// /api/v1/MediaItems
|
|
||||||
// Derive Params:
|
|
||||||
// startDate:
|
|
||||||
// &createdAt=>2020-10-10T10:10:10
|
|
||||||
// endDate:
|
|
||||||
// &createdAt=<2020-10-10T10:10:10
|
|
||||||
// albumID:
|
|
||||||
// &albumID=9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
|
|
||||||
// tagID:
|
|
||||||
// &tagID=9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d,9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
|
|
||||||
// type:
|
|
||||||
// &type=Photos
|
|
||||||
// &type=Videos
|
|
||||||
// page:
|
|
||||||
// &page=4
|
|
||||||
|
|
||||||
// Returns:
|
print(response);
|
||||||
// {
|
return response;
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> tags([
|
|
||||||
int page
|
|
||||||
]) async {
|
|
||||||
// Query:
|
|
||||||
// /api/v1/Tags
|
|
||||||
// Derive Params:
|
|
||||||
// page:
|
|
||||||
// &page=4
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> albums([
|
|
||||||
int page
|
|
||||||
]) async {
|
|
||||||
// Query:
|
|
||||||
// /api/v1/Albums
|
|
||||||
// Derive Params:
|
|
||||||
// page:
|
|
||||||
// &page=4
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> me() async {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {}
|
void dispose() {}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
import 'package:http/browser_client.dart';
|
|
||||||
import "package:http/http.dart";
|
|
||||||
|
|
||||||
BaseClient getCookieClient() => ClientWithCookies();
|
|
||||||
|
|
||||||
class ClientWithCookies extends BrowserClient {
|
|
||||||
String _accessToken = "asdasdasd";
|
|
||||||
String _refreshToken;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<StreamedResponse> send(BaseRequest request) async {
|
|
||||||
request.headers.addAll({
|
|
||||||
'X-Imagini-AccessToken': _accessToken,
|
|
||||||
'X-Imagini-RefreshToken': _refreshToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
return super.send(request).then((response) {
|
|
||||||
if (response.headers.containsKey("x-imagini-accesstoken")) {
|
|
||||||
this._accessToken = response.headers["x-imagini-accesstoken"];
|
|
||||||
}
|
|
||||||
if (response.headers.containsKey("x-imagini-refreshtoken")) {
|
|
||||||
this._refreshToken = response.headers["x-imagini-refreshtoken"];
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Access Token: $_accessToken");
|
|
||||||
print("Refresh Token: $_refreshToken");
|
|
||||||
return response;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
36
web_native/lib/api/cookie_client/browser_cookie_client.dart
Normal file
36
web_native/lib/api/cookie_client/browser_cookie_client.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:http/browser_client.dart';
|
||||||
|
import "package:http/http.dart";
|
||||||
|
import "package:imagini/core/storage_client/base_storage_client.dart";
|
||||||
|
|
||||||
|
BaseClient getCookieClient(storage) => ClientWithCookies(storage);
|
||||||
|
|
||||||
|
class ClientWithCookies extends BrowserClient {
|
||||||
|
BaseStorageClient _storage;
|
||||||
|
|
||||||
|
ClientWithCookies(BaseStorageClient storage) {
|
||||||
|
_storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<StreamedResponse> send(BaseRequest request) async {
|
||||||
|
String _accessToken = await _storage.get("accessToken");
|
||||||
|
String _refreshToken = await _storage.get("refreshToken");
|
||||||
|
|
||||||
|
request.headers.addAll({
|
||||||
|
'X-Imagini-AccessToken': _accessToken,
|
||||||
|
'X-Imagini-RefreshToken': _refreshToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
return super.send(request).then((response) async {
|
||||||
|
// We've been told to update our access token
|
||||||
|
if (response.headers.containsKey("x-imagini-accesstoken")) {
|
||||||
|
await _storage.set("accessToken", response.headers["x-imagini-accesstoken"]);
|
||||||
|
}
|
||||||
|
// We've been told to update our refresh token
|
||||||
|
if (response.headers.containsKey("x-imagini-refreshtoken")) {
|
||||||
|
await _storage.set("refreshToken", response.headers["x-imagini-refreshtoken"]);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
|
||||||
BaseClient getCookieClient() => throw UnsupportedError(
|
BaseClient getCookieClient(storage) => throw UnsupportedError(
|
||||||
'Cannot create a client without dart:html or dart:io.');
|
'Cannot create a client without dart:html or dart:io.');
|
43
web_native/lib/api/cookie_client/io_cookie_client.dart
Normal file
43
web_native/lib/api/cookie_client/io_cookie_client.dart
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import 'package:http/io_client.dart';
|
||||||
|
import "package:http/http.dart";
|
||||||
|
import "package:imagini/core/storage_client/base_storage_client.dart";
|
||||||
|
|
||||||
|
BaseClient getCookieClient(storage) => IOClientWithCookies(storage);
|
||||||
|
|
||||||
|
class IOClientWithCookies extends IOClient {
|
||||||
|
BaseStorageClient _storage;
|
||||||
|
|
||||||
|
IOClientWithCookies(BaseStorageClient storage) {
|
||||||
|
_storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IOStreamedResponse> send(BaseRequest request) async {
|
||||||
|
String _accessToken = await _storage.get("accessToken");
|
||||||
|
String _refreshToken = await _storage.get("refreshToken");
|
||||||
|
|
||||||
|
request.headers.addAll({
|
||||||
|
'X-Imagini-AccessToken': _accessToken,
|
||||||
|
'X-Imagini-RefreshToken': _refreshToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
return super.send(request).then((response) async {
|
||||||
|
// We've been told to update our access token
|
||||||
|
if (response.headers.containsKey("x-imagini-accesstoken")) {
|
||||||
|
await _storage.set("accessToken", response.headers["x-imagini-accesstoken"]);
|
||||||
|
}
|
||||||
|
// We've been told to update our refresh token
|
||||||
|
if (response.headers.containsKey("x-imagini-refreshtoken")) {
|
||||||
|
await _storage.set("refreshToken", response.headers["x-imagini-refreshtoken"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_accessToken = await _storage.get("accessToken");
|
||||||
|
_refreshToken = await _storage.get("refreshToken");
|
||||||
|
|
||||||
|
print("Access Token: $_accessToken");
|
||||||
|
print("Refresh Token: $_refreshToken");
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,35 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'package:imagini/api/api_provider.dart';
|
import 'package:imagini/api/api_provider.dart';
|
||||||
import 'package:imagini/graphql/imagini_graphql.dart';
|
import 'package:imagini/graphql/imagini_graphql.dart';
|
||||||
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
|
|
||||||
class ImaginiAPIRepository {
|
class ImaginiAPIRepository {
|
||||||
APIProvider _apiProvider;
|
APIProvider _apiProvider;
|
||||||
|
|
||||||
ImaginiAPIRepository(this._apiProvider);
|
ImaginiAPIRepository(this._apiProvider);
|
||||||
|
|
||||||
Stream<Login$Query$AuthResponse> login(String user, password) {
|
Stream<bool> login(String user, password, server) {
|
||||||
return Stream.fromFuture(_apiProvider.login(user, password));
|
return Stream.fromFuture(_apiProvider.login(user, password, server).then((QueryResult resp) {
|
||||||
|
if (resp.exception != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
final loginResponse = Login$Query.fromJson(resp.data);
|
||||||
|
if (loginResponse.login.result == AuthResult.failure)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<QueryResult> me() {
|
||||||
|
return Stream.fromFuture(_apiProvider.me());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<bool> isAuthenticated() {
|
||||||
|
return Stream.fromFuture(_apiProvider.me().then((QueryResult resp) {
|
||||||
|
if (resp.exception != null)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
import 'package:http/io_client.dart';
|
|
||||||
import "package:http/http.dart";
|
|
||||||
|
|
||||||
BaseClient getCookieClient() => IOClientWithCookies();
|
|
||||||
|
|
||||||
class IOClientWithCookies extends IOClient {
|
|
||||||
String _accessToken;
|
|
||||||
String _refreshToken;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<IOStreamedResponse> send(BaseRequest request) async {
|
|
||||||
// String cookie = await getCookie();
|
|
||||||
// String getCookieString(String _) => cookie;
|
|
||||||
// request.headers.update('cookie', getCookieString);
|
|
||||||
return super.send(request).then((response) {
|
|
||||||
if (response.headers.containsKey("x-imagini-accesstoken")) {
|
|
||||||
this._accessToken = response.headers["x-imagini-accesstoken"];
|
|
||||||
}
|
|
||||||
if (response.headers.containsKey("x-imagini-refreshtoken")) {
|
|
||||||
this._refreshToken = response.headers["x-imagini-refreshtoken"];
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Access Token: $_accessToken");
|
|
||||||
print("Refresh Token: $_refreshToken");
|
|
||||||
return response;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
40
web_native/lib/blocs/login_bloc.dart
Normal file
40
web_native/lib/blocs/login_bloc.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:imagini/core/imagini_application.dart';
|
||||||
|
import 'package:imagini/api/imagini_api_repository.dart';
|
||||||
|
|
||||||
|
class LoginBloc{
|
||||||
|
|
||||||
|
final ImaginiApplication _application;
|
||||||
|
ImaginiAPIRepository _imaginiAPI;
|
||||||
|
|
||||||
|
final _loginController = StreamController<bool>.broadcast();
|
||||||
|
Stream<bool> get loginResult => _loginController.stream;
|
||||||
|
|
||||||
|
final _authenticatedController = StreamController<bool>.broadcast();
|
||||||
|
Stream<bool> get authenticatedResult => _authenticatedController.stream;
|
||||||
|
|
||||||
|
LoginBloc(this._application){
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init(){
|
||||||
|
_imaginiAPI = _application.imaginiAPI;
|
||||||
|
checkAuthentication();
|
||||||
|
|
||||||
|
// attemptLogin("admin", "admin", "http://localhost:8484");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose(){
|
||||||
|
_loginController.close();
|
||||||
|
_authenticatedController.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAuthentication(){
|
||||||
|
_authenticatedController.addStream(_imaginiAPI.isAuthenticated());
|
||||||
|
}
|
||||||
|
|
||||||
|
attemptLogin(String username, password, server){
|
||||||
|
_loginController.addStream(_imaginiAPI.login(username, password, server));
|
||||||
|
}
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:imagini/core/imagini_application.dart';
|
|
||||||
import 'package:imagini/api/imagini_api_repository.dart';
|
|
||||||
import 'package:imagini/graphql/imagini_graphql.dart';
|
|
||||||
|
|
||||||
class SplashBloc{
|
|
||||||
|
|
||||||
final ImaginiApplication _application;
|
|
||||||
|
|
||||||
final _loginController = StreamController<Login$Query$AuthResponse>();
|
|
||||||
Stream<Login$Query$AuthResponse> get loginResult => _loginController.stream;
|
|
||||||
|
|
||||||
SplashBloc(this._application){
|
|
||||||
_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(){
|
|
||||||
// Do Initial Load
|
|
||||||
initializeLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose(){
|
|
||||||
_loginController.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeLogin(){
|
|
||||||
ImaginiAPIRepository imaginiAPI = _application.imaginiAPI;
|
|
||||||
|
|
||||||
// TODO: This should actually attempt to load the existing Tokens, not login
|
|
||||||
_loginController.addStream(imaginiAPI.login("admin", "admin"));
|
|
||||||
|
|
||||||
// imaginiAPI.login("admin", "admin1").listen((LoginResponse lr) {
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,6 @@ class AppComponentState extends State<AppComponent> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() async {
|
void dispose() async {
|
||||||
// Log.info('dispose');
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
await _application.onTerminate();
|
await _application.onTerminate();
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'package:imagini/screens/home_screen.dart';
|
import 'package:imagini/screens/home_screen.dart';
|
||||||
import 'package:imagini/screens/login_screen.dart';
|
import 'package:imagini/screens/login_screen.dart';
|
||||||
import 'package:imagini/screens/splash_screen.dart';
|
// import 'package:imagini/screens/splash_screen.dart';
|
||||||
|
|
||||||
var splashHandler = new Handler(
|
// var splashHandler = new Handler(
|
||||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
// handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||||
return SplashScreen();
|
// return SplashScreen();
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
|
|
||||||
var loginHandler = new Handler(
|
var loginHandler = new Handler(
|
||||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||||
@ -42,7 +42,7 @@ class AppRoutes {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
router.define(SplashScreen.PATH, handler: splashHandler);
|
// router.define(SplashScreen.PATH, handler: splashHandler);
|
||||||
router.define(LoginScreen.PATH, handler: loginHandler);
|
router.define(LoginScreen.PATH, handler: loginHandler);
|
||||||
router.define(HomeScreen.PATH, handler: homeHandler);
|
router.define(HomeScreen.PATH, handler: homeHandler);
|
||||||
// router.define(AppDetailPage.PATH, handler: appDetailRouteHandler);
|
// router.define(AppDetailPage.PATH, handler: appDetailRouteHandler);
|
||||||
|
@ -3,13 +3,20 @@ import 'package:fluro/fluro.dart';
|
|||||||
import 'package:imagini/core/app_routes.dart';
|
import 'package:imagini/core/app_routes.dart';
|
||||||
import 'package:imagini/api/api_provider.dart';
|
import 'package:imagini/api/api_provider.dart';
|
||||||
import 'package:imagini/api/imagini_api_repository.dart';
|
import 'package:imagini/api/imagini_api_repository.dart';
|
||||||
|
import 'package:imagini/core/storage_client/base_storage_client.dart';
|
||||||
|
|
||||||
|
import 'package:imagini/core/storage_client/storage_client.dart'
|
||||||
|
if (dart.library.html) 'package:imagini/core/storage_client/browser_storage_client.dart'
|
||||||
|
if (dart.library.io) 'package:imagini/core/storage_client/mobile_storage_client.dart';
|
||||||
|
|
||||||
class ImaginiApplication {
|
class ImaginiApplication {
|
||||||
FluroRouter router;
|
FluroRouter router;
|
||||||
ImaginiAPIRepository imaginiAPI;
|
ImaginiAPIRepository imaginiAPI;
|
||||||
|
BaseStorageClient storageClient;
|
||||||
|
|
||||||
Future<void> onCreate() async {
|
Future<void> onCreate() async {
|
||||||
_initRouter();
|
_initRouter();
|
||||||
|
_initStorageClient();
|
||||||
_initAPIRepository();
|
_initAPIRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,8 +27,13 @@ class ImaginiApplication {
|
|||||||
AppRoutes.configureRoutes(router);
|
AppRoutes.configureRoutes(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_initStorageClient() {
|
||||||
|
storageClient = getStorageClient();
|
||||||
|
}
|
||||||
|
|
||||||
_initAPIRepository() {
|
_initAPIRepository() {
|
||||||
APIProvider apiProvider = new APIProvider(server: "http://localhost:8484");
|
// TODO: Get from config
|
||||||
|
APIProvider apiProvider = new APIProvider(storageClient);
|
||||||
imaginiAPI = ImaginiAPIRepository(apiProvider);
|
imaginiAPI = ImaginiAPIRepository(apiProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
abstract class BaseStorageClient {
|
||||||
|
Future<String> get(String key);
|
||||||
|
Future<void> set(String key, String value);
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import 'dart:html';
|
||||||
|
|
||||||
|
import './base_storage_client.dart';
|
||||||
|
|
||||||
|
BaseStorageClient getStorageClient() => BrowserStorageClient();
|
||||||
|
|
||||||
|
class BrowserStorageClient extends BaseStorageClient {
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> get(String key) async {
|
||||||
|
var requestedValue = window.localStorage.containsKey(key) ? window.localStorage[key] : "";
|
||||||
|
return requestedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> set(String key, String value) async {
|
||||||
|
window.localStorage[key] = value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
|
||||||
|
import './base_storage_client.dart';
|
||||||
|
|
||||||
|
BaseStorageClient getStorageClient() => MobileStorageClient();
|
||||||
|
|
||||||
|
class MobileStorageClient extends BaseStorageClient {
|
||||||
|
final storage = new FlutterSecureStorage();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> get(String key) async {
|
||||||
|
return storage.read(key: key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> set(String key, String value) async {
|
||||||
|
return storage.write(key: key, value: value);
|
||||||
|
}
|
||||||
|
}
|
4
web_native/lib/core/storage_client/storage_client.dart
Normal file
4
web_native/lib/core/storage_client/storage_client.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import './base_storage_client.dart';
|
||||||
|
|
||||||
|
BaseStorageClient getStorageClient() => throw UnsupportedError(
|
||||||
|
'Cannot create a storage client.');
|
@ -170,6 +170,362 @@ class Me$Query with EquatableMixin {
|
|||||||
Map<String, dynamic> toJson() => _$Me$QueryToJson(this);
|
Map<String, dynamic> toJson() => _$Me$QueryToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class MediaItems$Query$MediaItemResponse$MediaItem with EquatableMixin {
|
||||||
|
MediaItems$Query$MediaItemResponse$MediaItem();
|
||||||
|
|
||||||
|
factory MediaItems$Query$MediaItemResponse$MediaItem.fromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$MediaItems$Query$MediaItemResponse$MediaItemFromJson(json);
|
||||||
|
|
||||||
|
String id;
|
||||||
|
|
||||||
|
String fileName;
|
||||||
|
|
||||||
|
double latitude;
|
||||||
|
|
||||||
|
double longitude;
|
||||||
|
|
||||||
|
bool isVideo;
|
||||||
|
|
||||||
|
String origName;
|
||||||
|
|
||||||
|
DateTime createdAt;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props =>
|
||||||
|
[id, fileName, latitude, longitude, isVideo, origName, createdAt];
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
_$MediaItems$Query$MediaItemResponse$MediaItemToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class MediaItems$Query$MediaItemResponse$PageResponse with EquatableMixin {
|
||||||
|
MediaItems$Query$MediaItemResponse$PageResponse();
|
||||||
|
|
||||||
|
factory MediaItems$Query$MediaItemResponse$PageResponse.fromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$MediaItems$Query$MediaItemResponse$PageResponseFromJson(json);
|
||||||
|
|
||||||
|
int size;
|
||||||
|
|
||||||
|
int page;
|
||||||
|
|
||||||
|
int total;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [size, page, total];
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
_$MediaItems$Query$MediaItemResponse$PageResponseToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class MediaItems$Query$MediaItemResponse with EquatableMixin {
|
||||||
|
MediaItems$Query$MediaItemResponse();
|
||||||
|
|
||||||
|
factory MediaItems$Query$MediaItemResponse.fromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$MediaItems$Query$MediaItemResponseFromJson(json);
|
||||||
|
|
||||||
|
List<MediaItems$Query$MediaItemResponse$MediaItem> data;
|
||||||
|
|
||||||
|
MediaItems$Query$MediaItemResponse$PageResponse page;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [data, page];
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
_$MediaItems$Query$MediaItemResponseToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class MediaItems$Query with EquatableMixin {
|
||||||
|
MediaItems$Query();
|
||||||
|
|
||||||
|
factory MediaItems$Query.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MediaItems$QueryFromJson(json);
|
||||||
|
|
||||||
|
MediaItems$Query$MediaItemResponse mediaItems;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [mediaItems];
|
||||||
|
Map<String, dynamic> toJson() => _$MediaItems$QueryToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class TimeFilter with EquatableMixin {
|
||||||
|
TimeFilter(
|
||||||
|
{this.equalTo,
|
||||||
|
this.notEqualTo,
|
||||||
|
this.lessThan,
|
||||||
|
this.lessThanOrEqualTo,
|
||||||
|
this.greaterThan,
|
||||||
|
this.greaterThanOrEqualTo});
|
||||||
|
|
||||||
|
factory TimeFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TimeFilterFromJson(json);
|
||||||
|
|
||||||
|
DateTime equalTo;
|
||||||
|
|
||||||
|
DateTime notEqualTo;
|
||||||
|
|
||||||
|
DateTime lessThan;
|
||||||
|
|
||||||
|
DateTime lessThanOrEqualTo;
|
||||||
|
|
||||||
|
DateTime greaterThan;
|
||||||
|
|
||||||
|
DateTime greaterThanOrEqualTo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [
|
||||||
|
equalTo,
|
||||||
|
notEqualTo,
|
||||||
|
lessThan,
|
||||||
|
lessThanOrEqualTo,
|
||||||
|
greaterThan,
|
||||||
|
greaterThanOrEqualTo
|
||||||
|
];
|
||||||
|
Map<String, dynamic> toJson() => _$TimeFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class FloatFilter with EquatableMixin {
|
||||||
|
FloatFilter(
|
||||||
|
{this.equalTo,
|
||||||
|
this.notEqualTo,
|
||||||
|
this.lessThan,
|
||||||
|
this.lessThanOrEqualTo,
|
||||||
|
this.greaterThan,
|
||||||
|
this.greaterThanOrEqualTo});
|
||||||
|
|
||||||
|
factory FloatFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$FloatFilterFromJson(json);
|
||||||
|
|
||||||
|
double equalTo;
|
||||||
|
|
||||||
|
double notEqualTo;
|
||||||
|
|
||||||
|
double lessThan;
|
||||||
|
|
||||||
|
double lessThanOrEqualTo;
|
||||||
|
|
||||||
|
double greaterThan;
|
||||||
|
|
||||||
|
double greaterThanOrEqualTo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [
|
||||||
|
equalTo,
|
||||||
|
notEqualTo,
|
||||||
|
lessThan,
|
||||||
|
lessThanOrEqualTo,
|
||||||
|
greaterThan,
|
||||||
|
greaterThanOrEqualTo
|
||||||
|
];
|
||||||
|
Map<String, dynamic> toJson() => _$FloatFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class BooleanFilter with EquatableMixin {
|
||||||
|
BooleanFilter({this.equalTo, this.notEqualTo});
|
||||||
|
|
||||||
|
factory BooleanFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$BooleanFilterFromJson(json);
|
||||||
|
|
||||||
|
bool equalTo;
|
||||||
|
|
||||||
|
bool notEqualTo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [equalTo, notEqualTo];
|
||||||
|
Map<String, dynamic> toJson() => _$BooleanFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class IDFilter with EquatableMixin {
|
||||||
|
IDFilter({this.equalTo, this.notEqualTo});
|
||||||
|
|
||||||
|
factory IDFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$IDFilterFromJson(json);
|
||||||
|
|
||||||
|
String equalTo;
|
||||||
|
|
||||||
|
String notEqualTo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [equalTo, notEqualTo];
|
||||||
|
Map<String, dynamic> toJson() => _$IDFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class StringFilter with EquatableMixin {
|
||||||
|
StringFilter(
|
||||||
|
{this.equalTo,
|
||||||
|
this.notEqualTo,
|
||||||
|
this.startsWith,
|
||||||
|
this.notStartsWith,
|
||||||
|
this.endsWith,
|
||||||
|
this.notEndsWith,
|
||||||
|
this.contains,
|
||||||
|
this.notContains});
|
||||||
|
|
||||||
|
factory StringFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$StringFilterFromJson(json);
|
||||||
|
|
||||||
|
String equalTo;
|
||||||
|
|
||||||
|
String notEqualTo;
|
||||||
|
|
||||||
|
String startsWith;
|
||||||
|
|
||||||
|
String notStartsWith;
|
||||||
|
|
||||||
|
String endsWith;
|
||||||
|
|
||||||
|
String notEndsWith;
|
||||||
|
|
||||||
|
String contains;
|
||||||
|
|
||||||
|
String notContains;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [
|
||||||
|
equalTo,
|
||||||
|
notEqualTo,
|
||||||
|
startsWith,
|
||||||
|
notStartsWith,
|
||||||
|
endsWith,
|
||||||
|
notEndsWith,
|
||||||
|
contains,
|
||||||
|
notContains
|
||||||
|
];
|
||||||
|
Map<String, dynamic> toJson() => _$StringFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class MediaItemFilter with EquatableMixin {
|
||||||
|
MediaItemFilter(
|
||||||
|
{this.id,
|
||||||
|
this.createdAt,
|
||||||
|
this.updatedAt,
|
||||||
|
this.exifDate,
|
||||||
|
this.latitude,
|
||||||
|
this.longitude,
|
||||||
|
this.isVideo,
|
||||||
|
this.origName,
|
||||||
|
this.tags,
|
||||||
|
this.albums});
|
||||||
|
|
||||||
|
factory MediaItemFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MediaItemFilterFromJson(json);
|
||||||
|
|
||||||
|
IDFilter id;
|
||||||
|
|
||||||
|
TimeFilter createdAt;
|
||||||
|
|
||||||
|
TimeFilter updatedAt;
|
||||||
|
|
||||||
|
TimeFilter exifDate;
|
||||||
|
|
||||||
|
FloatFilter latitude;
|
||||||
|
|
||||||
|
FloatFilter longitude;
|
||||||
|
|
||||||
|
BooleanFilter isVideo;
|
||||||
|
|
||||||
|
StringFilter origName;
|
||||||
|
|
||||||
|
TagFilter tags;
|
||||||
|
|
||||||
|
AlbumFilter albums;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [
|
||||||
|
id,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
exifDate,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
isVideo,
|
||||||
|
origName,
|
||||||
|
tags,
|
||||||
|
albums
|
||||||
|
];
|
||||||
|
Map<String, dynamic> toJson() => _$MediaItemFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class TagFilter with EquatableMixin {
|
||||||
|
TagFilter({this.id, this.createdAt, this.updatedAt, this.name});
|
||||||
|
|
||||||
|
factory TagFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TagFilterFromJson(json);
|
||||||
|
|
||||||
|
IDFilter id;
|
||||||
|
|
||||||
|
TimeFilter createdAt;
|
||||||
|
|
||||||
|
TimeFilter updatedAt;
|
||||||
|
|
||||||
|
StringFilter name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [id, createdAt, updatedAt, name];
|
||||||
|
Map<String, dynamic> toJson() => _$TagFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class AlbumFilter with EquatableMixin {
|
||||||
|
AlbumFilter({this.id, this.createdAt, this.updatedAt, this.name});
|
||||||
|
|
||||||
|
factory AlbumFilter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AlbumFilterFromJson(json);
|
||||||
|
|
||||||
|
IDFilter id;
|
||||||
|
|
||||||
|
TimeFilter createdAt;
|
||||||
|
|
||||||
|
TimeFilter updatedAt;
|
||||||
|
|
||||||
|
StringFilter name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [id, createdAt, updatedAt, name];
|
||||||
|
Map<String, dynamic> toJson() => _$AlbumFilterToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Page with EquatableMixin {
|
||||||
|
Page({this.size, this.page});
|
||||||
|
|
||||||
|
factory Page.fromJson(Map<String, dynamic> json) => _$PageFromJson(json);
|
||||||
|
|
||||||
|
int size;
|
||||||
|
|
||||||
|
int page;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [size, page];
|
||||||
|
Map<String, dynamic> toJson() => _$PageToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Order with EquatableMixin {
|
||||||
|
Order({this.by, this.direction});
|
||||||
|
|
||||||
|
factory Order.fromJson(Map<String, dynamic> json) => _$OrderFromJson(json);
|
||||||
|
|
||||||
|
String by;
|
||||||
|
|
||||||
|
@JsonKey(unknownEnumValue: OrderDirection.artemisUnknown)
|
||||||
|
OrderDirection direction;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [by, direction];
|
||||||
|
Map<String, dynamic> toJson() => _$OrderToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
enum AuthResult {
|
enum AuthResult {
|
||||||
@JsonValue('Success')
|
@JsonValue('Success')
|
||||||
success,
|
success,
|
||||||
@ -194,6 +550,14 @@ enum AuthType {
|
|||||||
@JsonValue('ARTEMIS_UNKNOWN')
|
@JsonValue('ARTEMIS_UNKNOWN')
|
||||||
artemisUnknown,
|
artemisUnknown,
|
||||||
}
|
}
|
||||||
|
enum OrderDirection {
|
||||||
|
@JsonValue('ASC')
|
||||||
|
asc,
|
||||||
|
@JsonValue('DESC')
|
||||||
|
desc,
|
||||||
|
@JsonValue('ARTEMIS_UNKNOWN')
|
||||||
|
artemisUnknown,
|
||||||
|
}
|
||||||
|
|
||||||
@JsonSerializable(explicitToJson: true)
|
@JsonSerializable(explicitToJson: true)
|
||||||
class LoginArguments extends JsonSerializable with EquatableMixin {
|
class LoginArguments extends JsonSerializable with EquatableMixin {
|
||||||
@ -508,3 +872,161 @@ class MeQuery extends GraphQLQuery<Me$Query, JsonSerializable> {
|
|||||||
@override
|
@override
|
||||||
Me$Query parse(Map<String, dynamic> json) => Me$Query.fromJson(json);
|
Me$Query parse(Map<String, dynamic> json) => Me$Query.fromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class MediaItemsArguments extends JsonSerializable with EquatableMixin {
|
||||||
|
MediaItemsArguments({this.order, this.page, this.filter});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory MediaItemsArguments.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MediaItemsArgumentsFromJson(json);
|
||||||
|
|
||||||
|
final Order order;
|
||||||
|
|
||||||
|
final Page page;
|
||||||
|
|
||||||
|
final MediaItemFilter filter;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [order, page, filter];
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$MediaItemsArgumentsToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MediaItemsQuery
|
||||||
|
extends GraphQLQuery<MediaItems$Query, MediaItemsArguments> {
|
||||||
|
MediaItemsQuery({this.variables});
|
||||||
|
|
||||||
|
@override
|
||||||
|
final DocumentNode document = DocumentNode(definitions: [
|
||||||
|
OperationDefinitionNode(
|
||||||
|
type: OperationType.query,
|
||||||
|
name: NameNode(value: 'mediaItems'),
|
||||||
|
variableDefinitions: [
|
||||||
|
VariableDefinitionNode(
|
||||||
|
variable: VariableNode(name: NameNode(value: 'order')),
|
||||||
|
type: NamedTypeNode(
|
||||||
|
name: NameNode(value: 'Order'), isNonNull: false),
|
||||||
|
defaultValue: DefaultValueNode(value: null),
|
||||||
|
directives: []),
|
||||||
|
VariableDefinitionNode(
|
||||||
|
variable: VariableNode(name: NameNode(value: 'page')),
|
||||||
|
type: NamedTypeNode(
|
||||||
|
name: NameNode(value: 'Page'), isNonNull: false),
|
||||||
|
defaultValue: DefaultValueNode(value: null),
|
||||||
|
directives: []),
|
||||||
|
VariableDefinitionNode(
|
||||||
|
variable: VariableNode(name: NameNode(value: 'filter')),
|
||||||
|
type: NamedTypeNode(
|
||||||
|
name: NameNode(value: 'MediaItemFilter'), isNonNull: false),
|
||||||
|
defaultValue: DefaultValueNode(value: null),
|
||||||
|
directives: [])
|
||||||
|
],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: SelectionSetNode(selections: [
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'mediaItems'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [
|
||||||
|
ArgumentNode(
|
||||||
|
name: NameNode(value: 'filter'),
|
||||||
|
value: VariableNode(name: NameNode(value: 'filter'))),
|
||||||
|
ArgumentNode(
|
||||||
|
name: NameNode(value: 'page'),
|
||||||
|
value: VariableNode(name: NameNode(value: 'page'))),
|
||||||
|
ArgumentNode(
|
||||||
|
name: NameNode(value: 'order'),
|
||||||
|
value: VariableNode(name: NameNode(value: 'order')))
|
||||||
|
],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: SelectionSetNode(selections: [
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'data'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: SelectionSetNode(selections: [
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'id'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'fileName'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'latitude'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'longitude'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'isVideo'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'origName'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'createdAt'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null)
|
||||||
|
])),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'page'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: SelectionSetNode(selections: [
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'size'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'page'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'total'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null)
|
||||||
|
]))
|
||||||
|
]))
|
||||||
|
]))
|
||||||
|
]);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String operationName = 'mediaItems';
|
||||||
|
|
||||||
|
@override
|
||||||
|
final MediaItemsArguments variables;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [document, operationName, variables];
|
||||||
|
@override
|
||||||
|
MediaItems$Query parse(Map<String, dynamic> json) =>
|
||||||
|
MediaItems$Query.fromJson(json);
|
||||||
|
}
|
||||||
|
@ -192,6 +192,318 @@ Map<String, dynamic> _$Me$QueryToJson(Me$Query instance) => <String, dynamic>{
|
|||||||
'me': instance.me?.toJson(),
|
'me': instance.me?.toJson(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MediaItems$Query$MediaItemResponse$MediaItem
|
||||||
|
_$MediaItems$Query$MediaItemResponse$MediaItemFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return MediaItems$Query$MediaItemResponse$MediaItem()
|
||||||
|
..id = json['id'] as String
|
||||||
|
..fileName = json['fileName'] as String
|
||||||
|
..latitude = (json['latitude'] as num)?.toDouble()
|
||||||
|
..longitude = (json['longitude'] as num)?.toDouble()
|
||||||
|
..isVideo = json['isVideo'] as bool
|
||||||
|
..origName = json['origName'] as String
|
||||||
|
..createdAt = json['createdAt'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['createdAt'] as String);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MediaItems$Query$MediaItemResponse$MediaItemToJson(
|
||||||
|
MediaItems$Query$MediaItemResponse$MediaItem instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'fileName': instance.fileName,
|
||||||
|
'latitude': instance.latitude,
|
||||||
|
'longitude': instance.longitude,
|
||||||
|
'isVideo': instance.isVideo,
|
||||||
|
'origName': instance.origName,
|
||||||
|
'createdAt': instance.createdAt?.toIso8601String(),
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaItems$Query$MediaItemResponse$PageResponse
|
||||||
|
_$MediaItems$Query$MediaItemResponse$PageResponseFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return MediaItems$Query$MediaItemResponse$PageResponse()
|
||||||
|
..size = json['size'] as int
|
||||||
|
..page = json['page'] as int
|
||||||
|
..total = json['total'] as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MediaItems$Query$MediaItemResponse$PageResponseToJson(
|
||||||
|
MediaItems$Query$MediaItemResponse$PageResponse instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'size': instance.size,
|
||||||
|
'page': instance.page,
|
||||||
|
'total': instance.total,
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaItems$Query$MediaItemResponse _$MediaItems$Query$MediaItemResponseFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return MediaItems$Query$MediaItemResponse()
|
||||||
|
..data = (json['data'] as List)
|
||||||
|
?.map((e) => e == null
|
||||||
|
? null
|
||||||
|
: MediaItems$Query$MediaItemResponse$MediaItem.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
?.toList()
|
||||||
|
..page = json['page'] == null
|
||||||
|
? null
|
||||||
|
: MediaItems$Query$MediaItemResponse$PageResponse.fromJson(
|
||||||
|
json['page'] as Map<String, dynamic>);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MediaItems$Query$MediaItemResponseToJson(
|
||||||
|
MediaItems$Query$MediaItemResponse instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'data': instance.data?.map((e) => e?.toJson())?.toList(),
|
||||||
|
'page': instance.page?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaItems$Query _$MediaItems$QueryFromJson(Map<String, dynamic> json) {
|
||||||
|
return MediaItems$Query()
|
||||||
|
..mediaItems = json['mediaItems'] == null
|
||||||
|
? null
|
||||||
|
: MediaItems$Query$MediaItemResponse.fromJson(
|
||||||
|
json['mediaItems'] as Map<String, dynamic>);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MediaItems$QueryToJson(MediaItems$Query instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'mediaItems': instance.mediaItems?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeFilter _$TimeFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return TimeFilter(
|
||||||
|
equalTo: json['equalTo'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['equalTo'] as String),
|
||||||
|
notEqualTo: json['notEqualTo'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['notEqualTo'] as String),
|
||||||
|
lessThan: json['lessThan'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['lessThan'] as String),
|
||||||
|
lessThanOrEqualTo: json['lessThanOrEqualTo'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['lessThanOrEqualTo'] as String),
|
||||||
|
greaterThan: json['greaterThan'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['greaterThan'] as String),
|
||||||
|
greaterThanOrEqualTo: json['greaterThanOrEqualTo'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['greaterThanOrEqualTo'] as String),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$TimeFilterToJson(TimeFilter instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'equalTo': instance.equalTo?.toIso8601String(),
|
||||||
|
'notEqualTo': instance.notEqualTo?.toIso8601String(),
|
||||||
|
'lessThan': instance.lessThan?.toIso8601String(),
|
||||||
|
'lessThanOrEqualTo': instance.lessThanOrEqualTo?.toIso8601String(),
|
||||||
|
'greaterThan': instance.greaterThan?.toIso8601String(),
|
||||||
|
'greaterThanOrEqualTo': instance.greaterThanOrEqualTo?.toIso8601String(),
|
||||||
|
};
|
||||||
|
|
||||||
|
FloatFilter _$FloatFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return FloatFilter(
|
||||||
|
equalTo: (json['equalTo'] as num)?.toDouble(),
|
||||||
|
notEqualTo: (json['notEqualTo'] as num)?.toDouble(),
|
||||||
|
lessThan: (json['lessThan'] as num)?.toDouble(),
|
||||||
|
lessThanOrEqualTo: (json['lessThanOrEqualTo'] as num)?.toDouble(),
|
||||||
|
greaterThan: (json['greaterThan'] as num)?.toDouble(),
|
||||||
|
greaterThanOrEqualTo: (json['greaterThanOrEqualTo'] as num)?.toDouble(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$FloatFilterToJson(FloatFilter instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'equalTo': instance.equalTo,
|
||||||
|
'notEqualTo': instance.notEqualTo,
|
||||||
|
'lessThan': instance.lessThan,
|
||||||
|
'lessThanOrEqualTo': instance.lessThanOrEqualTo,
|
||||||
|
'greaterThan': instance.greaterThan,
|
||||||
|
'greaterThanOrEqualTo': instance.greaterThanOrEqualTo,
|
||||||
|
};
|
||||||
|
|
||||||
|
BooleanFilter _$BooleanFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return BooleanFilter(
|
||||||
|
equalTo: json['equalTo'] as bool,
|
||||||
|
notEqualTo: json['notEqualTo'] as bool,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$BooleanFilterToJson(BooleanFilter instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'equalTo': instance.equalTo,
|
||||||
|
'notEqualTo': instance.notEqualTo,
|
||||||
|
};
|
||||||
|
|
||||||
|
IDFilter _$IDFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return IDFilter(
|
||||||
|
equalTo: json['equalTo'] as String,
|
||||||
|
notEqualTo: json['notEqualTo'] as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$IDFilterToJson(IDFilter instance) => <String, dynamic>{
|
||||||
|
'equalTo': instance.equalTo,
|
||||||
|
'notEqualTo': instance.notEqualTo,
|
||||||
|
};
|
||||||
|
|
||||||
|
StringFilter _$StringFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return StringFilter(
|
||||||
|
equalTo: json['equalTo'] as String,
|
||||||
|
notEqualTo: json['notEqualTo'] as String,
|
||||||
|
startsWith: json['startsWith'] as String,
|
||||||
|
notStartsWith: json['notStartsWith'] as String,
|
||||||
|
endsWith: json['endsWith'] as String,
|
||||||
|
notEndsWith: json['notEndsWith'] as String,
|
||||||
|
contains: json['contains'] as String,
|
||||||
|
notContains: json['notContains'] as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$StringFilterToJson(StringFilter instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'equalTo': instance.equalTo,
|
||||||
|
'notEqualTo': instance.notEqualTo,
|
||||||
|
'startsWith': instance.startsWith,
|
||||||
|
'notStartsWith': instance.notStartsWith,
|
||||||
|
'endsWith': instance.endsWith,
|
||||||
|
'notEndsWith': instance.notEndsWith,
|
||||||
|
'contains': instance.contains,
|
||||||
|
'notContains': instance.notContains,
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaItemFilter _$MediaItemFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return MediaItemFilter(
|
||||||
|
id: json['id'] == null
|
||||||
|
? null
|
||||||
|
: IDFilter.fromJson(json['id'] as Map<String, dynamic>),
|
||||||
|
createdAt: json['createdAt'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['createdAt'] as Map<String, dynamic>),
|
||||||
|
updatedAt: json['updatedAt'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['updatedAt'] as Map<String, dynamic>),
|
||||||
|
exifDate: json['exifDate'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['exifDate'] as Map<String, dynamic>),
|
||||||
|
latitude: json['latitude'] == null
|
||||||
|
? null
|
||||||
|
: FloatFilter.fromJson(json['latitude'] as Map<String, dynamic>),
|
||||||
|
longitude: json['longitude'] == null
|
||||||
|
? null
|
||||||
|
: FloatFilter.fromJson(json['longitude'] as Map<String, dynamic>),
|
||||||
|
isVideo: json['isVideo'] == null
|
||||||
|
? null
|
||||||
|
: BooleanFilter.fromJson(json['isVideo'] as Map<String, dynamic>),
|
||||||
|
origName: json['origName'] == null
|
||||||
|
? null
|
||||||
|
: StringFilter.fromJson(json['origName'] as Map<String, dynamic>),
|
||||||
|
tags: json['tags'] == null
|
||||||
|
? null
|
||||||
|
: TagFilter.fromJson(json['tags'] as Map<String, dynamic>),
|
||||||
|
albums: json['albums'] == null
|
||||||
|
? null
|
||||||
|
: AlbumFilter.fromJson(json['albums'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MediaItemFilterToJson(MediaItemFilter instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id?.toJson(),
|
||||||
|
'createdAt': instance.createdAt?.toJson(),
|
||||||
|
'updatedAt': instance.updatedAt?.toJson(),
|
||||||
|
'exifDate': instance.exifDate?.toJson(),
|
||||||
|
'latitude': instance.latitude?.toJson(),
|
||||||
|
'longitude': instance.longitude?.toJson(),
|
||||||
|
'isVideo': instance.isVideo?.toJson(),
|
||||||
|
'origName': instance.origName?.toJson(),
|
||||||
|
'tags': instance.tags?.toJson(),
|
||||||
|
'albums': instance.albums?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
TagFilter _$TagFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return TagFilter(
|
||||||
|
id: json['id'] == null
|
||||||
|
? null
|
||||||
|
: IDFilter.fromJson(json['id'] as Map<String, dynamic>),
|
||||||
|
createdAt: json['createdAt'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['createdAt'] as Map<String, dynamic>),
|
||||||
|
updatedAt: json['updatedAt'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['updatedAt'] as Map<String, dynamic>),
|
||||||
|
name: json['name'] == null
|
||||||
|
? null
|
||||||
|
: StringFilter.fromJson(json['name'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$TagFilterToJson(TagFilter instance) => <String, dynamic>{
|
||||||
|
'id': instance.id?.toJson(),
|
||||||
|
'createdAt': instance.createdAt?.toJson(),
|
||||||
|
'updatedAt': instance.updatedAt?.toJson(),
|
||||||
|
'name': instance.name?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
AlbumFilter _$AlbumFilterFromJson(Map<String, dynamic> json) {
|
||||||
|
return AlbumFilter(
|
||||||
|
id: json['id'] == null
|
||||||
|
? null
|
||||||
|
: IDFilter.fromJson(json['id'] as Map<String, dynamic>),
|
||||||
|
createdAt: json['createdAt'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['createdAt'] as Map<String, dynamic>),
|
||||||
|
updatedAt: json['updatedAt'] == null
|
||||||
|
? null
|
||||||
|
: TimeFilter.fromJson(json['updatedAt'] as Map<String, dynamic>),
|
||||||
|
name: json['name'] == null
|
||||||
|
? null
|
||||||
|
: StringFilter.fromJson(json['name'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AlbumFilterToJson(AlbumFilter instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id?.toJson(),
|
||||||
|
'createdAt': instance.createdAt?.toJson(),
|
||||||
|
'updatedAt': instance.updatedAt?.toJson(),
|
||||||
|
'name': instance.name?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Page _$PageFromJson(Map<String, dynamic> json) {
|
||||||
|
return Page(
|
||||||
|
size: json['size'] as int,
|
||||||
|
page: json['page'] as int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$PageToJson(Page instance) => <String, dynamic>{
|
||||||
|
'size': instance.size,
|
||||||
|
'page': instance.page,
|
||||||
|
};
|
||||||
|
|
||||||
|
Order _$OrderFromJson(Map<String, dynamic> json) {
|
||||||
|
return Order(
|
||||||
|
by: json['by'] as String,
|
||||||
|
direction: _$enumDecodeNullable(_$OrderDirectionEnumMap, json['direction'],
|
||||||
|
unknownValue: OrderDirection.artemisUnknown),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$OrderToJson(Order instance) => <String, dynamic>{
|
||||||
|
'by': instance.by,
|
||||||
|
'direction': _$OrderDirectionEnumMap[instance.direction],
|
||||||
|
};
|
||||||
|
|
||||||
|
const _$OrderDirectionEnumMap = {
|
||||||
|
OrderDirection.asc: 'ASC',
|
||||||
|
OrderDirection.desc: 'DESC',
|
||||||
|
OrderDirection.artemisUnknown: 'ARTEMIS_UNKNOWN',
|
||||||
|
};
|
||||||
|
|
||||||
LoginArguments _$LoginArgumentsFromJson(Map<String, dynamic> json) {
|
LoginArguments _$LoginArgumentsFromJson(Map<String, dynamic> json) {
|
||||||
return LoginArguments(
|
return LoginArguments(
|
||||||
user: json['user'] as String,
|
user: json['user'] as String,
|
||||||
@ -219,3 +531,25 @@ Map<String, dynamic> _$CreateMediaItemArgumentsToJson(
|
|||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'file': fromDartMultipartFileToGraphQLUpload(instance.file),
|
'file': fromDartMultipartFileToGraphQLUpload(instance.file),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MediaItemsArguments _$MediaItemsArgumentsFromJson(Map<String, dynamic> json) {
|
||||||
|
return MediaItemsArguments(
|
||||||
|
order: json['order'] == null
|
||||||
|
? null
|
||||||
|
: Order.fromJson(json['order'] as Map<String, dynamic>),
|
||||||
|
page: json['page'] == null
|
||||||
|
? null
|
||||||
|
: Page.fromJson(json['page'] as Map<String, dynamic>),
|
||||||
|
filter: json['filter'] == null
|
||||||
|
? null
|
||||||
|
: MediaItemFilter.fromJson(json['filter'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MediaItemsArgumentsToJson(
|
||||||
|
MediaItemsArguments instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'order': instance.order?.toJson(),
|
||||||
|
'page': instance.page?.toJson(),
|
||||||
|
'filter': instance.filter?.toJson(),
|
||||||
|
};
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:fluro/fluro.dart';
|
import 'package:fluro/fluro.dart';
|
||||||
|
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
|
|
||||||
|
import 'package:imagini/blocs/login_bloc.dart';
|
||||||
import 'package:imagini/core/app_provider.dart';
|
import 'package:imagini/core/app_provider.dart';
|
||||||
|
|
||||||
class LoginScreen extends StatefulWidget {
|
class LoginScreen extends StatefulWidget {
|
||||||
static const String PATH = '/Login';
|
static const String PATH = '/';
|
||||||
|
|
||||||
LoginScreen({Key key}) : super(key: key);
|
LoginScreen({Key key}) : super(key: key);
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ class LoginScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _LoginScreenState extends State<LoginScreen> {
|
class _LoginScreenState extends State<LoginScreen> {
|
||||||
|
|
||||||
// LoginBloc bloc;
|
LoginBloc bloc;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@ -29,12 +30,76 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
_init();
|
_init();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: StreamBuilder<bool>(
|
||||||
child: ConstrainedBox(
|
stream: bloc.authenticatedResult,
|
||||||
constraints: BoxConstraints(maxWidth: 500),
|
builder: (context, snapshot) {
|
||||||
child: Container(
|
if (snapshot.data == null || snapshot.data == true)
|
||||||
margin: EdgeInsets.fromLTRB(50, 0, 50, 0),
|
return _appLoading();
|
||||||
height: 500,
|
return _appLogin();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init(){
|
||||||
|
if(bloc != null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bloc = LoginBloc(AppProvider.getApplication(context));
|
||||||
|
bloc.authenticatedResult.listen((bool status) {
|
||||||
|
if (status)
|
||||||
|
AppProvider.getRouter(context).navigateTo(context, "/Home", transition: TransitionType.fadeIn);
|
||||||
|
});
|
||||||
|
|
||||||
|
bloc.loginResult.listen((bool status) {
|
||||||
|
if (status == null || status == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AppProvider.getRouter(context).navigateTo(context, "/Home", transition: TransitionType.fadeIn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _appLoading(){
|
||||||
|
return Center(
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxWidth: 500),
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.fromLTRB(50, 0, 50, 0),
|
||||||
|
height: 270,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
child: const FlutterLogo(),
|
||||||
|
),
|
||||||
|
width: 175,
|
||||||
|
margin: EdgeInsets.fromLTRB(0, 0, 0, 50),
|
||||||
|
),
|
||||||
|
PlatformCircularProgressIndicator()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _appLogin(){
|
||||||
|
TextEditingController serverController = new TextEditingController();
|
||||||
|
TextEditingController userController = new TextEditingController();
|
||||||
|
TextEditingController passwordController = new TextEditingController();
|
||||||
|
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
return Center(
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxWidth: 500),
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.fromLTRB(50, 0, 50, 0),
|
||||||
|
height: 500,
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
@ -46,24 +111,45 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
margin: EdgeInsets.fromLTRB(0, 0, 0, 50),
|
margin: EdgeInsets.fromLTRB(0, 0, 0, 50),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
|
controller: serverController,
|
||||||
|
validator: (value) {
|
||||||
|
if (value.isEmpty) {
|
||||||
|
return 'Please enter server address';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Server Address'
|
labelText: 'Server Address'
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
|
controller: userController,
|
||||||
|
validator: (value) {
|
||||||
|
if (value.isEmpty) {
|
||||||
|
return 'Please enter username or email';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Username / Email'
|
labelText: 'Username / Email'
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
enableSuggestions: false,
|
enableSuggestions: false,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
|
controller: passwordController,
|
||||||
|
validator: (value) {
|
||||||
|
if (value.isEmpty) {
|
||||||
|
return 'Please enter password';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Password'
|
labelText: 'Password'
|
||||||
),
|
),
|
||||||
@ -73,11 +159,31 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: PlatformButton(
|
child: PlatformButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
AppProvider.getRouter(context).navigateTo(context, "/Home", transition: TransitionType.fadeIn);
|
if (!_formKey.currentState.validate())
|
||||||
|
return;
|
||||||
|
bloc.attemptLogin(userController.text, passwordController.text, serverController.text);
|
||||||
},
|
},
|
||||||
child: Text('Login')
|
child: Text('Login')
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
StreamBuilder<bool>(
|
||||||
|
stream: bloc.loginResult,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.data == null || snapshot.data == true)
|
||||||
|
return Container();
|
||||||
|
|
||||||
|
return Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
|
||||||
|
child: Text(
|
||||||
|
"Login Failed",
|
||||||
|
style: TextStyle(color: Colors.red),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -85,10 +191,4 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _init(){
|
|
||||||
// if(null == bloc){
|
|
||||||
// bloc = LoginBloc(AppProvider.getApplication(context));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
|
||||||
import 'package:fluro/fluro.dart';
|
|
||||||
|
|
||||||
import 'package:imagini/core/app_provider.dart';
|
|
||||||
import 'package:imagini/blocs/splash_bloc.dart';
|
|
||||||
import 'package:imagini/graphql/imagini_graphql.dart';
|
|
||||||
|
|
||||||
class SplashScreen extends StatefulWidget {
|
|
||||||
static const String PATH = '/';
|
|
||||||
|
|
||||||
SplashScreen({Key key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_SplashScreenState createState() => _SplashScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SplashScreenState extends State<SplashScreen> {
|
|
||||||
|
|
||||||
SplashBloc bloc;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
bloc.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
_init();
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
body: Center(
|
|
||||||
child: ConstrainedBox(
|
|
||||||
constraints: BoxConstraints(maxWidth: 500),
|
|
||||||
child: Container(
|
|
||||||
margin: EdgeInsets.fromLTRB(50, 0, 50, 0),
|
|
||||||
height: 270,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Container(
|
|
||||||
child: FittedBox(
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
child: const FlutterLogo(),
|
|
||||||
),
|
|
||||||
width: 175,
|
|
||||||
margin: EdgeInsets.fromLTRB(0, 0, 0, 50),
|
|
||||||
),
|
|
||||||
PlatformCircularProgressIndicator()
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(){
|
|
||||||
if(null == bloc){
|
|
||||||
bloc = SplashBloc(AppProvider.getApplication(context));
|
|
||||||
bloc.loginResult.listen((Login$Query$AuthResponse lr) {
|
|
||||||
if (lr.result == AuthResult.success) {
|
|
||||||
AppProvider.getRouter(context).navigateTo(context, "/Home", transition: TransitionType.fadeIn);
|
|
||||||
} else {
|
|
||||||
AppProvider.getRouter(context).navigateTo(context, "/Login", transition: TransitionType.fadeIn);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user