Switch to new endpoints

This commit is contained in:
Nutcake 2023-09-29 09:51:46 +02:00
parent 491b392944
commit 73f41ef71e
26 changed files with 159 additions and 147 deletions

View file

@ -2,12 +2,36 @@ import 'dart:convert';
import 'package:contacts_plus_plus/clients/api_client.dart'; import 'package:contacts_plus_plus/clients/api_client.dart';
import 'package:contacts_plus_plus/models/users/friend.dart'; import 'package:contacts_plus_plus/models/users/friend.dart';
import 'package:contacts_plus_plus/models/users/friend_status.dart';
import 'package:contacts_plus_plus/models/users/user.dart';
import 'package:contacts_plus_plus/models/users/user_profile.dart';
import 'package:contacts_plus_plus/models/users/user_status.dart';
class FriendApi { class FriendApi {
static Future<List<Friend>> getFriendsList(ApiClient client, {DateTime? lastStatusUpdate}) async { static Future<List<Friend>> getFriendsList(ApiClient client, {DateTime? lastStatusUpdate}) async {
final response = await client.get("/users/${client.userId}/friends${lastStatusUpdate != null ? "?lastStatusUpdate=${lastStatusUpdate.toUtc().toIso8601String()}" : ""}"); final response = await client.get("/users/${client.userId}/contacts${lastStatusUpdate != null ? "?lastStatusUpdate=${lastStatusUpdate.toUtc().toIso8601String()}" : ""}");
client.checkResponse(response); client.checkResponse(response);
final data = jsonDecode(response.body) as List; final data = jsonDecode(response.body) as List;
return data.map((e) => Friend.fromMap(e)).toList(); return data.map((e) => Friend.fromMap(e)).toList();
} }
static Future<void> addUserAsFriend(ApiClient client, {required User user}) async {
final friend = Friend(
id: user.id,
username: user.username,
ownerId: client.userId,
userStatus: UserStatus.empty(),
userProfile: UserProfile.empty(),
friendStatus: FriendStatus.accepted,
latestMessageTime: DateTime.now(),
);
final body = jsonEncode(friend.toMap(shallow: true));
final response = await client.put("/users/${client.userId}/contacts/${user.id}", body: body);
client.checkResponse(response);
}
static Future<void> removeUserAsFriend(ApiClient client, {required User user}) async {
final response = await client.delete("/users/${client.userId}/friends/${user.id}");
client.checkResponse(response);
}
} }

View file

@ -68,7 +68,7 @@ class RecordApi {
return status; return status;
} }
static Future<AssetUploadData> beginUploadAsset(ApiClient client, {required NeosDBAsset asset}) async { static Future<AssetUploadData> beginUploadAsset(ApiClient client, {required ResoniteDBAsset asset}) async {
final response = await client.post("/users/${client.userId}/assets/${asset.hash}/chunks"); final response = await client.post("/users/${client.userId}/assets/${asset.hash}/chunks");
client.checkResponse(response); client.checkResponse(response);
final body = jsonDecode(response.body); final body = jsonDecode(response.body);
@ -84,7 +84,7 @@ class RecordApi {
} }
static Future<void> uploadAsset(ApiClient client, static Future<void> uploadAsset(ApiClient client,
{required AssetUploadData uploadData, required String filename, required NeosDBAsset asset, required Uint8List data, void Function(double number)? progressCallback}) async { {required AssetUploadData uploadData, required String filename, required ResoniteDBAsset asset, required Uint8List data, void Function(double number)? progressCallback}) async {
for (int i = 0; i < uploadData.totalChunks; i++) { for (int i = 0; i < uploadData.totalChunks; i++) {
progressCallback?.call(i/uploadData.totalChunks); progressCallback?.call(i/uploadData.totalChunks);
final offset = i * uploadData.chunkSize; final offset = i * uploadData.chunkSize;
@ -104,7 +104,7 @@ class RecordApi {
} }
} }
static Future<void> finishUpload(ApiClient client, {required NeosDBAsset asset}) async { static Future<void> finishUpload(ApiClient client, {required ResoniteDBAsset asset}) async {
final response = await client.patch("/users/${client.userId}/assets/${asset.hash}/chunks"); final response = await client.patch("/users/${client.userId}/assets/${asset.hash}/chunks");
client.checkResponse(response); client.checkResponse(response);
} }

View file

@ -25,6 +25,7 @@ class UserApi {
} }
static Future<UserStatus> getUserStatus(ApiClient client, {required String userId}) async { static Future<UserStatus> getUserStatus(ApiClient client, {required String userId}) async {
return UserStatus.empty();
final response = await client.get("/users/$userId/status"); final response = await client.get("/users/$userId/status");
client.checkResponse(response); client.checkResponse(response);
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
@ -32,11 +33,12 @@ class UserApi {
} }
static Future<void> notifyOnlineInstance(ApiClient client) async { static Future<void> notifyOnlineInstance(ApiClient client) async {
final response = await client.post("/stats/instanceOnline/${client.authenticationData.secretMachineId.hashCode}"); final response = await client.post("/stats/instanceOnline/${client.authenticationData.secretMachineIdHash}");
client.checkResponse(response); client.checkResponse(response);
} }
static Future<void> setStatus(ApiClient client, {required UserStatus status}) async { static Future<void> setStatus(ApiClient client, {required UserStatus status}) async {
return;
final pkginfo = await PackageInfo.fromPlatform(); final pkginfo = await PackageInfo.fromPlatform();
status = status.copyWith( status = status.copyWith(
neosVersion: "${pkginfo.version} of ${pkginfo.appName}", neosVersion: "${pkginfo.version} of ${pkginfo.appName}",
@ -53,24 +55,4 @@ class UserApi {
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
return PersonalProfile.fromMap(data); return PersonalProfile.fromMap(data);
} }
static Future<void> addUserAsFriend(ApiClient client, {required User user}) async {
final friend = Friend(
id: user.id,
username: user.username,
ownerId: client.userId,
userStatus: UserStatus.empty(),
userProfile: UserProfile.empty(),
friendStatus: FriendStatus.accepted,
latestMessageTime: DateTime.now(),
);
final body = jsonEncode(friend.toMap(shallow: true));
final response = await client.put("/users/${client.userId}/friends/${user.id}", body: body);
client.checkResponse(response);
}
static Future<void> removeUserAsFriend(ApiClient client, {required User user}) async {
final response = await client.delete("/users/${client.userId}/friends/${user.id}");
client.checkResponse(response);
}
} }

View file

@ -3,53 +3,12 @@ import 'package:flutter/material.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:html/parser.dart' as htmlparser; import 'package:html/parser.dart' as htmlparser;
enum NeosDBEndpoint
{
def,
blob,
cdn,
videoCDN,
}
extension NeosStringExtensions on Uri {
static String dbSignature(Uri neosdb) => neosdb.pathSegments.length < 2 ? "" : p.basenameWithoutExtension(neosdb.pathSegments[1]);
static String? neosDBQuery(Uri neosdb) => neosdb.query.trim().isEmpty ? null : neosdb.query.substring(1);
static bool isLegacyNeosDB(Uri uri) => !(uri.scheme != "neosdb") && uri.pathSegments.length >= 2 && p.basenameWithoutExtension(uri.pathSegments[1]).length < 30;
Uri neosDBToHTTP(NeosDBEndpoint endpoint) {
var signature = dbSignature(this);
var query = neosDBQuery(this);
if (query != null) {
signature = "$signature/$query";
}
if (isLegacyNeosDB(this)) {
return Uri.parse(Config.legacyCloudUrl + signature);
}
String base;
switch (endpoint) {
case NeosDBEndpoint.blob:
base = Config.blobStorageUrl;
break;
case NeosDBEndpoint.cdn:
base = Config.neosCdnUrl;
break;
case NeosDBEndpoint.videoCDN:
base = Config.videoStorageUrl;
break;
case NeosDBEndpoint.def:
base = Config.neosAssetsUrl;
}
return Uri.parse(base + signature);
}
}
class Aux { class Aux {
static String neosDbToHttp(String? neosdb) { static String resdbToHttp(String? resdb) {
if (neosdb == null || neosdb.isEmpty) return ""; if (resdb == null || resdb.isEmpty) return "";
if (neosdb.startsWith("http")) return neosdb; if (resdb.startsWith("http")) return resdb;
final filename = p.basenameWithoutExtension(neosdb); final filename = p.basenameWithoutExtension(resdb);
return "${Config.neosCdnUrl}$filename"; return "${Config.skyfrostAssetsUrl}$filename";
} }
} }

View file

@ -41,14 +41,19 @@ class ApiClient {
}) async { }) async {
final body = { final body = {
(username.contains("@") ? "email" : "username"): username.trim(), (username.contains("@") ? "email" : "username"): username.trim(),
"password": password, "authentication": {
"\$type": "password",
"password": password,
},
"rememberMe": rememberMe, "rememberMe": rememberMe,
"secretMachineId": const Uuid().v4(), "secretMachineId": const Uuid().v4(),
}; };
final response = await http.post( final response = await http.post(
buildFullUri("/UserSessions"), buildFullUri("/userSessions"),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"SecretClientAccessKey": Config.secretClientKey,
"UID":"2cde2bd72c104d1785af28ae77c29fc2",
if (oneTimePad != null) totpKey: oneTimePad, if (oneTimePad != null) totpKey: oneTimePad,
}, },
body: jsonEncode(body), body: jsonEncode(body),
@ -67,7 +72,7 @@ class ApiClient {
aOptions: AndroidOptions(encryptedSharedPreferences: true), aOptions: AndroidOptions(encryptedSharedPreferences: true),
); );
await storage.write(key: userIdKey, value: authData.userId); await storage.write(key: userIdKey, value: authData.userId);
await storage.write(key: machineIdKey, value: authData.secretMachineId); await storage.write(key: machineIdKey, value: authData.secretMachineIdHash);
await storage.write(key: tokenKey, value: authData.token); await storage.write(key: tokenKey, value: authData.token);
if (rememberPass) await storage.write(key: passwordKey, value: password); if (rememberPass) await storage.write(key: passwordKey, value: password);
} }
@ -88,10 +93,13 @@ class ApiClient {
} }
if (token != null) { if (token != null) {
final response = final response = await http.patch(buildFullUri("/userSessions"), headers: {
await http.patch(buildFullUri("/userSessions"), headers: {"Authorization": "neos $userId:$token"}); "Authorization": "res $userId:$token",
"UID":"2cde2bd72c104d1785af28ae77c29fc2",
"SecretClientAccessKey": Config.secretClientKey,
});
if (response.statusCode < 300) { if (response.statusCode < 300) {
return AuthenticationData(userId: userId, token: token, secretMachineId: machineId, isAuthenticated: true); return AuthenticationData(userId: userId, token: token, secretMachineIdHash: machineId, isAuthenticated: true);
} }
} }
@ -148,13 +156,16 @@ class ApiClient {
_ => "Unknown Error." _ => "Unknown Error."
}} (${response.statusCode}${kDebugMode && response.body.isNotEmpty ? "|${response.body}" : ""})"; }} (${response.statusCode}${kDebugMode && response.body.isNotEmpty ? "|${response.body}" : ""})";
FlutterError.reportError(FlutterErrorDetails(exception: error)); FlutterError.reportError(FlutterErrorDetails(
exception: error,
stack: StackTrace.current,
));
throw error; throw error;
} }
Map<String, String> get authorizationHeader => _authenticationData.authorizationHeader; Map<String, String> get authorizationHeader => _authenticationData.authorizationHeader;
static Uri buildFullUri(String path) => Uri.parse("${Config.apiBaseUrl}/api$path"); static Uri buildFullUri(String path) => Uri.parse("${Config.apiBaseUrl}$path");
Future<http.Response> get(String path, {Map<String, String>? headers}) async { Future<http.Response> get(String path, {Map<String, String>? headers}) async {
headers ??= {}; headers ??= {};

View file

@ -15,7 +15,7 @@ class AudioCacheClient {
final file = File("${directory.path}/${basename(clip.assetUri)}"); final file = File("${directory.path}/${basename(clip.assetUri)}");
if (!await file.exists()) { if (!await file.exists()) {
await file.create(recursive: true); await file.create(recursive: true);
final response = await http.get(Uri.parse(Aux.neosDbToHttp(clip.assetUri))); final response = await http.get(Uri.parse(Aux.resdbToHttp(clip.assetUri)));
ApiClient.checkResponseCode(response); ApiClient.checkResponseCode(response);
await file.writeAsBytes(response.bodyBytes); await file.writeAsBytes(response.bodyBytes);
} }

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -288,7 +289,7 @@ class MessagingClient extends ChangeNotifier {
final http.Response response; final http.Response response;
try { try {
response = await http.post( response = await http.post(
Uri.parse("${Config.neosHubUrl}/negotiate"), Uri.parse("${Config.resoniteHubUrl}/negotiate"),
headers: _apiClient.authorizationHeader, headers: _apiClient.authorizationHeader,
); );
_apiClient.checkResponse(response); _apiClient.checkResponse(response);

View file

@ -1,11 +1,9 @@
class Config { class Config {
static const String apiBaseUrl = "https://api.neos.com"; static const String apiBaseUrl = "https://api.resonite.com";
static const String legacyCloudUrl = "https://neoscloud.blob.core.windows.net/assets/"; static const String durianAssetsUrl = "https://assets.everion.com";
static const String blobStorageUrl = "https://cloudxstorage.blob.core.windows.net/assets/"; static const String skyfrostAssetsUrl = "https://assets.resonite.com";
static const String videoStorageUrl = "https://cloudx-video.azureedge.net/"; static const String resoniteHubUrl = "$apiBaseUrl/hub";
static const String neosCdnUrl = "https://cloudx.azureedge.net/assets/"; static const String secretClientKey = "";
static const String neosAssetsUrl = "https://cloudxstorage.blob.core.windows.net/assets/";
static const String neosHubUrl = "$apiBaseUrl/hub";
static const int messageCacheValiditySeconds = 90; static const int messageCacheValiditySeconds = 90;

View file

@ -1,35 +1,40 @@
import 'package:contacts_plus_plus/config.dart';
class AuthenticationData { class AuthenticationData {
static const _unauthenticated = AuthenticationData(userId: "", token: "", secretMachineId: "", isAuthenticated: false); static const _unauthenticated = AuthenticationData(userId: "", token: "", secretMachineIdHash: "", isAuthenticated: false);
final String userId; final String userId;
final String token; final String token;
final String secretMachineId; final String secretMachineIdHash;
final bool isAuthenticated; final bool isAuthenticated;
const AuthenticationData({ const AuthenticationData({
required this.userId, required this.token, required this.secretMachineId, required this.isAuthenticated required this.userId, required this.token, required this.secretMachineIdHash, required this.isAuthenticated
}); });
factory AuthenticationData.fromMap(Map map) { factory AuthenticationData.fromMap(Map map) {
map = map["entity"];
final userId = map["userId"]; final userId = map["userId"];
final token = map["token"]; final token = map["token"];
final machineId = map["secretMachineId"]; final machineId = map["secretMachineIdHash"];
if (userId == null || token == null || machineId == null) { if (userId == null || token == null || machineId == null) {
return _unauthenticated; return _unauthenticated;
} }
return AuthenticationData(userId: userId, token: token, secretMachineId: machineId, isAuthenticated: true); return AuthenticationData(userId: userId, token: token, secretMachineIdHash: machineId, isAuthenticated: true);
} }
factory AuthenticationData.unauthenticated() => _unauthenticated; factory AuthenticationData.unauthenticated() => _unauthenticated;
Map<String, String> get authorizationHeader => { Map<String, String> get authorizationHeader => {
"Authorization": "neos $userId:$token" "Authorization": "res $userId:$token",
"SecretClientAccessKey": Config.secretClientKey,
"UID":"2cde2bd72c104d1785af28ae77c29fc2",
}; };
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
"userId": userId, "userId": userId,
"token": token, "token": token,
"secretMachineId": secretMachineId, "secretMachineId": secretMachineIdHash,
}; };
} }
} }

View file

@ -1,7 +1,7 @@
import 'package:contacts_plus_plus/models/records/neos_db_asset.dart'; import 'package:contacts_plus_plus/models/records/neos_db_asset.dart';
class AssetDiff extends NeosDBAsset{ class AssetDiff extends ResoniteDBAsset{
final Diff state; final Diff state;
final bool isUploaded; final bool isUploaded;

View file

@ -6,20 +6,20 @@ import 'package:path/path.dart';
class AssetDigest { class AssetDigest {
final Uint8List data; final Uint8List data;
final NeosDBAsset asset; final ResoniteDBAsset asset;
final String name; final String name;
final String dbUri; final String dbUri;
AssetDigest({required this.data, required this.asset, required this.name, required this.dbUri}); AssetDigest({required this.data, required this.asset, required this.name, required this.dbUri});
static Future<AssetDigest> fromData(Uint8List data, String filename) async { static Future<AssetDigest> fromData(Uint8List data, String filename) async {
final asset = NeosDBAsset.fromData(data); final asset = ResoniteDBAsset.fromData(data);
return AssetDigest( return AssetDigest(
data: data, data: data,
asset: asset, asset: asset,
name: basenameWithoutExtension(filename), name: basenameWithoutExtension(filename),
dbUri: "neosdb:///${asset.hash}${extension(filename)}", dbUri: "resdb:///${asset.hash}${extension(filename)}",
); );
} }
} }

View file

@ -2,19 +2,19 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
class NeosDBAsset { class ResoniteDBAsset {
final String hash; final String hash;
final int bytes; final int bytes;
const NeosDBAsset({required this.hash, required this.bytes}); const ResoniteDBAsset({required this.hash, required this.bytes});
factory NeosDBAsset.fromMap(Map map) { factory ResoniteDBAsset.fromMap(Map map) {
return NeosDBAsset(hash: map["hash"] ?? "", bytes: map["bytes"] ?? -1); return ResoniteDBAsset(hash: map["hash"] ?? "", bytes: map["bytes"] ?? -1);
} }
factory NeosDBAsset.fromData(Uint8List data) { factory ResoniteDBAsset.fromData(Uint8List data) {
final digest = sha256.convert(data); final digest = sha256.convert(data);
return NeosDBAsset(hash: digest.toString().replaceAll("-", "").toLowerCase(), bytes: data.length); return ResoniteDBAsset(hash: digest.toString().replaceAll("-", "").toLowerCase(), bytes: data.length);
} }
Map toMap() { Map toMap() {

View file

@ -100,7 +100,7 @@ class Record {
final int rating; final int rating;
final int randomOrder; final int randomOrder;
final List<String> manifest; final List<String> manifest;
final List<NeosDBAsset> neosDBManifest; final List<ResoniteDBAsset> neosDBManifest;
final String url; final String url;
final bool isValidOwnerId; final bool isValidOwnerId;
final bool isValidRecordId; final bool isValidRecordId;
@ -199,7 +199,7 @@ class Record {
isForPatreons: map["isForPatreons"] ?? false, isForPatreons: map["isForPatreons"] ?? false,
isListed: map["isListed"] ?? false, isListed: map["isListed"] ?? false,
lastModificationTime: DateTime.tryParse(map["lastModificationTime"]) ?? DateTimeX.epoch, lastModificationTime: DateTime.tryParse(map["lastModificationTime"]) ?? DateTimeX.epoch,
neosDBManifest: (map["neosDBManifest"] as List? ?? []).map((e) => NeosDBAsset.fromMap(e)).toList(), neosDBManifest: (map["neosDBManifest"] as List? ?? []).map((e) => ResoniteDBAsset.fromMap(e)).toList(),
lastModifyingUserId: map["lastModifyingUserId"] ?? "", lastModifyingUserId: map["lastModifyingUserId"] ?? "",
lastModifyingMachineId: map["lastModifyingMachineId"] ?? "", lastModifyingMachineId: map["lastModifyingMachineId"] ?? "",
creationTime: DateTime.tryParse(map["lastModificationTime"]) ?? DateTimeX.epoch, creationTime: DateTime.tryParse(map["lastModificationTime"]) ?? DateTimeX.epoch,
@ -265,7 +265,7 @@ class Record {
bool? isListed, bool? isListed,
bool? isDeleted, bool? isDeleted,
DateTime? lastModificationTime, DateTime? lastModificationTime,
List<NeosDBAsset>? neosDBManifest, List<ResoniteDBAsset>? neosDBManifest,
String? lastModifyingUserId, String? lastModifyingUserId,
String? lastModifyingMachineId, String? lastModifyingMachineId,
DateTime? creationTime, DateTime? creationTime,

View file

@ -19,7 +19,7 @@ class FriendListTile extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final imageUri = Aux.neosDbToHttp(friend.userProfile.iconUrl); final imageUri = Aux.resdbToHttp(friend.userProfile.iconUrl);
final theme = Theme.of(context); final theme = Theme.of(context);
return ListTile( return ListTile(
leading: GenericAvatar( leading: GenericAvatar(

View file

@ -1,4 +1,4 @@
import 'package:contacts_plus_plus/apis/user_api.dart'; import 'package:contacts_plus_plus/apis/friend_api.dart';
import 'package:contacts_plus_plus/auxiliary.dart'; import 'package:contacts_plus_plus/auxiliary.dart';
import 'package:contacts_plus_plus/client_holder.dart'; import 'package:contacts_plus_plus/client_holder.dart';
import 'package:contacts_plus_plus/models/users/user.dart'; import 'package:contacts_plus_plus/models/users/user.dart';
@ -41,7 +41,7 @@ class _UserListTileState extends State<UserListTile> {
), ),
); );
return ListTile( return ListTile(
leading: GenericAvatar(imageUri: Aux.neosDbToHttp(widget.user.userProfile?.iconUrl),), leading: GenericAvatar(imageUri: Aux.resdbToHttp(widget.user.userProfile?.iconUrl),),
title: Text(widget.user.username), title: Text(widget.user.username),
subtitle: Text(_regDateFormat.format(widget.user.registrationDate)), subtitle: Text(_regDateFormat.format(widget.user.registrationDate)),
trailing: IconButton( trailing: IconButton(
@ -55,11 +55,11 @@ class _UserListTileState extends State<UserListTile> {
}); });
try { try {
if (_localAdded) { if (_localAdded) {
await UserApi.removeUserAsFriend(ClientHolder await FriendApi.removeUserAsFriend(ClientHolder
.of(context) .of(context)
.apiClient, user: widget.user); .apiClient, user: widget.user);
} else { } else {
await UserApi.addUserAsFriend(ClientHolder await FriendApi.addUserAsFriend(ClientHolder
.of(context) .of(context)
.apiClient, user: widget.user); .apiClient, user: widget.user);
} }

View file

@ -179,7 +179,7 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
builder: (context) => PhotoView( builder: (context) => PhotoView(
minScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained,
imageProvider: imageProvider:
CachedNetworkImageProvider(Aux.neosDbToHttp(record.thumbnailUri)), CachedNetworkImageProvider(Aux.resdbToHttp(record.thumbnailUri)),
heroAttributes: PhotoViewHeroAttributes(tag: record.id), heroAttributes: PhotoViewHeroAttributes(tag: record.id),
), ),
), ),

View file

@ -142,7 +142,7 @@ class _InventoryBrowserAppBarState extends State<InventoryBrowserAppBar> {
for (var record in selectedRecords) { for (var record in selectedRecords) {
final uri = selectedUris == thumbUris ? record.thumbnailUri : record.thumbnailUri; final uri = selectedUris == thumbUris ? record.thumbnailUri : record.thumbnailUri;
await FlutterDownloader.enqueue( await FlutterDownloader.enqueue(
url: Aux.neosDbToHttp(uri), url: Aux.resdbToHttp(uri),
savedDir: directory, savedDir: directory,
showNotification: true, showNotification: true,
openFileFromNotification: false, openFileFromNotification: false,

View file

@ -42,7 +42,7 @@ class ObjectInventoryTile extends StatelessWidget {
child: CachedNetworkImage( child: CachedNetworkImage(
height: double.infinity, height: double.infinity,
width: double.infinity, width: double.infinity,
imageUrl: Aux.neosDbToHttp(record.thumbnailUri), imageUrl: Aux.resdbToHttp(record.thumbnailUri),
fit: BoxFit.cover, fit: BoxFit.cover,
errorWidget: (context, url, error) => const Center( errorWidget: (context, url, error) => const Center(
child: Icon( child: Icon(

View file

@ -29,7 +29,7 @@ class MessageAsset extends StatelessWidget {
height: 256, height: 256,
width: double.infinity, width: double.infinity,
child: CachedNetworkImage( child: CachedNetworkImage(
imageUrl: Aux.neosDbToHttp(content["thumbnailUri"]), imageUrl: Aux.resdbToHttp(content["thumbnailUri"]),
imageBuilder: (context, image) { imageBuilder: (context, image) {
return InkWell( return InkWell(
onTap: () async { onTap: () async {
@ -43,7 +43,7 @@ class MessageAsset extends StatelessWidget {
minScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained,
imageProvider: photoAsset == null imageProvider: photoAsset == null
? image ? image
: CachedNetworkImageProvider(Aux.neosDbToHttp(photoAsset.imageUri)), : CachedNetworkImageProvider(Aux.resdbToHttp(photoAsset.imageUri)),
heroAttributes: PhotoViewHeroAttributes(tag: message.id), heroAttributes: PhotoViewHeroAttributes(tag: message.id),
), ),
),); ),);

View file

@ -44,7 +44,7 @@ class MessageSessionInvite extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
GenericAvatar( GenericAvatar(
imageUri: Aux.neosDbToHttp(sessionInfo.thumbnail), imageUri: Aux.resdbToHttp(sessionInfo.thumbnail),
placeholderIcon: Icons.no_photography, placeholderIcon: Icons.no_photography,
foregroundColor: foregroundColor, foregroundColor: foregroundColor,
), ),

View file

@ -14,7 +14,7 @@ class SessionPopup extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ScrollController userListScrollController = ScrollController(); final ScrollController userListScrollController = ScrollController();
final thumbnailUri = Aux.neosDbToHttp(session.thumbnail); final thumbnailUri = Aux.resdbToHttp(session.thumbnail);
return Dialog( return Dialog(
insetPadding: const EdgeInsets.all(32), insetPadding: const EdgeInsets.all(32),
child: Container( child: Container(
@ -145,7 +145,7 @@ class SessionTile extends StatelessWidget {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
GenericAvatar(imageUri: Aux.neosDbToHttp(session.thumbnail), placeholderIcon: Icons.no_photography), GenericAvatar(imageUri: Aux.resdbToHttp(session.thumbnail), placeholderIcon: Icons.no_photography),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0), padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column( child: Column(

View file

@ -59,7 +59,7 @@ class _MyProfileDialogState extends State<MyProfileDialog> {
Text(profile.email, style: tt.labelMedium?.copyWith(color: Theme.of(context).colorScheme.onSurface.withAlpha(150)),) Text(profile.email, style: tt.labelMedium?.copyWith(color: Theme.of(context).colorScheme.onSurface.withAlpha(150)),)
], ],
), ),
GenericAvatar(imageUri: Aux.neosDbToHttp(profile.userProfile.iconUrl), radius: 24,) GenericAvatar(imageUri: Aux.resdbToHttp(profile.userProfile.iconUrl), radius: 24,)
], ],
), ),
const SizedBox(height: 16,), const SizedBox(height: 16,),

View file

@ -92,7 +92,7 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
child: Hero( child: Hero(
tag: session.id, tag: session.id,
child: CachedNetworkImage( child: CachedNetworkImage(
imageUrl: Aux.neosDbToHttp(session.thumbnail), imageUrl: Aux.resdbToHttp(session.thumbnail),
fit: BoxFit.cover, fit: BoxFit.cover,
errorWidget: (context, url, error) => const Center( errorWidget: (context, url, error) => const Center(
child: Icon( child: Icon(

View file

@ -61,7 +61,7 @@ class _SessionViewState extends State<SessionView> {
SizedBox( SizedBox(
height: 192, height: 192,
child: CachedNetworkImage( child: CachedNetworkImage(
imageUrl: Aux.neosDbToHttp(session.thumbnail), imageUrl: Aux.resdbToHttp(session.thumbnail),
imageBuilder: (context, image) { imageBuilder: (context, image) {
return Material( return Material(
child: InkWell( child: InkWell(

View file

@ -117,10 +117,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: collection name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.1" version: "1.17.2"
color: color:
dependency: "direct main" dependency: "direct main"
description: description:
@ -484,26 +484,26 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: logging name: logging
sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.2.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.15" version: "0.12.16"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.0" version: "0.5.0"
message_pack_dart: message_pack_dart:
dependency: transitive dependency: transitive
description: description:
@ -688,6 +688,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
pool:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
url: "https://pub.dev"
source: hosted
version: "1.5.1"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -768,14 +776,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.27.7" version: "0.27.7"
shelf:
dependency: transitive
description:
name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
url: "https://pub.dev"
source: hosted
version: "1.4.1"
signalr_netcore: signalr_netcore:
dependency: "direct main" dependency: "direct main"
description: description:
name: signalr_netcore name: signalr_netcore
sha256: bfc6e4cb95e3c2c1d9691e8c582a72e2b3fee4cd380abb060eaf65e3c5c43b29 sha256: "8f84b4b516c03f3a6872f94e9729d1441d5d223a77c81d0a7d7dae5dd0ce1f2f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.3.6"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -785,10 +801,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.10.0"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
@ -805,14 +821,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.5" version: "2.4.5"
sse_client: sse:
dependency: transitive dependency: transitive
description: description:
name: sse_client name: sse
sha256: "71bd826430b41ab20a69d85bf2dfe9f11cfe222938e681ada1aea71fc8adf348" sha256: "3ff9088cac3f45aa8b91336f1962e3ea6c81baaba0bbba361c05f8aa7fb59442"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.0" version: "4.1.2"
sse_channel:
dependency: transitive
description:
name: sse_channel
sha256: ba2b1382b9423c58fa83e1f01a3a40fbaa16a0594aa984870c88bad0b45d4ca4
url: "https://pub.dev"
source: hosted
version: "0.0.3"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -865,10 +889,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.6.0"
timezone: timezone:
dependency: transitive dependency: transitive
description: description:
@ -881,10 +905,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: tuple name: tuple
sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa" sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.0.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -973,6 +997,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
web_socket_channel: web_socket_channel:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1014,5 +1046,5 @@ packages:
source: hosted source: hosted
version: "6.3.0" version: "6.3.0"
sdks: sdks:
dart: ">=3.0.1 <4.0.0" dart: ">=3.1.0-185.0.dev <4.0.0"
flutter: ">=3.4.0-17.0.pre" flutter: ">=3.4.0-17.0.pre"

View file

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.5.1+1 version: 2.0.0+1
environment: environment:
sdk: '>=3.0.1' sdk: '>=3.0.1'
@ -38,7 +38,7 @@ dependencies:
flutter_secure_storage: ^8.0.0 flutter_secure_storage: ^8.0.0
intl: ^0.18.1 intl: ^0.18.1
path: ^1.8.2 path: ^1.8.2
signalr_netcore: ^1.3.3 signalr_netcore: ^1.3.6
logging: ^1.1.1 logging: ^1.1.1
cached_network_image: ^3.2.3 cached_network_image: ^3.2.3
web_socket_channel: ^2.4.0 web_socket_channel: ^2.4.0