Compare commits

..

No commits in common. "stashed-flutter" and "master" have entirely different histories.

17 changed files with 91 additions and 312 deletions

View File

@ -12,8 +12,6 @@ PODS:
- Flutter
- path_provider (0.0.1):
- Flutter
- photo_manager (0.0.1):
- Flutter
- Reachability (3.2)
- sqflite (0.0.2):
- Flutter
@ -25,7 +23,6 @@ DEPENDENCIES:
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
SPEC REPOS:
@ -44,8 +41,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios"
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
photo_manager:
:path: ".symlinks/plugins/photo_manager/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/ios"
@ -56,7 +51,6 @@ SPEC CHECKSUMS:
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
photo_manager: f7c619c2cc8c2adb8d85c63363babac477de9c67
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904

View File

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>App needs access to Gallery</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>

View File

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>App needs access to Gallery</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>

View File

@ -1,10 +1,9 @@
import 'dart:async';
import "package:imagini/api/auth_client/base_auth_client.dart";
import 'package:flutter/material.dart' show BoxFit, Center, SizedBox;
import 'package:imagini/api/auth_client/auth_client.dart'
if (dart.library.html) 'package:imagini/api/auth_client/browser_auth_client.dart'
if (dart.library.io) 'package:imagini/api/auth_client/io_auth_client.dart';
import 'package:imagini/api/cookie_client/cookie_client.dart'
if (dart.library.html) 'package:imagini/api/cookie_client/browser_cookie_client.dart'
if (dart.library.io) 'package:imagini/api/cookie_client/io_cookie_client.dart';
import 'package:imagini/core/storage_client/base_storage_client.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
@ -16,7 +15,6 @@ class APIProvider{
static const String _GRAPHQL_ENDPOINT = "/query";
BaseStorageClient _storage;
BaseAuthClient _authClient;
GraphQLClient _client;
HttpLink httpLink;
@ -25,22 +23,16 @@ class APIProvider{
}
Future<void> init() async {
// Initialize Server
String _server = await _storage.get("server");
if (_server == null) {
// Initialize
if (_server == null)
_server = "http://localhost";
await _storage.set("server", _server);
}
// Initialize Auth Client
_authClient = getAuthClient(_storage);
// Initialize HTTP Link
httpLink = HttpLink(_server + _GRAPHQL_ENDPOINT,
httpClient: _authClient,
httpClient: getCookieClient(_storage),
);
// Initialize GraphQL Client
_client = GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
@ -72,8 +64,11 @@ class APIProvider{
return response;
}
CachedNetworkImage getImage(String fileName, int width, int height) {
String server = _authClient.getServer();
Future<CachedNetworkImage> getImage(String fileName, int width, int height) async {
String server = await _storage.get("server");
String accessToken = await _storage.get("accessToken");
String refreshToken = await _storage.get("refreshToken");
String fullURL = "$server/media/$fileName?width=$width";
print(fullURL);
return CachedNetworkImage(
@ -86,36 +81,14 @@ class APIProvider{
),
),
imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
httpHeaders: _authClient.getHeaders(),
httpHeaders: {
"X-Imagini-AccessToken": accessToken,
"X-Imagini-RefreshToken": refreshToken,
},
fit: BoxFit.contain,
);
}
// Future<CachedNetworkImage> getImage(String fileName, int width, int height) async {
// String server = await _storage.get("server");
// String accessToken = await _storage.get("accessToken");
// String refreshToken = await _storage.get("refreshToken");
// String fullURL = "$server/media/$fileName?width=$width";
// print(fullURL);
// return CachedNetworkImage(
// imageUrl: fullURL,
// placeholder: (context, url) => Center(
// child: SizedBox(
// width: width.toDouble() / 3.5,
// height: height.toDouble() / 3.5,
// child: new PlatformCircularProgressIndicator(),
// ),
// ),
// imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
// httpHeaders: {
// "X-Imagini-AccessToken": accessToken,
// "X-Imagini-RefreshToken": refreshToken,
// },
// fit: BoxFit.contain,
// );
// }
Future<QueryResult> me() async {
QueryResult response = await _client.query(
QueryOptions(

View File

@ -1,4 +0,0 @@
import "package:imagini/api/auth_client/base_auth_client.dart";
BaseAuthClient getAuthClient(storage) => throw UnsupportedError(
'Cannot create a client without dart:html or dart:io.');

View File

@ -1,6 +0,0 @@
import 'package:http/http.dart';
abstract class BaseAuthClient implements BaseClient {
String getServer();
Map<String, String> getHeaders();
}

View File

@ -1,56 +0,0 @@
import "package:http/http.dart";
import 'package:http/browser_client.dart';
import "package:imagini/api/auth_client/base_auth_client.dart";
import "package:imagini/core/storage_client/base_storage_client.dart";
BaseClient getAuthClient(storage) => BrowserAuthClient(storage);
class BrowserAuthClient extends BrowserClient implements BaseAuthClient {
BaseStorageClient _storage;
String _cachedServer;
String _cachedAccessToken;
String _cachedRefreshToken;
BrowserAuthClient(BaseStorageClient storage) {
_storage = storage;
}
@override
String getServer() {
return _cachedServer;
}
@override
Map<String, String> getHeaders() {
return {
'X-Imagini-AccessToken': _cachedAccessToken,
'X-Imagini-RefreshToken': _cachedRefreshToken,
};
}
@override
Future<StreamedResponse> send(BaseRequest request) async {
String _accessToken = await _storage.get("accessToken");
String _refreshToken = await _storage.get("refreshToken");
_cachedAccessToken = _accessToken;
_cachedRefreshToken = _refreshToken;
request.headers.addAll({
'X-Imagini-AccessToken': _accessToken,
'X-Imagini-RefreshToken': _refreshToken,
});
return super.send(request).then((response) async {
if (response.headers.containsKey("x-imagini-accesstoken")) {
_cachedAccessToken = response.headers["x-imagini-accesstoken"];
await _storage.set("accessToken", response.headers["x-imagini-accesstoken"]);
}
if (response.headers.containsKey("x-imagini-refreshtoken")) {
_cachedRefreshToken = response.headers["x-imagini-refreshtoken"];
await _storage.set("refreshToken", response.headers["x-imagini-refreshtoken"]);
}
return response;
});
}
}

View File

@ -1,56 +0,0 @@
import "package:http/http.dart";
import 'package:http/io_client.dart';
import "package:imagini/api/auth_client/base_auth_client.dart";
import "package:imagini/core/storage_client/base_storage_client.dart";
BaseClient getAuthClient(storage) => IOAuthClient(storage);
class IOAuthClient extends IOClient implements BaseAuthClient {
BaseStorageClient _storage;
String _cachedServer;
String _cachedAccessToken;
String _cachedRefreshToken;
IOAuthClient(BaseStorageClient storage) {
_storage = storage;
}
@override
String getServer() {
return _cachedServer;
}
@override
Map<String, String> getHeaders() {
return {
'X-Imagini-AccessToken': _cachedAccessToken,
'X-Imagini-RefreshToken': _cachedRefreshToken,
};
}
@override
Future<IOStreamedResponse> send(BaseRequest request) async {
String _accessToken = await _storage.get("accessToken");
String _refreshToken = await _storage.get("refreshToken");
_cachedAccessToken = _accessToken;
_cachedRefreshToken = _refreshToken;
request.headers.addAll({
'X-Imagini-AccessToken': _accessToken,
'X-Imagini-RefreshToken': _refreshToken,
});
return super.send(request).then((response) async {
if (response.headers.containsKey("x-imagini-accesstoken")) {
_cachedAccessToken = response.headers["x-imagini-accesstoken"];
await _storage.set("accessToken", response.headers["x-imagini-accesstoken"]);
}
if (response.headers.containsKey("x-imagini-refreshtoken")) {
_cachedRefreshToken = response.headers["x-imagini-refreshtoken"];
await _storage.set("refreshToken", response.headers["x-imagini-refreshtoken"]);
}
return response;
});
}
}

View File

@ -39,7 +39,7 @@ class ImaginiAPIRepository {
}));
}
CachedNetworkImage getImage(String fileName, int width, int height) {
Future<CachedNetworkImage> getImage(String fileName, int width, int height) {
return _apiProvider.getImage(fileName, width, height);
}
}

View File

@ -1,12 +1,9 @@
import 'dart:io';
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';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:photo_manager/photo_manager.dart';
class HomeBloc{
final ImaginiApplication _application;
@ -30,31 +27,6 @@ class HomeBloc{
void _init(){
_imaginiAPI = _application.imaginiAPI;
_init_photo_manager();
}
void _init_photo_manager() async {
var result = await PhotoManager.requestPermission();
if (!result) {
PhotoManager.openSetting();
return;
}
// Gets list of "Albums"
List<AssetPathEntity> list = await PhotoManager.getAssetPathList();
// iOS - Select Gallery (predefined settings?)
// TODO: Filters: https://pub.dev/packages/photo_manager#filteroption
final assetList = await list[0].getAssetListPaged(0, 50);
// Example entity. This should be done through a loop
AssetEntity currEntity = assetList[0];
// File, Create, Modified, Title
File file = await currEntity.file;
DateTime createDt = currEntity.createDateTime;
DateTime modifiedDt = currEntity.modifiedDateTime;
String title = await currEntity.titleAsync;
}
void dispose(){
@ -62,7 +34,7 @@ class HomeBloc{
_authenticatedController.close();
}
CachedNetworkImage getMedia(int index, derivedContentWidth) {
Future<CachedNetworkImage> getMedia(int index, derivedContentWidth) async {
MediaItems$Query$MediaItemResponse$MediaItem mediaDetails = await getMediaDetails(index);
if (mediaDetails == null)
return null;

View File

@ -4,8 +4,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:photo_view/photo_view_gallery.dart';
import 'package:photo_view/photo_view.dart';
import 'package:imagini/blocs/home_bloc.dart';
import 'package:imagini/core/app_provider.dart';
@ -113,36 +111,6 @@ class _HomeScreenState extends State<HomeScreen> {
);
}
// Widget _buildPhotoPreview(){
// return Container(
// child: PhotoViewGallery.builder(
// scrollPhysics: const BouncingScrollPhysics(),
// builder: (BuildContext context, int index) {
// return PhotoViewGalleryPageOptions(
// imageProvider: AssetImage(widget.galleryItems[index].image),
// initialScale: PhotoViewComputedScale.contained * 0.8,
// heroAttributes: PhotoViewHeroAttributes(tag: galleryItems[index].id),
// );
// },
// itemCount: _totalLength,
// loadingBuilder: (context, event) => Center(
// child: Container(
// width: 20.0,
// height: 20.0,
// child: CircularProgressIndicator(
// value: event == null
// ? 0
// : event.cumulativeBytesLoaded / event.expectedTotalBytes,
// ),
// ),
// ),
// // backgroundDecoration: widget.backgroundDecoration,
// // pageController: widget.pageController,
// // onPageChanged: onPageChanged,
// )
// );
// }
Widget _appLoading(){
return Center(
child: ConstrainedBox(
@ -173,8 +141,7 @@ class _HomeScreenState extends State<HomeScreen> {
maxCrossAxisExtent: 500 / queryData.devicePixelRatio,
staggeredTileBuilder: (int index) => new StaggeredTile.fit(1),
itemBuilder: (BuildContext context, int index) {
return bloc.getMedia(index, desiredContentWidth);
// return _buildCard(index, desiredContentWidth);
return _buildCard(index, desiredContentWidth);
},
);
}

View File

@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "12.0.0"
version: "14.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "0.40.6"
version: "0.41.2"
archive:
dependency: transitive
description:
@ -42,14 +42,14 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0"
version: "2.5.0-nullsafety.3"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.1.0-nullsafety.3"
build:
dependency: transitive
description:
@ -70,7 +70,7 @@ packages:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.8"
version: "2.1.7"
build_resolvers:
dependency: transitive
description:
@ -105,35 +105,28 @@ packages:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.0.0"
built_value_generator:
dependency: "direct dev"
description:
name: built_value_generator
url: "https://pub.dartlang.org"
source: hosted
version: "8.0.0"
version: "8.0.0-nullsafety.0"
cached_network_image:
dependency: "direct main"
description:
name: cached_network_image
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.1"
version: "2.5.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.0-nullsafety.5"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.0-nullsafety.3"
checked_yaml:
dependency: transitive
description:
@ -154,7 +147,7 @@ packages:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.0-nullsafety.3"
code_builder:
dependency: transitive
description:
@ -168,7 +161,7 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
version: "1.15.0-nullsafety.5"
connectivity:
dependency: transitive
description:
@ -224,7 +217,7 @@ packages:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.10"
version: "1.3.12"
equatable:
dependency: "direct main"
description:
@ -238,21 +231,21 @@ packages:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.0-nullsafety.3"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "0.1.3"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0"
version: "6.0.0-nullsafety.4"
fixnum:
dependency: transitive
description:
@ -304,7 +297,7 @@ packages:
name: flutter_platform_widgets
url: "https://pub.dartlang.org"
source: hosted
version: "0.80.0"
version: "0.80.0-beta.0"
flutter_secure_storage:
dependency: "direct main"
description:
@ -464,14 +457,14 @@ packages:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.5"
version: "0.3.4"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
version: "0.6.3-nullsafety.3"
json_annotation:
dependency: "direct main"
description:
@ -492,21 +485,21 @@ packages:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "0.11.4"
version: "1.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10"
version: "0.12.10-nullsafety.3"
meta:
dependency: "direct main"
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.3.0-nullsafety.6"
mime:
dependency: transitive
description:
@ -555,7 +548,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
version: "1.8.0-nullsafety.3"
path_provider:
dependency: transitive
description:
@ -590,14 +583,14 @@ packages:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
version: "0.0.4+3"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.0"
version: "1.10.0"
petitparser:
dependency: transitive
description:
@ -605,27 +598,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
photo_manager:
dependency: "direct main"
description:
name: photo_manager
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.0"
photo_view:
dependency: "direct main"
description:
name: photo_view
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.3"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
version: "3.0.0-nullsafety.4"
plugin_platform_interface:
dependency: transitive
description:
@ -639,14 +618,14 @@ packages:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.0"
version: "1.4.0"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
version: "4.0.0-nullsafety.4"
pub_semver:
dependency: transitive
description:
@ -661,13 +640,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.8"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
recase:
dependency: transitive
description:
@ -695,7 +667,7 @@ packages:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.4+1"
version: "0.2.4"
sky_engine:
dependency: transitive
description: flutter
@ -707,21 +679,21 @@ packages:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.10+2"
version: "0.9.10+1"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
version: "1.8.0-nullsafety.4"
sqflite:
dependency: transitive
description:
name: sqflite
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.2+4"
version: "1.3.2+3"
sqflite_common:
dependency: transitive
description:
@ -735,14 +707,14 @@ packages:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
version: "1.10.0-nullsafety.6"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.1.0-nullsafety.3"
stream_transform:
dependency: transitive
description:
@ -756,7 +728,7 @@ packages:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.0-nullsafety.3"
sync_http:
dependency: transitive
description:
@ -777,14 +749,14 @@ packages:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.0-nullsafety.3"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19"
version: "0.2.19-nullsafety.6"
timing:
dependency: transitive
description:
@ -798,7 +770,7 @@ packages:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.3.0-nullsafety.5"
uuid:
dependency: transitive
description:
@ -819,7 +791,7 @@ packages:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.1.0-nullsafety.5"
vm_service:
dependency: transitive
description:
@ -861,7 +833,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "1.7.4+1"
xdg_directories:
dependency: transitive
description:
@ -884,5 +856,5 @@ packages:
source: hosted
version: "2.2.1"
sdks:
dart: ">=2.12.0-259.9.beta <3.0.0"
dart: ">=2.12.0-0.0 <3.0.0"
flutter: ">=1.22.2"

View File

@ -10,19 +10,17 @@ environment:
dependencies:
flutter:
sdk: flutter
photo_view: ^0.10.3
photo_manager: ^0.6.0
graphql_flutter: ^4.0.1
flutter_staggered_grid_view: "^0.3.2"
fluro: ^1.7.8
equatable: ^1.2.5
http: ^0.12.0+2
http: ^0.12.2
flutter_secure_storage: ^3.3.5
flutter_platform_widgets: ^0.80.0-beta.0
json_annotation: ^3.1.0
meta: '>=1.0.0 <2.0.0'
gql: '>=0.12.3 <1.0.0'
cached_network_image: ^2.5.1
cached_network_image: ^2.5.0
cupertino_icons: ^1.0.1
flutter_launcher_icons: ^0.8.1
@ -33,7 +31,6 @@ dev_dependencies:
sdk: flutter
artemis: '>=6.0.0 <7.0.0'
build_runner: ^1.10.4
built_value_generator: any
json_serializable: ^3.5.0
flutter:

View File

@ -0,0 +1,30 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:imagini/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}