Compare commits
5 Commits
e6c58b7b63
...
3.1.0+114
| Author | SHA1 | Date | |
|---|---|---|---|
| 25ae18d6a9 | |||
| 18db50d80c | |||
| 903008d397 | |||
| 4499d4ec8e | |||
| 3a4faac8cb |
@@ -698,5 +698,9 @@
|
|||||||
"postForwardingTo": "Forwarding to",
|
"postForwardingTo": "Forwarding to",
|
||||||
"postReplyingTo": "Replying to",
|
"postReplyingTo": "Replying to",
|
||||||
"postEditing": "You are editing an existing post",
|
"postEditing": "You are editing an existing post",
|
||||||
"postArticle": "Article"
|
"postArticle": "Article",
|
||||||
|
"aboutDeviceName": "Device Name",
|
||||||
|
"aboutDeviceIdentifier": "Device Identifier",
|
||||||
|
"donate": "Donate",
|
||||||
|
"donateDescription": "Support us to continue developing the Solar Network and keep the server up and running."
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ part 'config.g.dart';
|
|||||||
|
|
||||||
const kTokenPairStoreKey = 'dyn_user_tk';
|
const kTokenPairStoreKey = 'dyn_user_tk';
|
||||||
|
|
||||||
const kNetworkServerDefault = 'https://nt.solian.app';
|
const kNetworkServerDefault = 'https://api.solian.app';
|
||||||
const kNetworkServerStoreKey = 'app_server_url';
|
const kNetworkServerStoreKey = 'app_server_url';
|
||||||
|
|
||||||
const kAppbarTransparentStoreKey = 'app_bar_transparent';
|
const kAppbarTransparentStoreKey = 'app_bar_transparent';
|
||||||
@@ -82,7 +82,7 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
|
|||||||
Size? _getWindowSizeFromPrefs(SharedPreferences prefs) {
|
Size? _getWindowSizeFromPrefs(SharedPreferences prefs) {
|
||||||
final sizeString = prefs.getString(kAppWindowSize);
|
final sizeString = prefs.getString(kAppWindowSize);
|
||||||
if (sizeString == null) return null;
|
if (sizeString == null) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final parts = sizeString.split(',');
|
final parts = sizeString.split(',');
|
||||||
if (parts.length == 2) {
|
if (parts.length == 2) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class WebFeedNotifier
|
|||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/publishers/${arg.pubName}/feeds/${arg.feedId}',
|
'/sphere/publishers/${arg.pubName}/feeds/${arg.feedId}',
|
||||||
);
|
);
|
||||||
return SnWebFeed.fromJson(response.data);
|
return SnWebFeed.fromJson(response.data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -51,7 +51,7 @@ class WebFeedNotifier
|
|||||||
state = const AsyncValue.loading();
|
state = const AsyncValue.loading();
|
||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final url = '/publishers/${feed.publisherId}/feeds';
|
final url = '/sphere/publishers/${feed.publisherId}/feeds';
|
||||||
|
|
||||||
final response =
|
final response =
|
||||||
feed.id.isEmpty
|
feed.id.isEmpty
|
||||||
@@ -98,7 +98,7 @@ class WebFeedNotifier
|
|||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.post(
|
await client.post(
|
||||||
'/publishers/${arg.pubName}/feeds/$feedId/scrap',
|
'/sphere/publishers/${arg.pubName}/feeds/$feedId/scrap',
|
||||||
options: Options(
|
options: Options(
|
||||||
sendTimeout: const Duration(seconds: 60),
|
sendTimeout: const Duration(seconds: 60),
|
||||||
receiveTimeout: const Duration(seconds: 180),
|
receiveTimeout: const Duration(seconds: 180),
|
||||||
@@ -107,7 +107,7 @@ class WebFeedNotifier
|
|||||||
|
|
||||||
// Reload the feed
|
// Reload the feed
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/publishers/${arg.pubName}/feeds/$feedId',
|
'/sphere/publishers/${arg.pubName}/feeds/$feedId',
|
||||||
);
|
);
|
||||||
state = AsyncValue.data(SnWebFeed.fromJson(response.data));
|
state = AsyncValue.data(SnWebFeed.fromJson(response.data));
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ sealed class WebSocketPacket with _$WebSocketPacket {
|
|||||||
const factory WebSocketPacket({
|
const factory WebSocketPacket({
|
||||||
required String type,
|
required String type,
|
||||||
required Map<String, dynamic>? data,
|
required Map<String, dynamic>? data,
|
||||||
|
String? endpoint,
|
||||||
String? errorMessage,
|
String? errorMessage,
|
||||||
}) = _WebSocketPacket;
|
}) = _WebSocketPacket;
|
||||||
|
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ as String,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$WebSocketPacket implements DiagnosticableTreeMixin {
|
mixin _$WebSocketPacket implements DiagnosticableTreeMixin {
|
||||||
|
|
||||||
String get type; Map<String, dynamic>? get data; String? get errorMessage;
|
String get type; Map<String, dynamic>? get data; String? get endpoint; String? get errorMessage;
|
||||||
/// Create a copy of WebSocketPacket
|
/// Create a copy of WebSocketPacket
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -393,21 +393,21 @@ $WebSocketPacketCopyWith<WebSocketPacket> get copyWith => _$WebSocketPacketCopyW
|
|||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
properties
|
properties
|
||||||
..add(DiagnosticsProperty('type', 'WebSocketPacket'))
|
..add(DiagnosticsProperty('type', 'WebSocketPacket'))
|
||||||
..add(DiagnosticsProperty('type', type))..add(DiagnosticsProperty('data', data))..add(DiagnosticsProperty('errorMessage', errorMessage));
|
..add(DiagnosticsProperty('type', type))..add(DiagnosticsProperty('data', data))..add(DiagnosticsProperty('endpoint', endpoint))..add(DiagnosticsProperty('errorMessage', errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WebSocketPacket&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is WebSocketPacket&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.endpoint, endpoint) || other.endpoint == endpoint)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(data),errorMessage);
|
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(data),endpoint,errorMessage);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
return 'WebSocketPacket(type: $type, data: $data, errorMessage: $errorMessage)';
|
return 'WebSocketPacket(type: $type, data: $data, endpoint: $endpoint, errorMessage: $errorMessage)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -418,7 +418,7 @@ abstract mixin class $WebSocketPacketCopyWith<$Res> {
|
|||||||
factory $WebSocketPacketCopyWith(WebSocketPacket value, $Res Function(WebSocketPacket) _then) = _$WebSocketPacketCopyWithImpl;
|
factory $WebSocketPacketCopyWith(WebSocketPacket value, $Res Function(WebSocketPacket) _then) = _$WebSocketPacketCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String type, Map<String, dynamic>? data, String? errorMessage
|
String type, Map<String, dynamic>? data, String? endpoint, String? errorMessage
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -435,11 +435,12 @@ class _$WebSocketPacketCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of WebSocketPacket
|
/// Create a copy of WebSocketPacket
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? data = freezed,Object? errorMessage = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? data = freezed,Object? endpoint = freezed,Object? errorMessage = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as String,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
as String,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>?,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>?,endpoint: freezed == endpoint ? _self.endpoint : endpoint // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -522,10 +523,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String type, Map<String, dynamic>? data, String? errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String type, Map<String, dynamic>? data, String? endpoint, String? errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _WebSocketPacket() when $default != null:
|
case _WebSocketPacket() when $default != null:
|
||||||
return $default(_that.type,_that.data,_that.errorMessage);case _:
|
return $default(_that.type,_that.data,_that.endpoint,_that.errorMessage);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -543,10 +544,10 @@ return $default(_that.type,_that.data,_that.errorMessage);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String type, Map<String, dynamic>? data, String? errorMessage) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String type, Map<String, dynamic>? data, String? endpoint, String? errorMessage) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _WebSocketPacket():
|
case _WebSocketPacket():
|
||||||
return $default(_that.type,_that.data,_that.errorMessage);}
|
return $default(_that.type,_that.data,_that.endpoint,_that.errorMessage);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -560,10 +561,10 @@ return $default(_that.type,_that.data,_that.errorMessage);}
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String type, Map<String, dynamic>? data, String? errorMessage)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String type, Map<String, dynamic>? data, String? endpoint, String? errorMessage)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _WebSocketPacket() when $default != null:
|
case _WebSocketPacket() when $default != null:
|
||||||
return $default(_that.type,_that.data,_that.errorMessage);case _:
|
return $default(_that.type,_that.data,_that.endpoint,_that.errorMessage);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -575,7 +576,7 @@ return $default(_that.type,_that.data,_that.errorMessage);case _:
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _WebSocketPacket with DiagnosticableTreeMixin implements WebSocketPacket {
|
class _WebSocketPacket with DiagnosticableTreeMixin implements WebSocketPacket {
|
||||||
const _WebSocketPacket({required this.type, required final Map<String, dynamic>? data, this.errorMessage}): _data = data;
|
const _WebSocketPacket({required this.type, required final Map<String, dynamic>? data, this.endpoint, this.errorMessage}): _data = data;
|
||||||
factory _WebSocketPacket.fromJson(Map<String, dynamic> json) => _$WebSocketPacketFromJson(json);
|
factory _WebSocketPacket.fromJson(Map<String, dynamic> json) => _$WebSocketPacketFromJson(json);
|
||||||
|
|
||||||
@override final String type;
|
@override final String type;
|
||||||
@@ -588,6 +589,7 @@ class _WebSocketPacket with DiagnosticableTreeMixin implements WebSocketPacket {
|
|||||||
return EqualUnmodifiableMapView(value);
|
return EqualUnmodifiableMapView(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override final String? endpoint;
|
||||||
@override final String? errorMessage;
|
@override final String? errorMessage;
|
||||||
|
|
||||||
/// Create a copy of WebSocketPacket
|
/// Create a copy of WebSocketPacket
|
||||||
@@ -604,21 +606,21 @@ Map<String, dynamic> toJson() {
|
|||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
properties
|
properties
|
||||||
..add(DiagnosticsProperty('type', 'WebSocketPacket'))
|
..add(DiagnosticsProperty('type', 'WebSocketPacket'))
|
||||||
..add(DiagnosticsProperty('type', type))..add(DiagnosticsProperty('data', data))..add(DiagnosticsProperty('errorMessage', errorMessage));
|
..add(DiagnosticsProperty('type', type))..add(DiagnosticsProperty('data', data))..add(DiagnosticsProperty('endpoint', endpoint))..add(DiagnosticsProperty('errorMessage', errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WebSocketPacket&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._data, _data)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WebSocketPacket&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._data, _data)&&(identical(other.endpoint, endpoint) || other.endpoint == endpoint)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(_data),errorMessage);
|
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(_data),endpoint,errorMessage);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
return 'WebSocketPacket(type: $type, data: $data, errorMessage: $errorMessage)';
|
return 'WebSocketPacket(type: $type, data: $data, endpoint: $endpoint, errorMessage: $errorMessage)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -629,7 +631,7 @@ abstract mixin class _$WebSocketPacketCopyWith<$Res> implements $WebSocketPacket
|
|||||||
factory _$WebSocketPacketCopyWith(_WebSocketPacket value, $Res Function(_WebSocketPacket) _then) = __$WebSocketPacketCopyWithImpl;
|
factory _$WebSocketPacketCopyWith(_WebSocketPacket value, $Res Function(_WebSocketPacket) _then) = __$WebSocketPacketCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String type, Map<String, dynamic>? data, String? errorMessage
|
String type, Map<String, dynamic>? data, String? endpoint, String? errorMessage
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -646,11 +648,12 @@ class __$WebSocketPacketCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of WebSocketPacket
|
/// Create a copy of WebSocketPacket
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? data = freezed,Object? errorMessage = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? data = freezed,Object? endpoint = freezed,Object? errorMessage = freezed,}) {
|
||||||
return _then(_WebSocketPacket(
|
return _then(_WebSocketPacket(
|
||||||
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as String,data: freezed == data ? _self._data : data // ignore: cast_nullable_to_non_nullable
|
as String,data: freezed == data ? _self._data : data // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>?,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>?,endpoint: freezed == endpoint ? _self.endpoint : endpoint // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ _WebSocketPacket _$WebSocketPacketFromJson(Map<String, dynamic> json) =>
|
|||||||
_WebSocketPacket(
|
_WebSocketPacket(
|
||||||
type: json['type'] as String,
|
type: json['type'] as String,
|
||||||
data: json['data'] as Map<String, dynamic>?,
|
data: json['data'] as Map<String, dynamic>?,
|
||||||
|
endpoint: json['endpoint'] as String?,
|
||||||
errorMessage: json['error_message'] as String?,
|
errorMessage: json['error_message'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -17,5 +18,6 @@ Map<String, dynamic> _$WebSocketPacketToJson(_WebSocketPacket instance) =>
|
|||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'type': instance.type,
|
'type': instance.type,
|
||||||
'data': instance.data,
|
'data': instance.data,
|
||||||
|
'endpoint': instance.endpoint,
|
||||||
'error_message': instance.errorMessage,
|
'error_message': instance.errorMessage,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/pods/network.dart';
|
|
||||||
import 'package:island/services/notify.dart';
|
|
||||||
import 'package:island/services/udid.native.dart';
|
import 'package:island/services/udid.native.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
class AboutScreen extends ConsumerStatefulWidget {
|
class AboutScreen extends ConsumerStatefulWidget {
|
||||||
const AboutScreen({super.key});
|
const AboutScreen({super.key});
|
||||||
@@ -168,34 +169,16 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
|
|||||||
_buildInfoItem(
|
_buildInfoItem(
|
||||||
context,
|
context,
|
||||||
icon: Symbols.label,
|
icon: Symbols.label,
|
||||||
label: 'Device Name',
|
label: 'aboutDeviceName'.tr(),
|
||||||
value: _deviceInfo?.data['name'],
|
value: _deviceInfo?.data['name'],
|
||||||
),
|
),
|
||||||
_buildInfoItem(
|
_buildInfoItem(
|
||||||
context,
|
context,
|
||||||
icon: Symbols.fingerprint,
|
icon: Symbols.fingerprint,
|
||||||
label: 'Device Identifier',
|
label: 'aboutDeviceIdentifier'.tr(),
|
||||||
value: _deviceUdid ?? 'N/A',
|
value: _deviceUdid ?? 'N/A',
|
||||||
copyable: true,
|
copyable: true,
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
|
||||||
_buildListTile(
|
|
||||||
context,
|
|
||||||
icon: Symbols.notifications_active,
|
|
||||||
title: 'Reactivate Push Notifications',
|
|
||||||
onTap: () async {
|
|
||||||
showLoadingModal(context);
|
|
||||||
try {
|
|
||||||
await subscribePushNotification(
|
|
||||||
ref.watch(apiClientProvider),
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
showErrorAlert(err);
|
|
||||||
} finally {
|
|
||||||
if (context.mounted) hideLoadingModal(context);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -266,6 +249,18 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
|
|||||||
'https://github.com/Solsynth/Solian/blob/v3/LICENSE.txt',
|
'https://github.com/Solsynth/Solian/blob/v3/LICENSE.txt',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (kIsWeb || !(Platform.isMacOS || Platform.isIOS))
|
||||||
|
_buildListTile(
|
||||||
|
context,
|
||||||
|
icon: Symbols.favorite,
|
||||||
|
title: 'donate'.tr(),
|
||||||
|
subtitle: 'donateDescription'.tr(),
|
||||||
|
onTap: () {
|
||||||
|
launchUrlString(
|
||||||
|
'https://afdian.com/@littlesheep',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class AuthFactorSheet extends HookConsumerWidget {
|
|||||||
showLoadingModal(context);
|
showLoadingModal(context);
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.post(
|
await client.post(
|
||||||
'/accounts/me/factors/${factor.id}/enable',
|
'/id/accounts/me/factors/${factor.id}/enable',
|
||||||
data: jsonEncode(password),
|
data: jsonEncode(password),
|
||||||
);
|
);
|
||||||
if (context.mounted) Navigator.pop(context, true);
|
if (context.mounted) Navigator.pop(context, true);
|
||||||
@@ -193,7 +193,7 @@ class AuthFactorNewSheet extends HookConsumerWidget {
|
|||||||
showLoadingModal(context);
|
showLoadingModal(context);
|
||||||
final apiClient = ref.read(apiClientProvider);
|
final apiClient = ref.read(apiClientProvider);
|
||||||
final resp = await apiClient.post(
|
final resp = await apiClient.post(
|
||||||
'/accounts/me/factors',
|
'/id/accounts/me/factors',
|
||||||
data: {'type': factorType.value, 'secret': secretController.text},
|
data: {'type': factorType.value, 'secret': secretController.text},
|
||||||
);
|
);
|
||||||
final factor = SnAuthFactor.fromJson(resp.data);
|
final factor = SnAuthFactor.fromJson(resp.data);
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ class AccountConnectionNewSheet extends HookConsumerWidget {
|
|||||||
if (context.mounted) showLoadingModal(context);
|
if (context.mounted) showLoadingModal(context);
|
||||||
|
|
||||||
await client.post(
|
await client.post(
|
||||||
'/auth/connect/apple/mobile',
|
'/id/auth/connect/apple/mobile',
|
||||||
data: {
|
data: {
|
||||||
'identity_token': credential.identityToken!,
|
'identity_token': credential.identityToken!,
|
||||||
'authorization_code': credential.authorizationCode,
|
'authorization_code': credential.authorizationCode,
|
||||||
@@ -336,7 +336,7 @@ class AccountConnectionsSheet extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.delete(
|
await client.delete(
|
||||||
'/accounts/me/connections/${connection.id}',
|
'/id/accounts/me/connections/${connection.id}',
|
||||||
);
|
);
|
||||||
ref.invalidate(accountConnectionsProvider);
|
ref.invalidate(accountConnectionsProvider);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ class ContactMethodNewSheet extends HookConsumerWidget {
|
|||||||
showLoadingModal(context);
|
showLoadingModal(context);
|
||||||
final apiClient = ref.read(apiClientProvider);
|
final apiClient = ref.read(apiClientProvider);
|
||||||
await apiClient.post(
|
await apiClient.post(
|
||||||
'/accounts/me/contacts',
|
'/id/accounts/me/contacts',
|
||||||
data: {'type': contactType.value, 'content': contentController.text},
|
data: {'type': contactType.value, 'content': contentController.text},
|
||||||
);
|
);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
await client.patch(
|
await client.patch(
|
||||||
'/accounts/me/profile',
|
'/id/accounts/me/profile',
|
||||||
data: {'${position}_id': cloudFile.id},
|
data: {'${position}_id': cloudFile.id},
|
||||||
);
|
);
|
||||||
final userNotifier = ref.read(userInfoProvider.notifier);
|
final userNotifier = ref.read(userInfoProvider.notifier);
|
||||||
@@ -102,7 +102,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
await client.patch(
|
await client.patch(
|
||||||
'/accounts/me',
|
'/id/accounts/me',
|
||||||
data: {
|
data: {
|
||||||
'name': usernameController.text,
|
'name': usernameController.text,
|
||||||
'nick': nicknameController.text,
|
'nick': nicknameController.text,
|
||||||
@@ -154,7 +154,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
await client.patch(
|
await client.patch(
|
||||||
'/accounts/me/profile',
|
'/id/accounts/me/profile',
|
||||||
data: {
|
data: {
|
||||||
'bio': bioController.text,
|
'bio': bioController.text,
|
||||||
'first_name': firstNameController.text,
|
'first_name': firstNameController.text,
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ Future<SnAccount> account(Ref ref, String uname) async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get("/accounts/$uname");
|
final resp = await apiClient.get("/id/accounts/$uname");
|
||||||
return SnAccount.fromJson(resp.data);
|
return SnAccount.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<List<SnAccountBadge>> accountBadges(Ref ref, String uname) async {
|
Future<List<SnAccountBadge>> accountBadges(Ref ref, String uname) async {
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get("/accounts/$uname/badges");
|
final resp = await apiClient.get("/id/accounts/$uname/badges");
|
||||||
return List<SnAccountBadge>.from(
|
return List<SnAccountBadge>.from(
|
||||||
resp.data.map((x) => SnAccountBadge.fromJson(x)),
|
resp.data.map((x) => SnAccountBadge.fromJson(x)),
|
||||||
);
|
);
|
||||||
@@ -78,7 +78,7 @@ Future<SnChatRoom?> accountDirectChat(Ref ref, String uname) async {
|
|||||||
final account = await ref.watch(accountProvider(uname).future);
|
final account = await ref.watch(accountProvider(uname).future);
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
try {
|
try {
|
||||||
final resp = await apiClient.get("/chat/direct/${account.id}");
|
final resp = await apiClient.get("/sphere/chat/direct/${account.id}");
|
||||||
return SnChatRoom.fromJson(resp.data);
|
return SnChatRoom.fromJson(resp.data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err is DioException && err.response?.statusCode == 404) {
|
if (err is DioException && err.response?.statusCode == 404) {
|
||||||
@@ -95,7 +95,7 @@ Future<SnRelationship?> accountRelationship(Ref ref, String uname) async {
|
|||||||
final account = await ref.watch(accountProvider(uname).future);
|
final account = await ref.watch(accountProvider(uname).future);
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
try {
|
try {
|
||||||
final resp = await apiClient.get("/relationships/${account.id}");
|
final resp = await apiClient.get("/id/relationships/${account.id}");
|
||||||
return SnRelationship.fromJson(resp.data);
|
return SnRelationship.fromJson(resp.data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err is DioException && err.response?.statusCode == 404) {
|
if (err is DioException && err.response?.statusCode == 404) {
|
||||||
@@ -174,7 +174,7 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final resp = await client.post(
|
final resp = await client.post(
|
||||||
'/chat/direct',
|
'/sphere/chat/direct',
|
||||||
data: {'related_user_id': account.value!.id},
|
data: {'related_user_id': account.value!.id},
|
||||||
);
|
);
|
||||||
final chat = SnChatRoom.fromJson(resp.data);
|
final chat = SnChatRoom.fromJson(resp.data);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'profile.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$accountHash() => r'd2b0579617e6264452d98f47f695a9cdf45b24ec';
|
String _$accountHash() => r'ce7264a04f69e32a5cb07bc10ca5fa47ae1fddaa';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
@@ -145,7 +145,7 @@ class _AccountProviderElement
|
|||||||
String get uname => (origin as AccountProvider).uname;
|
String get uname => (origin as AccountProvider).uname;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$accountBadgesHash() => r'4bfe5fb0d6ac0d4cde4563460bde289289188f6d';
|
String _$accountBadgesHash() => r'1de05e122c23ff2c6ac6d318977165761e2ad177';
|
||||||
|
|
||||||
/// See also [accountBadges].
|
/// See also [accountBadges].
|
||||||
@ProviderFor(accountBadges)
|
@ProviderFor(accountBadges)
|
||||||
@@ -395,7 +395,7 @@ class _AccountAppbarForcegroundColorProviderElement
|
|||||||
String get uname => (origin as AccountAppbarForcegroundColorProvider).uname;
|
String get uname => (origin as AccountAppbarForcegroundColorProvider).uname;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$accountDirectChatHash() => r'3d28c8ba8079159f724fe3cd47bbe00db55cedcc';
|
String _$accountDirectChatHash() => r'149ea3a3730672cfbbb8c16fe1f2caa0bb9f0e17';
|
||||||
|
|
||||||
/// See also [accountDirectChat].
|
/// See also [accountDirectChat].
|
||||||
@ProviderFor(accountDirectChat)
|
@ProviderFor(accountDirectChat)
|
||||||
@@ -517,7 +517,7 @@ class _AccountDirectChatProviderElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$accountRelationshipHash() =>
|
String _$accountRelationshipHash() =>
|
||||||
r'0be2420e1f6a65b8dcead9617191471924aaf232';
|
r'9a3a4e8c6c6706f73df95feccb86736fcad33f30';
|
||||||
|
|
||||||
/// See also [accountRelationship].
|
/// See also [accountRelationship].
|
||||||
@ProviderFor(accountRelationship)
|
@ProviderFor(accountRelationship)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class RelationshipListNotifier extends _$RelationshipListNotifier
|
|||||||
final take = 20;
|
final take = 20;
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/relationships',
|
'/id/relationships',
|
||||||
queryParameters: {'offset': offset, 'take': take},
|
queryParameters: {'offset': offset, 'take': take},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ class RelationshipScreen extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.post(
|
await client.post(
|
||||||
'/relationships/${relationship.accountId}/friends/${isAccept ? 'accept' : 'decline'}',
|
'/id/relationships/${relationship.accountId}/friends/${isAccept ? 'accept' : 'decline'}',
|
||||||
);
|
);
|
||||||
relationshipNotifier.forceRefresh();
|
relationshipNotifier.forceRefresh();
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
@@ -262,7 +262,7 @@ class RelationshipScreen extends HookConsumerWidget {
|
|||||||
) async {
|
) async {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.patch(
|
await client.patch(
|
||||||
'/relationships/${relationship.accountId}',
|
'/id/relationships/${relationship.accountId}',
|
||||||
data: {'status': newStatus},
|
data: {'status': newStatus},
|
||||||
);
|
);
|
||||||
relationshipNotifier.forceRefresh();
|
relationshipNotifier.forceRefresh();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ final sentFriendRequestProvider =
|
|||||||
typedef SentFriendRequestRef =
|
typedef SentFriendRequestRef =
|
||||||
AutoDisposeFutureProviderRef<List<SnRelationship>>;
|
AutoDisposeFutureProviderRef<List<SnRelationship>>;
|
||||||
String _$relationshipListNotifierHash() =>
|
String _$relationshipListNotifierHash() =>
|
||||||
r'560410cba6e4c26affd91aa86b3666319bd31f24';
|
r'0a134ce69489a4f2002d2223853855b6f22e4e9f';
|
||||||
|
|
||||||
/// See also [RelationshipListNotifier].
|
/// See also [RelationshipListNotifier].
|
||||||
@ProviderFor(RelationshipListNotifier)
|
@ProviderFor(RelationshipListNotifier)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'captcha.config.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$captchaUrlHash() => r'627caa2f2eb020a28a4b138122fe8e99915185f9';
|
String _$captchaUrlHash() => r'bbed0d18272dd205069642b3c6583ea2eef735d1';
|
||||||
|
|
||||||
/// See also [captchaUrl].
|
/// See also [captchaUrl].
|
||||||
@ProviderFor(captchaUrl)
|
@ProviderFor(captchaUrl)
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
|
useRootNavigator: true,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => const _ChatInvitesSheet(),
|
builder: (context) => const _ChatInvitesSheet(),
|
||||||
@@ -608,127 +609,129 @@ class EditChatScreen extends HookConsumerWidget {
|
|||||||
title: Text(id == null ? 'createChatRoom' : 'editChatRoom').tr(),
|
title: Text(id == null ? 'createChatRoom' : 'editChatRoom').tr(),
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: SingleChildScrollView(
|
||||||
children: [
|
child: Column(
|
||||||
RealmSelectionDropdown(
|
children: [
|
||||||
value: currentRealm.value,
|
RealmSelectionDropdown(
|
||||||
realms: joinedRealms.when(
|
value: currentRealm.value,
|
||||||
data: (realms) => realms,
|
realms: joinedRealms.when(
|
||||||
loading: () => [],
|
data: (realms) => realms,
|
||||||
error: (_, _) => [],
|
loading: () => [],
|
||||||
|
error: (_, _) => [],
|
||||||
|
),
|
||||||
|
onChanged: (SnRealm? value) {
|
||||||
|
currentRealm.value = value;
|
||||||
|
},
|
||||||
|
isLoading: joinedRealms.isLoading,
|
||||||
|
error: joinedRealms.error?.toString(),
|
||||||
),
|
),
|
||||||
onChanged: (SnRealm? value) {
|
AspectRatio(
|
||||||
currentRealm.value = value;
|
aspectRatio: 16 / 7,
|
||||||
},
|
child: Stack(
|
||||||
isLoading: joinedRealms.isLoading,
|
clipBehavior: Clip.none,
|
||||||
error: joinedRealms.error?.toString(),
|
fit: StackFit.expand,
|
||||||
),
|
children: [
|
||||||
AspectRatio(
|
GestureDetector(
|
||||||
aspectRatio: 16 / 7,
|
child: Container(
|
||||||
child: Stack(
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
clipBehavior: Clip.none,
|
child:
|
||||||
fit: StackFit.expand,
|
background.value != null
|
||||||
children: [
|
? CloudFileWidget(
|
||||||
GestureDetector(
|
item: background.value!,
|
||||||
child: Container(
|
fit: BoxFit.cover,
|
||||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
)
|
||||||
child:
|
: const SizedBox.shrink(),
|
||||||
background.value != null
|
|
||||||
? CloudFileWidget(
|
|
||||||
item: background.value!,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
setPicture('background');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
left: 20,
|
|
||||||
bottom: -32,
|
|
||||||
child: GestureDetector(
|
|
||||||
child: ProfilePictureWidget(
|
|
||||||
fileId: picture.value?.id,
|
|
||||||
radius: 40,
|
|
||||||
fallbackIcon: Symbols.group,
|
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setPicture('picture');
|
setPicture('background');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
Positioned(
|
||||||
],
|
left: 20,
|
||||||
|
bottom: -32,
|
||||||
|
child: GestureDetector(
|
||||||
|
child: ProfilePictureWidget(
|
||||||
|
fileId: picture.value?.id,
|
||||||
|
radius: 40,
|
||||||
|
fallbackIcon: Symbols.group,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setPicture('picture');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).padding(bottom: 32),
|
||||||
|
Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
controller: nameController,
|
||||||
|
decoration: const InputDecoration(labelText: 'Name'),
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: descriptionController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Description',
|
||||||
|
alignLabelWithHint: true,
|
||||||
|
),
|
||||||
|
minLines: 3,
|
||||||
|
maxLines: null,
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Card(
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
CheckboxListTile(
|
||||||
|
secondary: const Icon(Symbols.public),
|
||||||
|
title: Text('publicChat').tr(),
|
||||||
|
subtitle: Text('publicChatDescription').tr(),
|
||||||
|
value: isPublic.value,
|
||||||
|
onChanged: (value) {
|
||||||
|
isPublic.value = value ?? true;
|
||||||
|
},
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CheckboxListTile(
|
||||||
|
secondary: const Icon(Symbols.travel_explore),
|
||||||
|
title: Text('communityChat').tr(),
|
||||||
|
subtitle: Text('communityChatDescription').tr(),
|
||||||
|
value: isCommunity.value,
|
||||||
|
onChanged: (value) {
|
||||||
|
isCommunity.value = value ?? false;
|
||||||
|
},
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: TextButton.icon(
|
||||||
|
onPressed: submitting.value ? null : performAction,
|
||||||
|
label: const Text('Save'),
|
||||||
|
icon: const Icon(Symbols.save),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(all: 24),
|
||||||
),
|
),
|
||||||
).padding(bottom: 32),
|
],
|
||||||
Form(
|
),
|
||||||
key: formKey,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
TextFormField(
|
|
||||||
controller: nameController,
|
|
||||||
decoration: const InputDecoration(labelText: 'Name'),
|
|
||||||
onTapOutside:
|
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
TextFormField(
|
|
||||||
controller: descriptionController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Description',
|
|
||||||
alignLabelWithHint: true,
|
|
||||||
),
|
|
||||||
minLines: 3,
|
|
||||||
maxLines: null,
|
|
||||||
onTapOutside:
|
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Card(
|
|
||||||
margin: EdgeInsets.zero,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
CheckboxListTile(
|
|
||||||
secondary: const Icon(Symbols.public),
|
|
||||||
title: Text('publicChat').tr(),
|
|
||||||
subtitle: Text('publicChatDescription').tr(),
|
|
||||||
value: isPublic.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
isPublic.value = value ?? true;
|
|
||||||
},
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CheckboxListTile(
|
|
||||||
secondary: const Icon(Symbols.travel_explore),
|
|
||||||
title: Text('communityChat').tr(),
|
|
||||||
subtitle: Text('communityChatDescription').tr(),
|
|
||||||
value: isCommunity.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
isCommunity.value = value ?? false;
|
|
||||||
},
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: TextButton.icon(
|
|
||||||
onPressed: submitting.value ? null : performAction,
|
|
||||||
label: const Text('Save'),
|
|
||||||
icon: const Icon(Symbols.save),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
).padding(all: 24),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -376,7 +376,11 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
final wsState = ref.read(websocketStateProvider.notifier);
|
||||||
wsState.sendMessage(
|
wsState.sendMessage(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(type: 'messages.read', data: {'chat_room_id': id}),
|
WebSocketPacket(
|
||||||
|
type: 'messages.read',
|
||||||
|
data: {'chat_room_id': id},
|
||||||
|
endpoint: 'DysonNetwork.Sphere',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -393,7 +397,11 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
final wsState = ref.read(websocketStateProvider.notifier);
|
||||||
wsState.sendMessage(
|
wsState.sendMessage(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(type: 'messages.typing', data: {'chat_room_id': id}),
|
WebSocketPacket(
|
||||||
|
type: 'messages.typing',
|
||||||
|
data: {'chat_room_id': id},
|
||||||
|
endpoint: 'DysonNetwork.Sphere',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -389,7 +389,10 @@ class _ChatRoomActionMenu extends HookConsumerWidget {
|
|||||||
if ((chatIdentity.value?.role ?? 0) >= 50)
|
if ((chatIdentity.value?.role ?? 0) >= 50)
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushReplacement('/sphere/chat/$id/edit');
|
context.pushReplacementNamed(
|
||||||
|
'chatEdit',
|
||||||
|
pathParameters: {'id': id},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -502,7 +505,7 @@ class ChatMemberNotifier extends StateNotifier<ChatRoomMemberState> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await _apiClient.get(
|
final response = await _apiClient.get(
|
||||||
'/chat/$roomId/members',
|
'/sphere/chat/$roomId/members',
|
||||||
queryParameters: {'offset': offset, 'take': take},
|
queryParameters: {'offset': offset, 'take': take},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -540,7 +543,7 @@ class ChatMemberListNotifier extends _$ChatMemberListNotifier
|
|||||||
|
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final response = await apiClient.get(
|
final response = await apiClient.get(
|
||||||
'/chat/$roomId/members',
|
'/sphere/chat/$roomId/members',
|
||||||
queryParameters: {'offset': offset, 'take': take},
|
queryParameters: {'offset': offset, 'take': take},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -592,7 +595,7 @@ class _ChatMemberListSheet extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
await apiClient.post(
|
await apiClient.post(
|
||||||
'/chat/invites/$roomId',
|
'/sphere/chat/invites/$roomId',
|
||||||
data: {'related_user_id': result.id, 'role': 0},
|
data: {'related_user_id': result.id, 'role': 0},
|
||||||
);
|
);
|
||||||
// Refresh both providers
|
// Refresh both providers
|
||||||
@@ -846,7 +849,7 @@ class _ChatMemberRoleSheet extends HookConsumerWidget {
|
|||||||
|
|
||||||
final apiClient = ref.read(apiClientProvider);
|
final apiClient = ref.read(apiClientProvider);
|
||||||
await apiClient.patch(
|
await apiClient.patch(
|
||||||
'/chat/$roomId/members/${member.accountId}/role',
|
'/sphere/chat/$roomId/members/${member.accountId}/role',
|
||||||
data: newRole,
|
data: newRole,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class PublisherMemberListNotifier extends _$PublisherMemberListNotifier
|
|||||||
final offset = cursor != null ? int.parse(cursor) : 0;
|
final offset = cursor != null ? int.parse(cursor) : 0;
|
||||||
|
|
||||||
final response = await apiClient.get(
|
final response = await apiClient.get(
|
||||||
'/publishers/$uname/members',
|
'/sphere/publishers/$uname/members',
|
||||||
queryParameters: {'offset': offset, 'take': _pageSize},
|
queryParameters: {'offset': offset, 'take': _pageSize},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -143,14 +143,19 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
void updatePublisher() {
|
void updatePublisher() {
|
||||||
context.pushNamed('creatorEdit', pathParameters: {'name': currentPublisher.value!.name}).then((
|
context
|
||||||
value,
|
.pushNamed(
|
||||||
) async {
|
'creatorEdit',
|
||||||
if (value == null) return;
|
pathParameters: {'name': currentPublisher.value!.name},
|
||||||
final data = await ref.refresh(publishersManagedProvider.future);
|
)
|
||||||
currentPublisher.value =
|
.then((value) async {
|
||||||
data.where((e) => e.id == currentPublisher.value!.id).firstOrNull;
|
if (value == null) return;
|
||||||
});
|
final data = await ref.refresh(publishersManagedProvider.future);
|
||||||
|
currentPublisher.value =
|
||||||
|
data
|
||||||
|
.where((e) => e.id == currentPublisher.value!.id)
|
||||||
|
.firstOrNull;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void deletePublisher() {
|
void deletePublisher() {
|
||||||
@@ -350,7 +355,12 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
horizontal: 24,
|
horizontal: 24,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('creatorStickers', pathParameters: {'name': currentPublisher.value!.name});
|
context.pushNamed(
|
||||||
|
'creatorStickers',
|
||||||
|
pathParameters: {
|
||||||
|
'name': currentPublisher.value!.name,
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -362,7 +372,12 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
horizontal: 24,
|
horizontal: 24,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('creatorPosts', pathParameters: {'name': currentPublisher.value!.name});
|
context.pushNamed(
|
||||||
|
'creatorPosts',
|
||||||
|
pathParameters: {
|
||||||
|
'name': currentPublisher.value!.name,
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ final publisherInvitesProvider =
|
|||||||
typedef PublisherInvitesRef =
|
typedef PublisherInvitesRef =
|
||||||
AutoDisposeFutureProviderRef<List<SnPublisherMember>>;
|
AutoDisposeFutureProviderRef<List<SnPublisherMember>>;
|
||||||
String _$publisherMemberListNotifierHash() =>
|
String _$publisherMemberListNotifierHash() =>
|
||||||
r'237e8f39c9757a6cbdff817853c697539242ad2a';
|
r'b4afd5d591a6f3d29f1b45fb1b6d17cb34f3f11b';
|
||||||
|
|
||||||
abstract class _$PublisherMemberListNotifier
|
abstract class _$PublisherMemberListNotifier
|
||||||
extends
|
extends
|
||||||
|
|||||||
@@ -160,11 +160,11 @@ class EditPublisherScreen extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final resp = await client.request(
|
final resp = await client.request(
|
||||||
name == null
|
'/sphere${name == null
|
||||||
? currentRealm.value == null
|
? currentRealm.value == null
|
||||||
? '/publishers/individual'
|
? '/publishers/individual'
|
||||||
: '/publishers/organization/${currentRealm.value!.slug}'
|
: '/publishers/organization/${currentRealm.value!.slug}'
|
||||||
: '/publishers/$name',
|
: '/publishers/$name'}',
|
||||||
data: {
|
data: {
|
||||||
'name': nameController.text,
|
'name': nameController.text,
|
||||||
'nick': nickController.text,
|
'nick': nickController.text,
|
||||||
|
|||||||
@@ -28,13 +28,16 @@ class StickersScreen extends HookConsumerWidget {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.pushNamed('creatorStickerPackNew', queryParameters: {'pubName': pubName}).then((
|
context
|
||||||
value,
|
.pushNamed(
|
||||||
) {
|
'creatorStickerPackNew',
|
||||||
if (value != null) {
|
queryParameters: {'pubName': pubName},
|
||||||
ref.invalidate(stickerPacksNotifierProvider(pubName));
|
)
|
||||||
}
|
.then((value) {
|
||||||
});
|
if (value != null) {
|
||||||
|
ref.invalidate(stickerPacksNotifierProvider(pubName));
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
icon: const Icon(Symbols.add_circle),
|
icon: const Icon(Symbols.add_circle),
|
||||||
),
|
),
|
||||||
@@ -71,7 +74,10 @@ class SliverStickerPacksList extends HookConsumerWidget {
|
|||||||
subtitle: Text(sticker.description),
|
subtitle: Text(sticker.description),
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('creatorStickerPackDetail', pathParameters: {'pubName': pubName, 'packId': sticker.id});
|
context.pushNamed(
|
||||||
|
'creatorStickerPackDetail',
|
||||||
|
pathParameters: {'pubName': pubName, 'packId': sticker.id},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -99,7 +105,7 @@ class StickerPacksNotifier extends _$StickerPacksNotifier
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/stickers',
|
'/sphere/stickers',
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
'offset': offset,
|
'offset': offset,
|
||||||
'take': _pageSize,
|
'take': _pageSize,
|
||||||
@@ -129,7 +135,7 @@ class StickerPacksNotifier extends _$StickerPacksNotifier
|
|||||||
Future<SnStickerPack?> stickerPack(Ref ref, String? packId) async {
|
Future<SnStickerPack?> stickerPack(Ref ref, String? packId) async {
|
||||||
if (packId == null) return null;
|
if (packId == null) return null;
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get('/stickers/$packId');
|
final resp = await apiClient.get('/sphere/stickers/$packId');
|
||||||
return SnStickerPack.fromJson(resp.data);
|
return SnStickerPack.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +181,7 @@ class EditStickerPacksScreen extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.request(
|
final resp = await apiClient.request(
|
||||||
'/stickers',
|
'/sphere/stickers',
|
||||||
data: {
|
data: {
|
||||||
'name': nameController.text,
|
'name': nameController.text,
|
||||||
'description': descriptionController.text,
|
'description': descriptionController.text,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'stickers.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$stickerPackHash() => r'4f70d26e695ba1d8c7273d12730f77da79361733';
|
String _$stickerPackHash() => r'71ef84471237c8191918095094bdfc87d3920e77';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
@@ -148,7 +148,7 @@ class _StickerPackProviderElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$stickerPacksNotifierHash() =>
|
String _$stickerPacksNotifierHash() =>
|
||||||
r'dc0cc4ec27fdd6d5da28f982ff10c852f8107a18';
|
r'0a8edcf9c35396c411f1214f5e77b1e8fac6a3e6';
|
||||||
|
|
||||||
abstract class _$StickerPacksNotifier
|
abstract class _$StickerPacksNotifier
|
||||||
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnStickerPack>> {
|
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnStickerPack>> {
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ part 'hub.g.dart';
|
|||||||
Future<DeveloperStats?> developerStats(Ref ref, String? uname) async {
|
Future<DeveloperStats?> developerStats(Ref ref, String? uname) async {
|
||||||
if (uname == null) return null;
|
if (uname == null) return null;
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get('/developers/$uname/stats');
|
final resp = await apiClient.get('/sphere/developers/$uname/stats');
|
||||||
return DeveloperStats.fromJson(resp.data);
|
return DeveloperStats.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<List<SnPublisher>> developers(Ref ref) async {
|
Future<List<SnPublisher>> developers(Ref ref) async {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final resp = await client.get('/developers');
|
final resp = await client.get('/sphere/developers');
|
||||||
return resp.data
|
return resp.data
|
||||||
.map((e) => SnPublisher.fromJson(e))
|
.map((e) => SnPublisher.fromJson(e))
|
||||||
.cast<SnPublisher>()
|
.cast<SnPublisher>()
|
||||||
@@ -243,7 +243,12 @@ class DeveloperHubScreen extends HookConsumerWidget {
|
|||||||
horizontal: 24,
|
horizontal: 24,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('developerApps', pathParameters: {'name': currentDeveloper.value!.name});
|
context.pushNamed(
|
||||||
|
'developerApps',
|
||||||
|
pathParameters: {
|
||||||
|
'name': currentDeveloper.value!.name,
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -334,7 +339,7 @@ class _DeveloperEnrollmentSheet extends HookConsumerWidget {
|
|||||||
Future<void> enroll(SnPublisher publisher) async {
|
Future<void> enroll(SnPublisher publisher) async {
|
||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.post('/developers/${publisher.name}/enroll');
|
await client.post('/sphere/developers/${publisher.name}/enroll');
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'hub.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$developerStatsHash() => r'783398cbde09c3d956c3e20b02a1cebd1f8ab748';
|
String _$developerStatsHash() => r'baa708f3586e8987e221cc8ab825d759658c0f55';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
@@ -149,7 +149,7 @@ class _DeveloperStatsProviderElement
|
|||||||
String? get uname => (origin as DeveloperStatsProvider).uname;
|
String? get uname => (origin as DeveloperStatsProvider).uname;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$developersHash() => r'f52639d3c21aafbf235c8ae33f35448baf2989a1';
|
String _$developersHash() => r'f11335fdf553c661110281edeec70ef89c64727d';
|
||||||
|
|
||||||
/// See also [developers].
|
/// See also [developers].
|
||||||
@ProviderFor(developers)
|
@ProviderFor(developers)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class ArticlesListNotifier extends _$ArticlesListNotifier
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/feeds/articles',
|
'/sphere/feeds/articles',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class NotificationListNotifier extends _$NotificationListNotifier
|
|||||||
final queryParams = {'offset': offset, 'take': _pageSize};
|
final queryParams = {'offset': offset, 'take': _pageSize};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/notifications',
|
'/pusher/notifications',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ final notificationUnreadCountNotifierProvider =
|
|||||||
|
|
||||||
typedef _$NotificationUnreadCountNotifier = AutoDisposeAsyncNotifier<int>;
|
typedef _$NotificationUnreadCountNotifier = AutoDisposeAsyncNotifier<int>;
|
||||||
String _$notificationListNotifierHash() =>
|
String _$notificationListNotifierHash() =>
|
||||||
r'934a47bc2ce9e75699a4f53e2169470fd0c04a53';
|
r'5099466db475bbcf1ab6b514eb072f1dc4c6f930';
|
||||||
|
|
||||||
/// See also [NotificationListNotifier].
|
/// See also [NotificationListNotifier].
|
||||||
@ProviderFor(NotificationListNotifier)
|
@ProviderFor(NotificationListNotifier)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class PostSearchNotifier
|
|||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
final offset = cursor == null ? 0 : int.parse(cursor);
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/posts/search',
|
'/sphere/posts/search',
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
'query': _currentQuery,
|
'query': _currentQuery,
|
||||||
'offset': offset,
|
'offset': offset,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ part 'pub_profile.g.dart';
|
|||||||
@riverpod
|
@riverpod
|
||||||
Future<SnPublisher> publisher(Ref ref, String uname) async {
|
Future<SnPublisher> publisher(Ref ref, String uname) async {
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get("/publishers/$uname");
|
final resp = await apiClient.get("/sphere/publishers/$uname");
|
||||||
return SnPublisher.fromJson(resp.data);
|
return SnPublisher.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ Future<List<SnAccountBadge>> publisherBadges(Ref ref, String pubName) async {
|
|||||||
final pub = await ref.watch(publisherProvider(pubName).future);
|
final pub = await ref.watch(publisherProvider(pubName).future);
|
||||||
if (pub.type != 0 || pub.account == null) return [];
|
if (pub.type != 0 || pub.account == null) return [];
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get("/accounts/${pub.account!.name}/badges");
|
final resp = await apiClient.get("/id/accounts/${pub.account!.name}/badges");
|
||||||
return List<SnAccountBadge>.from(
|
return List<SnAccountBadge>.from(
|
||||||
resp.data.map((x) => SnAccountBadge.fromJson(x)),
|
resp.data.map((x) => SnAccountBadge.fromJson(x)),
|
||||||
);
|
);
|
||||||
@@ -49,7 +49,7 @@ Future<SnSubscriptionStatus> publisherSubscriptionStatus(
|
|||||||
String pubName,
|
String pubName,
|
||||||
) async {
|
) async {
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get("/publishers/$pubName/subscription");
|
final resp = await apiClient.get("/sphere/publishers/$pubName/subscription");
|
||||||
return SnSubscriptionStatus.fromJson(resp.data);
|
return SnSubscriptionStatus.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +188,10 @@ class PublisherProfileScreen extends HookConsumerWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
if (data.account?.name != null) {
|
if (data.account?.name != null) {
|
||||||
context.pushNamed('accountProfile', pathParameters: {'name': data.account!.name});
|
context.pushNamed(
|
||||||
|
'accountProfile',
|
||||||
|
pathParameters: {'name': data.account!.name},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ class RealmDetailScreen extends HookConsumerWidget {
|
|||||||
apiClientProvider,
|
apiClientProvider,
|
||||||
);
|
);
|
||||||
await apiClient.post(
|
await apiClient.post(
|
||||||
'/realms/$slug/members/me',
|
'/sphere/realms/$slug/members/me',
|
||||||
);
|
);
|
||||||
ref.invalidate(
|
ref.invalidate(
|
||||||
realmIdentityProvider(slug),
|
realmIdentityProvider(slug),
|
||||||
@@ -213,7 +213,10 @@ class RealmDetailScreen extends HookConsumerWidget {
|
|||||||
return ChatRoomListTile(
|
return ChatRoomListTile(
|
||||||
room: rooms[index],
|
room: rooms[index],
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('chatRoom', pathParameters: {'id': rooms[index].id});
|
context.pushNamed(
|
||||||
|
'chatRoom',
|
||||||
|
pathParameters: {'id': rooms[index].id},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}, childCount: rooms.length),
|
}, childCount: rooms.length),
|
||||||
@@ -251,7 +254,10 @@ class _RealmActionMenu extends HookConsumerWidget {
|
|||||||
if (isModerator)
|
if (isModerator)
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushReplacement('/sphere/realms/$realmSlug/edit');
|
context.pushReplacementNamed(
|
||||||
|
'realmEdit',
|
||||||
|
pathParameters: {'slug': realmSlug},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -319,7 +325,7 @@ class _RealmActionMenu extends HookConsumerWidget {
|
|||||||
if (confirm) {
|
if (confirm) {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
client.delete(
|
client.delete(
|
||||||
'/realms/$realmSlug/members/me',
|
'/sphere/realms/$realmSlug/members/me',
|
||||||
);
|
);
|
||||||
ref.invalidate(realmsJoinedProvider);
|
ref.invalidate(realmsJoinedProvider);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
@@ -389,7 +395,7 @@ class RealmMemberListNotifier extends _$RealmMemberListNotifier
|
|||||||
final offset = cursor != null ? int.parse(cursor) : 0;
|
final offset = cursor != null ? int.parse(cursor) : 0;
|
||||||
|
|
||||||
final response = await apiClient.get(
|
final response = await apiClient.get(
|
||||||
'/realms/$realmSlug/members',
|
'/sphere/realms/$realmSlug/members',
|
||||||
queryParameters: {'offset': offset, 'take': _pageSize},
|
queryParameters: {'offset': offset, 'take': _pageSize},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -432,7 +438,7 @@ class RealmMemberNotifier extends StateNotifier<RealmMemberState> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await _apiClient.get(
|
final response = await _apiClient.get(
|
||||||
'/realms/$realmSlug/members',
|
'/sphere/realms/$realmSlug/members',
|
||||||
queryParameters: {'offset': offset, 'take': take},
|
queryParameters: {'offset': offset, 'take': take},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -487,7 +493,7 @@ class _RealmMemberListSheet extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
await apiClient.post(
|
await apiClient.post(
|
||||||
'/realms/invites/$realmSlug',
|
'/sphere/realms/invites/$realmSlug',
|
||||||
data: {'related_user_id': result.id, 'role': 0},
|
data: {'related_user_id': result.id, 'role': 0},
|
||||||
);
|
);
|
||||||
// Refresh both providers
|
// Refresh both providers
|
||||||
@@ -619,7 +625,7 @@ class _RealmMemberListSheet extends HookConsumerWidget {
|
|||||||
apiClientProvider,
|
apiClientProvider,
|
||||||
);
|
);
|
||||||
await apiClient.delete(
|
await apiClient.delete(
|
||||||
'/realms/$realmSlug/members/${member.accountId}',
|
'/sphere/realms/$realmSlug/members/${member.accountId}',
|
||||||
);
|
);
|
||||||
// Refresh both providers
|
// Refresh both providers
|
||||||
memberNotifier.reset();
|
memberNotifier.reset();
|
||||||
@@ -769,7 +775,7 @@ class _RealmMemberRoleSheet extends HookConsumerWidget {
|
|||||||
|
|
||||||
final apiClient = ref.read(apiClientProvider);
|
final apiClient = ref.read(apiClientProvider);
|
||||||
await apiClient.patch(
|
await apiClient.patch(
|
||||||
'/realms/$realmSlug/members/${member.accountId}/role',
|
'/sphere/realms/$realmSlug/members/${member.accountId}/role',
|
||||||
data: newRole,
|
data: newRole,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ class _RealmChatRoomsProviderElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$realmMemberListNotifierHash() =>
|
String _$realmMemberListNotifierHash() =>
|
||||||
r'b2e3eefc62a597f45df9470b2058fdda62f8853f';
|
r'022bcef5a90cbae05ff23b937851afc3ef913d42';
|
||||||
|
|
||||||
abstract class _$RealmMemberListNotifier
|
abstract class _$RealmMemberListNotifier
|
||||||
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnRealmMember>> {
|
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnRealmMember>> {
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
final realmInvites = ref.watch(realmInvitesProvider);
|
final realmInvites = ref.watch(realmInvitesProvider);
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
extendBody: false, // Prevent conflicts with tabs navigation
|
|
||||||
noBackground: false,
|
noBackground: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('realms').tr(),
|
title: const Text('realms').tr(),
|
||||||
@@ -70,6 +69,7 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
builder: (_) => const _RealmInviteSheet(),
|
builder: (_) => const _RealmInviteSheet(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -108,7 +108,10 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
title: Text(value[item].name),
|
title: Text(value[item].name),
|
||||||
subtitle: Text(value[item].description),
|
subtitle: Text(value[item].description),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('realmDetail', pathParameters: {'slug': value[item].slug});
|
context.pushNamed(
|
||||||
|
'realmDetail',
|
||||||
|
pathParameters: {'slug': value[item].slug},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
contentPadding: const EdgeInsets.only(
|
contentPadding: const EdgeInsets.only(
|
||||||
left: 16,
|
left: 16,
|
||||||
@@ -253,7 +256,7 @@ class EditRealmScreen extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final resp = await client.request(
|
final resp = await client.request(
|
||||||
slug == null ? '/realms' : '/realms/$slug',
|
'/sphere${slug == null ? '/realms' : '/realms/$slug'}',
|
||||||
data: {
|
data: {
|
||||||
'slug': slugController.text,
|
'slug': slugController.text,
|
||||||
'name': nameController.text,
|
'name': nameController.text,
|
||||||
@@ -276,128 +279,131 @@ class EditRealmScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
|
noBackground: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(slug == null ? 'createRealm'.tr() : 'editRealm'.tr()),
|
title: Text(slug == null ? 'createRealm'.tr() : 'editRealm'.tr()),
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: SingleChildScrollView(
|
||||||
children: [
|
child: Column(
|
||||||
AspectRatio(
|
children: [
|
||||||
aspectRatio: 16 / 7,
|
AspectRatio(
|
||||||
child: Stack(
|
aspectRatio: 16 / 7,
|
||||||
clipBehavior: Clip.none,
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
fit: StackFit.expand,
|
||||||
GestureDetector(
|
children: [
|
||||||
child: Container(
|
GestureDetector(
|
||||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
child: Container(
|
||||||
child:
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
background.value != null
|
child:
|
||||||
? CloudFileWidget(
|
background.value != null
|
||||||
item: background.value!,
|
? CloudFileWidget(
|
||||||
fit: BoxFit.cover,
|
item: background.value!,
|
||||||
)
|
fit: BoxFit.cover,
|
||||||
: const SizedBox.shrink(),
|
)
|
||||||
),
|
: const SizedBox.shrink(),
|
||||||
onTap: () {
|
|
||||||
setPicture('background');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
left: 20,
|
|
||||||
bottom: -32,
|
|
||||||
child: GestureDetector(
|
|
||||||
child: ProfilePictureWidget(
|
|
||||||
fileId: picture.value?.id,
|
|
||||||
radius: 40,
|
|
||||||
fallbackIcon: Symbols.group,
|
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setPicture('picture');
|
setPicture('background');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
Positioned(
|
||||||
],
|
left: 20,
|
||||||
|
bottom: -32,
|
||||||
|
child: GestureDetector(
|
||||||
|
child: ProfilePictureWidget(
|
||||||
|
fileId: picture.value?.id,
|
||||||
|
radius: 40,
|
||||||
|
fallbackIcon: Symbols.group,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setPicture('picture');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).padding(bottom: 32),
|
||||||
|
Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
controller: slugController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'slug'.tr(),
|
||||||
|
helperText: 'slugHint'.tr(),
|
||||||
|
),
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: nameController,
|
||||||
|
decoration: InputDecoration(labelText: 'name'.tr()),
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: descriptionController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'description'.tr(),
|
||||||
|
alignLabelWithHint: true,
|
||||||
|
),
|
||||||
|
minLines: 3,
|
||||||
|
maxLines: null,
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Card(
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
CheckboxListTile(
|
||||||
|
secondary: const Icon(Symbols.public),
|
||||||
|
title: Text('publicRealm').tr(),
|
||||||
|
subtitle: Text('publicRealmDescription').tr(),
|
||||||
|
value: isPublic.value,
|
||||||
|
onChanged: (value) {
|
||||||
|
isPublic.value = value ?? true;
|
||||||
|
},
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CheckboxListTile(
|
||||||
|
secondary: const Icon(Symbols.travel_explore),
|
||||||
|
title: Text('communityRealm').tr(),
|
||||||
|
subtitle: Text('communityRealmDescription').tr(),
|
||||||
|
value: isCommunity.value,
|
||||||
|
onChanged: (value) {
|
||||||
|
isCommunity.value = value ?? false;
|
||||||
|
},
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: TextButton.icon(
|
||||||
|
onPressed: submitting.value ? null : performAction,
|
||||||
|
label: Text('saveChanges'.tr()),
|
||||||
|
icon: const Icon(Symbols.save),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(all: 24),
|
||||||
),
|
),
|
||||||
).padding(bottom: 32),
|
],
|
||||||
Form(
|
),
|
||||||
key: formKey,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
TextFormField(
|
|
||||||
controller: slugController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'slug'.tr(),
|
|
||||||
helperText: 'slugHint'.tr(),
|
|
||||||
),
|
|
||||||
onTapOutside:
|
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
TextFormField(
|
|
||||||
controller: nameController,
|
|
||||||
decoration: InputDecoration(labelText: 'name'.tr()),
|
|
||||||
onTapOutside:
|
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
TextFormField(
|
|
||||||
controller: descriptionController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'description'.tr(),
|
|
||||||
alignLabelWithHint: true,
|
|
||||||
),
|
|
||||||
minLines: 3,
|
|
||||||
maxLines: null,
|
|
||||||
onTapOutside:
|
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Card(
|
|
||||||
margin: EdgeInsets.zero,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
CheckboxListTile(
|
|
||||||
secondary: const Icon(Symbols.public),
|
|
||||||
title: Text('publicRealm').tr(),
|
|
||||||
subtitle: Text('publicRealmDescription').tr(),
|
|
||||||
value: isPublic.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
isPublic.value = value ?? true;
|
|
||||||
},
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CheckboxListTile(
|
|
||||||
secondary: const Icon(Symbols.travel_explore),
|
|
||||||
title: Text('communityRealm').tr(),
|
|
||||||
subtitle: Text('communityRealmDescription').tr(),
|
|
||||||
value: isCommunity.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
isCommunity.value = value ?? false;
|
|
||||||
},
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: TextButton.icon(
|
|
||||||
onPressed: submitting.value ? null : performAction,
|
|
||||||
label: Text('saveChanges'.tr()),
|
|
||||||
icon: const Icon(Symbols.save),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
).padding(all: 24),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ class TabsScreen extends HookConsumerWidget {
|
|||||||
final routes = ['/', '/chat', '/realms', '/account'];
|
final routes = ['/', '/chat', '/realms', '/account'];
|
||||||
|
|
||||||
int getCurrentIndex() {
|
int getCurrentIndex() {
|
||||||
if (currentLocation.startsWith('/sphere/chat')) return 1;
|
if (currentLocation.startsWith('/chat')) return 1;
|
||||||
if (currentLocation.startsWith('/sphere/realms')) return 2;
|
if (currentLocation.startsWith('/realms')) return 2;
|
||||||
if (currentLocation.startsWith('/id/account')) return 3;
|
if (currentLocation.startsWith('/account')) return 3;
|
||||||
return 0; // Default to explore
|
return 0; // Default to explore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class TransactionListNotifier extends _$TransactionListNotifier
|
|||||||
final queryParams = {'offset': offset, 'take': _pageSize};
|
final queryParams = {'offset': offset, 'take': _pageSize};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/wallets/transactions',
|
'/id/wallets/transactions',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
@@ -110,7 +110,7 @@ class WalletScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
).center();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ final walletCurrentProvider = AutoDisposeFutureProvider<SnWallet?>.internal(
|
|||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
typedef WalletCurrentRef = AutoDisposeFutureProviderRef<SnWallet?>;
|
typedef WalletCurrentRef = AutoDisposeFutureProviderRef<SnWallet?>;
|
||||||
String _$transactionListNotifierHash() =>
|
String _$transactionListNotifierHash() =>
|
||||||
r'148ffb0ee9e3be3b92de432f314d8ee2f09e9a24';
|
r'7b777cd44f3351f68f7bd1dd76bfe8b388381bdb';
|
||||||
|
|
||||||
/// See also [TransactionListNotifier].
|
/// See also [TransactionListNotifier].
|
||||||
@ProviderFor(TransactionListNotifier)
|
@ProviderFor(TransactionListNotifier)
|
||||||
|
|||||||
@@ -11,13 +11,16 @@ class AbuseReportService {
|
|||||||
AbuseReportService(this.ref);
|
AbuseReportService(this.ref);
|
||||||
|
|
||||||
Future<SnAbuseReport> getReport(String id) async {
|
Future<SnAbuseReport> getReport(String id) async {
|
||||||
final response =
|
final response = await ref
|
||||||
await ref.read(apiClientProvider).get('/safety/reports/me/$id');
|
.read(apiClientProvider)
|
||||||
|
.get('/id/safety/reports/me/$id');
|
||||||
return SnAbuseReport.fromJson(response.data);
|
return SnAbuseReport.fromJson(response.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SnAbuseReport>> getReports() async {
|
Future<List<SnAbuseReport>> getReports() async {
|
||||||
final response = await ref.read(apiClientProvider).get('/safety/reports/me');
|
final response = await ref
|
||||||
|
.read(apiClientProvider)
|
||||||
|
.get('/id/safety/reports/me');
|
||||||
return (response.data as List)
|
return (response.data as List)
|
||||||
.map((json) => SnAbuseReport.fromJson(json))
|
.map((json) => SnAbuseReport.fromJson(json))
|
||||||
.toList();
|
.toList();
|
||||||
|
|||||||
@@ -175,8 +175,8 @@ Completer<SnCloudFile?> _processUpload(
|
|||||||
final client = TusClient(file);
|
final client = TusClient(file);
|
||||||
client
|
client
|
||||||
.upload(
|
.upload(
|
||||||
uri: Uri.parse('$baseUrl/files/tus'),
|
uri: Uri.parse('$baseUrl/drive/tus'),
|
||||||
headers: {'Authorization': 'Bearer $atk'},
|
headers: {'Authorization': 'AtField $atk'},
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
onComplete: (lastResponse) {
|
onComplete: (lastResponse) {
|
||||||
final resp = jsonDecode(lastResponse!.headers['x-fileinfo']!);
|
final resp = jsonDecode(lastResponse!.headers['x-fileinfo']!);
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ Future<void> _putTokenToRemote(
|
|||||||
int provider,
|
int provider,
|
||||||
) async {
|
) async {
|
||||||
await apiClient.put(
|
await apiClient.put(
|
||||||
"/notifications/subscription",
|
"/pusher/notifications/subscription",
|
||||||
data: {"provider": provider, "device_token": token},
|
data: {"provider": provider, "device_token": token},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'account_picker.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$searchAccountsHash() => r'4923cd06876d04515d95d3c58ee3ea9e05c58e4a';
|
String _$searchAccountsHash() => r'fa3b8b7d51e14cf40d4116ba0ff0b6955fa0ff54';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ class FortuneGraphWidget extends HookConsumerWidget {
|
|||||||
constraints: const BoxConstraints(),
|
constraints: const BoxConstraints(),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.pushNamed(
|
context.pushNamed(
|
||||||
'/account/$eventCalanderUser/calendar',
|
'accountCalendar',
|
||||||
|
pathParameters: {'name': eventCalanderUser!},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ class CloudFileList extends HookConsumerWidget {
|
|||||||
double calculateAspectRatio() {
|
double calculateAspectRatio() {
|
||||||
double total = 0;
|
double total = 0;
|
||||||
for (var ratio in files.map((e) => e.fileMeta?['ratio'] ?? 1)) {
|
for (var ratio in files.map((e) => e.fileMeta?['ratio'] ?? 1)) {
|
||||||
total += ratio;
|
if (ratio is double) total += ratio;
|
||||||
|
if (ratio is String) total += double.parse(ratio);
|
||||||
}
|
}
|
||||||
if (total == 0) return 1;
|
if (total == 0) return 1;
|
||||||
return total / files.length;
|
return total / files.length;
|
||||||
@@ -78,6 +79,7 @@ class CloudFileList extends HookConsumerWidget {
|
|||||||
if (!disableZoomIn) {
|
if (!disableZoomIn) {
|
||||||
context.pushTransparentRoute(
|
context.pushTransparentRoute(
|
||||||
CloudFileZoomIn(item: files.first, heroTag: heroTags.first),
|
CloudFileZoomIn(item: files.first, heroTag: heroTags.first),
|
||||||
|
rootNavigator: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -505,7 +507,7 @@ class _CloudFileListEntry extends StatelessWidget {
|
|||||||
if (isImage)
|
if (isImage)
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child:
|
child:
|
||||||
file.fileMeta?['blur'] != null
|
file.fileMeta?['blur'] is String
|
||||||
? BlurHash(hash: file.fileMeta?['blur'])
|
? BlurHash(hash: file.fileMeta?['blur'])
|
||||||
: ImageFiltered(
|
: ImageFiltered(
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||||
|
|||||||
@@ -25,9 +25,14 @@ class CloudFileWidget extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final uri = '$serverUrl/api/files/${item.id}';
|
final uri = '$serverUrl/drive/files/${item.id}';
|
||||||
|
|
||||||
var ratio = (item.fileMeta?['ratio'] ?? 1).toDouble();
|
var ratio =
|
||||||
|
item.fileMeta?['ratio'] is num
|
||||||
|
? item.fileMeta!['ratio'].toDouble()
|
||||||
|
: item.fileMeta?['ratio'] is String
|
||||||
|
? double.parse(item.fileMeta!['ratio'])
|
||||||
|
: 1.0;
|
||||||
if (ratio == 0) ratio = 1.0;
|
if (ratio == 0) ratio = 1.0;
|
||||||
final content = switch (item.mimeType?.split('/').firstOrNull) {
|
final content = switch (item.mimeType?.split('/').firstOrNull) {
|
||||||
"image" => AspectRatio(
|
"image" => AspectRatio(
|
||||||
@@ -70,7 +75,7 @@ class CloudImageWidget extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final uri = '$serverUrl/api/files/${file?.id ?? fileId}';
|
final uri = '$serverUrl/drive/files/${file?.id ?? fileId}';
|
||||||
|
|
||||||
return AspectRatio(
|
return AspectRatio(
|
||||||
aspectRatio: aspectRatio,
|
aspectRatio: aspectRatio,
|
||||||
@@ -86,7 +91,7 @@ class CloudImageWidget extends ConsumerWidget {
|
|||||||
required String serverUrl,
|
required String serverUrl,
|
||||||
bool original = false,
|
bool original = false,
|
||||||
}) {
|
}) {
|
||||||
final uri = '$serverUrl/api/files/$fileId?original=$original';
|
final uri = '$serverUrl/drive/files/$fileId?original=$original';
|
||||||
return CachedNetworkImageProvider(uri);
|
return CachedNetworkImageProvider(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +114,7 @@ class ProfilePictureWidget extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final uri = '$serverUrl/api/files/${file?.id ?? fileId}';
|
final uri = '$serverUrl/drive/files/${file?.id ?? fileId}';
|
||||||
|
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(radius)),
|
borderRadius: BorderRadius.all(Radius.circular(radius)),
|
||||||
@@ -302,7 +307,7 @@ class SplitAvatarWidget extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final uri = '$serverUrl/api/files/$fileId';
|
final uri = '$serverUrl/drive/files/$fileId';
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: radius,
|
width: radius,
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ class ComposeLogic {
|
|||||||
final attachment = state.attachments.value[index];
|
final attachment = state.attachments.value[index];
|
||||||
if (attachment.isOnCloud) {
|
if (attachment.isOnCloud) {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
await client.delete('/files/${attachment.data.id}');
|
await client.delete('/drive/files/${attachment.data.id}');
|
||||||
}
|
}
|
||||||
final clone = List.of(state.attachments.value);
|
final clone = List.of(state.attachments.value);
|
||||||
clone.removeAt(index);
|
clone.removeAt(index);
|
||||||
@@ -530,7 +530,8 @@ class ComposeLogic {
|
|||||||
// Prepare API request
|
// Prepare API request
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final isNewPost = originalPost == null;
|
final isNewPost = originalPost == null;
|
||||||
final endpoint = isNewPost ? '/posts' : '/posts/${originalPost.id}';
|
final endpoint =
|
||||||
|
'/sphere${isNewPost ? '/posts' : '/posts/${originalPost.id}'}';
|
||||||
|
|
||||||
// Create request payload
|
// Create request payload
|
||||||
final payload = {
|
final payload = {
|
||||||
|
|||||||
@@ -72,7 +72,10 @@ class PostItem extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('publisherProfile', pathParameters: {'name': item.publisher.name});
|
context.pushNamed(
|
||||||
|
'publisherProfile',
|
||||||
|
pathParameters: {'name': item.publisher.name},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
@@ -254,7 +257,10 @@ class PostItem extends HookConsumerWidget {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: ProfilePictureWidget(file: item.publisher.picture),
|
child: ProfilePictureWidget(file: item.publisher.picture),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('publisherProfile', pathParameters: {'name': item.publisher.name});
|
context.pushNamed(
|
||||||
|
'publisherProfile',
|
||||||
|
pathParameters: {'name': item.publisher.name},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -427,7 +433,10 @@ class PostItem extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (isOpenable) {
|
if (isOpenable) {
|
||||||
context.pushNamed('postDetail', pathParameters: {'id': item.id});
|
context.pushNamed(
|
||||||
|
'postDetail',
|
||||||
|
pathParameters: {'id': item.id},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -496,11 +505,13 @@ class PostItem extends HookConsumerWidget {
|
|||||||
title: 'edit'.tr(),
|
title: 'edit'.tr(),
|
||||||
image: MenuImage.icon(Symbols.edit),
|
image: MenuImage.icon(Symbols.edit),
|
||||||
callback: () {
|
callback: () {
|
||||||
context.pushNamed('postEdit', pathParameters: {'id': item.id}).then((value) {
|
context
|
||||||
if (value != null) {
|
.pushNamed('postEdit', pathParameters: {'id': item.id})
|
||||||
onRefresh?.call();
|
.then((value) {
|
||||||
}
|
if (value != null) {
|
||||||
});
|
onRefresh?.call();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (isAuthor)
|
if (isAuthor)
|
||||||
@@ -732,7 +743,13 @@ Widget _buildReferencePost(BuildContext context, SnPost item) {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
).gestures(onTap: () => context.pushNamed('postDetail', pathParameters: {'id': referencePost.id}));
|
).gestures(
|
||||||
|
onTap:
|
||||||
|
() => context.pushNamed(
|
||||||
|
'postDetail',
|
||||||
|
pathParameters: {'id': referencePost.id},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostReactionList extends HookConsumerWidget {
|
class PostReactionList extends HookConsumerWidget {
|
||||||
@@ -757,7 +774,7 @@ class PostReactionList extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
await client
|
await client
|
||||||
.post(
|
.post(
|
||||||
'/posts/$parentId/reactions',
|
'/sphere/posts/$parentId/reactions',
|
||||||
data: {'symbol': symbol, 'attitude': attitude},
|
data: {'symbol': symbol, 'attitude': attitude},
|
||||||
)
|
)
|
||||||
.catchError((err) {
|
.catchError((err) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class PostQuickReply extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
await client.post(
|
await client.post(
|
||||||
'/posts',
|
'/sphere/posts',
|
||||||
data: {
|
data: {
|
||||||
'content': contentController.text,
|
'content': contentController.text,
|
||||||
'replied_post_id': parent.id,
|
'replied_post_id': parent.id,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class PostRepliesNotifier extends _$PostRepliesNotifier
|
|||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
final offset = cursor == null ? 0 : int.parse(cursor);
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/posts/$_postId/replies',
|
'/sphere/posts/$_postId/replies',
|
||||||
queryParameters: {'offset': offset, 'take': _pageSize},
|
queryParameters: {'offset': offset, 'take': _pageSize},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -57,7 +57,11 @@ class PostRepliesNotifier extends _$PostRepliesNotifier
|
|||||||
class PostRepliesList extends HookConsumerWidget {
|
class PostRepliesList extends HookConsumerWidget {
|
||||||
final String postId;
|
final String postId;
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
const PostRepliesList({super.key, required this.postId, this.backgroundColor});
|
const PostRepliesList({
|
||||||
|
super.key,
|
||||||
|
required this.postId,
|
||||||
|
this.backgroundColor,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -93,7 +97,8 @@ class PostRepliesList extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
PostItem(
|
PostItem(
|
||||||
item: data.items[index],
|
item: data.items[index],
|
||||||
backgroundColor: backgroundColor ?? (isWide ? Colors.transparent : null),
|
backgroundColor:
|
||||||
|
backgroundColor ?? (isWide ? Colors.transparent : null),
|
||||||
showReferencePost: false,
|
showReferencePost: false,
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'post_replies.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$postRepliesNotifierHash() =>
|
String _$postRepliesNotifierHash() =>
|
||||||
r'49c178102ec0a4136974a0e9a8f090f511abd542';
|
r'1cdda919249e3bf34459369e033ad5de8dbcf3f8';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class RealmListNotifier extends _$RealmListNotifier
|
|||||||
};
|
};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/discovery/realms',
|
'/sphere/discovery/realms',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'realm_list.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$realmListNotifierHash() => r'02dee373a5609a5617b04ffec395d09dea7ae070';
|
String _$realmListNotifierHash() => r'8ae5c3ae2837acae4c7bf5e44578518afc9ea1a6';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class AbuseReportSheet extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.post(
|
await client.post(
|
||||||
'/safety/reports',
|
'/id/safety/reports',
|
||||||
data: {
|
data: {
|
||||||
'resource_identifier': resourceIdentifier,
|
'resource_identifier': resourceIdentifier,
|
||||||
'type': selectedType.value,
|
'type': selectedType.value,
|
||||||
|
|||||||
@@ -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: 3.1.0+113
|
version: 3.1.0+114
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.7.2
|
sdk: ^3.7.2
|
||||||
|
|||||||
Reference in New Issue
Block a user