Improve repo structure (#22)
* app updated * readme updated * rename base folder * update chatty's readme * move apps to packages dir * update repo overview Co-authored-by: diegoveloper <[email protected]>
This commit is contained in:
co-authored by
diegoveloper
parent
bd6bb66279
commit
030c3eb428
@@ -0,0 +1,7 @@
|
||||
import 'package:stream_chatter/domain/models/auth_user.dart';
|
||||
|
||||
abstract class AuthRepository {
|
||||
Future<AuthUser> getAuthUser();
|
||||
Future<AuthUser> signIn();
|
||||
Future<void> logout();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
abstract class ImagePickerRepository {
|
||||
Future<File> pickImage();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:stream_chatter/data/auth_repository.dart';
|
||||
import 'package:stream_chatter/domain/models/auth_user.dart';
|
||||
|
||||
class AuthLocalImpl extends AuthRepository {
|
||||
@override
|
||||
Future<AuthUser> getAuthUser() async {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
return AuthUser('diego');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AuthUser> signIn() async {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
return AuthUser('diego');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> logout() async {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'dart:io';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:stream_chatter/data/image_picker_repository.dart';
|
||||
|
||||
class ImagePickerImpl extends ImagePickerRepository {
|
||||
@override
|
||||
Future<File> pickImage() async {
|
||||
final picker = ImagePicker();
|
||||
final pickedFile = await picker.getImage(source: ImageSource.gallery, maxWidth: 400);
|
||||
return File(pickedFile.path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:stream_chatter/data/persistent_storage_repository.dart';
|
||||
|
||||
class PersistentStorageLocalImpl extends PersistentStorageRepository {
|
||||
@override
|
||||
Future<bool> isDarkMode() async {
|
||||
await Future.delayed(const Duration(milliseconds: 50));
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateDarkMode(bool isDarkMode) async {
|
||||
await Future.delayed(const Duration(milliseconds: 50));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import 'package:stream_chatter/data/stream_api_repository.dart';
|
||||
import 'package:stream_chatter/domain/models/chat_user.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
class StreamApiLocalImpl extends StreamApiRepository {
|
||||
StreamApiLocalImpl(this._client);
|
||||
|
||||
final StreamChatClient _client;
|
||||
|
||||
@override
|
||||
Future<ChatUser> connectUser(ChatUser user, String token) async {
|
||||
Map<String, dynamic> extraData = {};
|
||||
if (user.image != null) {
|
||||
extraData['image'] = user.image;
|
||||
}
|
||||
if (user.name != null) {
|
||||
extraData['name'] = user.name;
|
||||
}
|
||||
await _client.disconnect();
|
||||
await _client.connectUser(
|
||||
User(id: user.id, extraData: extraData),
|
||||
token,
|
||||
);
|
||||
return user;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ChatUser>> getChatUsers() async {
|
||||
final result = await _client.queryUsers();
|
||||
final chatUsers = result.users
|
||||
.where((element) => element.id != _client.state.user.id)
|
||||
.map(
|
||||
(e) => ChatUser(
|
||||
id: e.id,
|
||||
name: e.name,
|
||||
image: e.extraData['image'],
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return chatUsers;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getToken(String userId) async {
|
||||
return _client.devToken(userId);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Channel> createGroupChat(String channelId, String name, List<String> members, {String image}) async {
|
||||
final channel = _client.channel('messaging', id: channelId, extraData: {
|
||||
'name': name,
|
||||
'image': image,
|
||||
'members': [_client.state.user.id, ...members],
|
||||
});
|
||||
await channel.watch();
|
||||
return channel;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Channel> createSimpleChat(String friendId) async {
|
||||
final channel =
|
||||
_client.channel('messaging', id: '${_client.state.user.id.hashCode}${friendId.hashCode}', extraData: {
|
||||
'members': [
|
||||
friendId,
|
||||
_client.state.user.id,
|
||||
],
|
||||
});
|
||||
await channel.watch();
|
||||
return channel;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> logout() {
|
||||
return _client.disconnect();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> connectIfExist(String userId) async {
|
||||
final token = await getToken(userId);
|
||||
await _client.connectUser(
|
||||
User(id: userId),
|
||||
token,
|
||||
);
|
||||
return _client.state.user.name != null && _client.state.user.name != userId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:stream_chatter/data/upload_storage_repository.dart';
|
||||
|
||||
class UploadStorageLocalImpl extends UploadStorageRepository {
|
||||
@override
|
||||
Future<String> uploadPhoto(File file, String path) async {
|
||||
return 'https://lh3.googleusercontent.com/a-/AOh14GjhqGZ-V7tNXS1pOIp9vbBij4OS9JbzxXgxgy1t=s600-k-no-rp-mo';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
abstract class PersistentStorageRepository {
|
||||
Future<bool> isDarkMode();
|
||||
Future<void> updateDarkMode(bool isDarkMode);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:stream_chatter/data/auth_repository.dart';
|
||||
import 'package:stream_chatter/domain/models/auth_user.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
|
||||
class AuthImpl extends AuthRepository {
|
||||
FirebaseAuth _auth = FirebaseAuth.instance;
|
||||
|
||||
@override
|
||||
Future<AuthUser> getAuthUser() async {
|
||||
final user = _auth.currentUser;
|
||||
if (user != null) {
|
||||
return AuthUser(user.uid);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AuthUser> signIn() async {
|
||||
try {
|
||||
UserCredential userCredential;
|
||||
final GoogleSignInAccount googleUser = await GoogleSignIn().signIn();
|
||||
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
|
||||
final GoogleAuthCredential googleAuthCredential = GoogleAuthProvider.credential(
|
||||
accessToken: googleAuth.accessToken,
|
||||
idToken: googleAuth.idToken,
|
||||
);
|
||||
userCredential = await _auth.signInWithCredential(googleAuthCredential);
|
||||
final user = userCredential.user;
|
||||
return AuthUser(user.uid);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
throw Exception('login error');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> logout() async {
|
||||
return _auth.signOut();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:stream_chatter/data/persistent_storage_repository.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
const _isDarkMode = 'isDarkMode';
|
||||
|
||||
class PersistentStorageImpl extends PersistentStorageRepository {
|
||||
@override
|
||||
Future<bool> isDarkMode() async {
|
||||
final preference = await SharedPreferences.getInstance();
|
||||
return preference.getBool(_isDarkMode) ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateDarkMode(bool isDarkMode) async {
|
||||
final preference = await SharedPreferences.getInstance();
|
||||
return await preference.setBool(_isDarkMode, isDarkMode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:stream_chatter/data/stream_api_repository.dart';
|
||||
import 'package:stream_chatter/domain/models/chat_user.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class StreamApiImpl extends StreamApiRepository {
|
||||
StreamApiImpl(this._client);
|
||||
|
||||
final StreamChatClient _client;
|
||||
|
||||
@override
|
||||
Future<ChatUser> connectUser(ChatUser user, String token) async {
|
||||
Map<String, dynamic> extraData = {};
|
||||
if (user.image != null) {
|
||||
extraData['image'] = user.image;
|
||||
}
|
||||
if (user.name != null) {
|
||||
extraData['name'] = user.name;
|
||||
}
|
||||
await _client.disconnect();
|
||||
await _client.connectUser(
|
||||
User(id: user.id, extraData: extraData),
|
||||
token,
|
||||
);
|
||||
return user;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ChatUser>> getChatUsers() async {
|
||||
final result = await _client.queryUsers();
|
||||
final chatUsers = result.users
|
||||
.where((element) => element.id != _client.state.user.id)
|
||||
.map(
|
||||
(e) => ChatUser(
|
||||
id: e.id,
|
||||
name: e.name,
|
||||
image: e.extraData['image'],
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return chatUsers;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getToken(String userId) async {
|
||||
//TODO: use your own implementation in Production
|
||||
final response = await http.post(
|
||||
'your_backend_url',
|
||||
body: jsonEncode(<String, String>{'id': userId}),
|
||||
headers: <String, String>{
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
);
|
||||
final token = jsonDecode(response.body)['token'];
|
||||
|
||||
//In Development mode you can just use :
|
||||
// _client.devToken(userId);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Channel> createGroupChat(String id, String name, List<String> members, {String image}) async {
|
||||
final channel = _client.channel('messaging', id: id, extraData: {
|
||||
'name': name,
|
||||
'image': image,
|
||||
'members': [_client.state.user.id, ...members],
|
||||
});
|
||||
await channel.watch();
|
||||
return channel;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Channel> createSimpleChat(String friendId) async {
|
||||
final channel =
|
||||
_client.channel('messaging', id: '${_client.state.user.id.hashCode}${friendId.hashCode}', extraData: {
|
||||
'members': [
|
||||
friendId,
|
||||
_client.state.user.id,
|
||||
],
|
||||
});
|
||||
await channel.watch();
|
||||
return channel;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> logout() async {
|
||||
return _client.disconnect();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> connectIfExist(String userId) async {
|
||||
final token = await getToken(userId);
|
||||
await _client.connectUser(
|
||||
User(id: userId),
|
||||
token,
|
||||
);
|
||||
return _client.state.user.name != null && _client.state.user.name != userId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'dart:io';
|
||||
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
|
||||
import 'package:stream_chatter/data/upload_storage_repository.dart';
|
||||
|
||||
class UploadStorageImpl extends UploadStorageRepository {
|
||||
@override
|
||||
Future<String> uploadPhoto(File file, String path) async {
|
||||
final ref = firebase_storage.FirebaseStorage.instance.ref(path);
|
||||
final uploadTask = ref.putFile(file);
|
||||
await uploadTask;
|
||||
return await ref.getDownloadURL();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:stream_chatter/domain/models/chat_user.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
abstract class StreamApiRepository {
|
||||
Future<List<ChatUser>> getChatUsers();
|
||||
Future<String> getToken(String userId);
|
||||
Future<bool> connectIfExist(String userId);
|
||||
Future<ChatUser> connectUser(ChatUser user, String token);
|
||||
Future<Channel> createGroupChat(String channelId, String name, List<String> members, {String image});
|
||||
Future<Channel> createSimpleChat(String friendId);
|
||||
Future<void> logout();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
abstract class UploadStorageRepository {
|
||||
Future<String> uploadPhoto(File file, String path);
|
||||
}
|
||||
Reference in New Issue
Block a user