Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
9ac4a940dd | |||
ec050ab712 | |||
77e3ce8bcc | |||
f5dcf71e10 | |||
7fc18b40db | |||
8c8ab24c9e | |||
a319bd7f8c | |||
6427ec1f82 | |||
35dc7f4392 |
@ -10,8 +10,9 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.glance:glance:1.1.1"
|
||||
implementation "androidx.glance:glance-appwidget:1.1.1"
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'androidx.glance:glance:1.1.1'
|
||||
implementation 'androidx.glance:glance-appwidget:1.1.1'
|
||||
implementation 'androidx.compose.foundation:foundation-layout-android:1.7.6'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
@ -19,6 +20,12 @@ dependencies {
|
||||
implementation 'io.coil-kt.coil3:coil-network-okhttp:3.0.4'
|
||||
}
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
buildFeatures {
|
||||
compose true
|
||||
@ -49,6 +56,15 @@ android {
|
||||
versionName = flutter.versionName
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias = keystoreProperties['keyAlias']
|
||||
keyPassword = keystoreProperties['keyPassword']
|
||||
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword = keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
debuggable true
|
||||
@ -56,9 +72,7 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig = signingConfigs.debug
|
||||
signingConfig = signingConfigs.release
|
||||
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.glance.GlanceId
|
||||
@ -87,11 +86,18 @@ class CheckInWidget : GlanceAppWidget() {
|
||||
Column {
|
||||
Text(
|
||||
text = resultTierSymbols[checkIn.resultTier],
|
||||
style = TextStyle(fontSize = 17.sp)
|
||||
style = TextStyle(
|
||||
fontSize = 17.sp,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
Text(
|
||||
text = "+${checkIn.resultExperience} EXP",
|
||||
style = TextStyle(fontSize = 13.sp, fontFamily = FontFamily.Monospace)
|
||||
style = TextStyle(
|
||||
fontSize = 13.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = GlanceModifier.height(8.dp))
|
||||
@ -102,7 +108,10 @@ class CheckInWidget : GlanceAppWidget() {
|
||||
ZoneId.systemDefault()
|
||||
)
|
||||
.format(dateFormatter),
|
||||
style = TextStyle(fontSize = 11.sp)
|
||||
style = TextStyle(
|
||||
fontSize = 11.sp,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -112,7 +121,7 @@ class CheckInWidget : GlanceAppWidget() {
|
||||
|
||||
Text(
|
||||
text = "You haven't checked in today",
|
||||
style = TextStyle(fontSize = 15.sp)
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -87,12 +87,16 @@ class RandomPostWidget : GlanceAppWidget() {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = data.publisher.nick,
|
||||
style = TextStyle(fontSize = 15.sp)
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
Spacer(modifier = GlanceModifier.width(8.dp))
|
||||
Text(
|
||||
text = "@${data.publisher.name}",
|
||||
style = TextStyle(fontSize = 13.sp, fontFamily = FontFamily.Monospace)
|
||||
style = TextStyle(
|
||||
fontSize = 13.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -101,13 +105,13 @@ class RandomPostWidget : GlanceAppWidget() {
|
||||
if (data.body.title != null) {
|
||||
Text(
|
||||
text = data.body.title,
|
||||
style = TextStyle(fontSize = 25.sp)
|
||||
style = TextStyle(fontSize = 19.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
if (data.body.description != null) {
|
||||
Text(
|
||||
text = data.body.description,
|
||||
style = TextStyle(fontSize = 19.sp)
|
||||
style = TextStyle(fontSize = 17.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
|
||||
@ -117,7 +121,7 @@ class RandomPostWidget : GlanceAppWidget() {
|
||||
|
||||
Text(
|
||||
text = data.body.content ?: "No content",
|
||||
style = TextStyle(fontSize = 15.sp),
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface),
|
||||
)
|
||||
|
||||
Spacer(modifier = GlanceModifier.height(8.dp))
|
||||
@ -126,12 +130,16 @@ class RandomPostWidget : GlanceAppWidget() {
|
||||
Text(
|
||||
LocalDateTime.ofInstant(data.createdAt, ZoneId.systemDefault())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
|
||||
style = TextStyle(fontSize = 13.sp),
|
||||
style = TextStyle(fontSize = 13.sp, color = GlanceTheme.colors.onSurface),
|
||||
)
|
||||
|
||||
Text(
|
||||
"#${data.id}",
|
||||
style = TextStyle(fontSize = 11.sp, fontWeight = FontWeight.Bold),
|
||||
style = TextStyle(
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
),
|
||||
)
|
||||
|
||||
return@Column;
|
||||
@ -143,12 +151,16 @@ class RandomPostWidget : GlanceAppWidget() {
|
||||
horizontalAlignment = Alignment.Horizontal.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "Unable to fetch post",
|
||||
style = TextStyle(fontSize = 17.sp, fontWeight = FontWeight.Bold)
|
||||
text = "No Recommendations",
|
||||
style = TextStyle(
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
Text(
|
||||
text = "Check your internet connection",
|
||||
style = TextStyle(fontSize = 15.sp)
|
||||
text = "Open app to load some posts",
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 537 B |
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.5 KiB |
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#FFFFFFFF</color>
|
||||
<color name="ic_notification_background">#00000000</color>
|
||||
</resources>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<style name="LaunchTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
@ -16,7 +16,7 @@
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
@ -139,6 +139,8 @@
|
||||
"fieldPostTitle": "Title",
|
||||
"fieldPostDescription": "Description",
|
||||
"fieldPostTags": "Tags",
|
||||
"fieldPostAlias": "Alias",
|
||||
"fieldPostAliasHint": "Optional, used to represent the post in URL, should follow URL-Safe.",
|
||||
"postPublish": "Publish",
|
||||
"postPosted": "Post has been posted.",
|
||||
"postPublishedAt": "Published At",
|
||||
|
@ -123,6 +123,8 @@
|
||||
"fieldPostTitle": "标题",
|
||||
"fieldPostDescription": "描述",
|
||||
"fieldPostTags": "标签",
|
||||
"fieldPostAlias": "别名",
|
||||
"fieldPostAliasHint": "可选项,用于在 URL 中表示该帖子,应遵循 URL-Safe 的原则。",
|
||||
"postPublish": "发布",
|
||||
"postPublishedAt": "发布于",
|
||||
"postPublishedUntil": "取消发布于",
|
||||
|
@ -103,6 +103,8 @@ PODS:
|
||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||
- nanopb (~> 3.30910.0)
|
||||
- Flutter (1.0.0)
|
||||
- flutter_app_update (0.0.1):
|
||||
- Flutter
|
||||
- flutter_native_splash (2.4.3):
|
||||
- Flutter
|
||||
- flutter_udid (0.0.1):
|
||||
@ -168,6 +170,8 @@ PODS:
|
||||
- Flutter
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- in_app_review (2.0.0):
|
||||
- Flutter
|
||||
- Kingfisher (8.1.3)
|
||||
- livekit_client (2.3.2):
|
||||
- Flutter
|
||||
@ -232,12 +236,14 @@ DEPENDENCIES:
|
||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
|
||||
- flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`)
|
||||
- gal (from `.symlinks/plugins/gal/darwin`)
|
||||
- home_widget (from `.symlinks/plugins/home_widget/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
||||
- Kingfisher (~> 8.0)
|
||||
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
@ -298,6 +304,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_app_update:
|
||||
:path: ".symlinks/plugins/flutter_app_update/ios"
|
||||
flutter_native_splash:
|
||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||
flutter_udid:
|
||||
@ -310,6 +318,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/home_widget/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
in_app_review:
|
||||
:path: ".symlinks/plugins/in_app_review/ios"
|
||||
livekit_client:
|
||||
:path: ".symlinks/plugins/livekit_client/ios"
|
||||
media_kit_libs_ios_video:
|
||||
@ -364,8 +374,9 @@ SPEC CHECKSUMS:
|
||||
FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414
|
||||
FirebaseMessaging: f8a160d99c2c2e5babbbcc90c4a3e15db036aee2
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_app_update: 65f61da626cb111d1b24674abc4b01728d7723bc
|
||||
flutter_native_splash: e8a1e01082d97a8099d973f919f57904c925008a
|
||||
flutter_udid: a2482c67a61b9c806ef59dd82ed8d007f1b7ac04
|
||||
flutter_udid: b2417673f287ee62817a1de3d1643f47b9f508ab
|
||||
flutter_webrtc: 1a53bd24f97bcfeff512f13699e721897f261563
|
||||
gal: 6a522c75909f1244732d4596d11d6a2f86ff37a5
|
||||
GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e
|
||||
@ -373,6 +384,7 @@ SPEC CHECKSUMS:
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
in_app_review: a31b5257259646ea78e0e35fc914979b0031d011
|
||||
Kingfisher: f2af9028b16baf9dc6c07c570072bc41cbf009ef
|
||||
livekit_client: 6108dad8b77db3142bafd4c630f471d0a54335cd
|
||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -152,6 +153,7 @@ class PostWriteController extends ChangeNotifier {
|
||||
final TextEditingController contentController = TextEditingController();
|
||||
final TextEditingController titleController = TextEditingController();
|
||||
final TextEditingController descriptionController = TextEditingController();
|
||||
final TextEditingController aliasController = TextEditingController();
|
||||
|
||||
PostWriteController() {
|
||||
titleController.addListener(() => notifyListeners());
|
||||
@ -198,6 +200,7 @@ class PostWriteController extends ChangeNotifier {
|
||||
titleController.text = post.body['title'] ?? '';
|
||||
descriptionController.text = post.body['description'] ?? '';
|
||||
contentController.text = post.body['content'] ?? '';
|
||||
aliasController.text = post.alias ?? '';
|
||||
publishedAt = post.publishedAt;
|
||||
publishedUntil = post.publishedUntil;
|
||||
visibleUsers = List.from(post.visibleUsersList ?? []);
|
||||
@ -269,7 +272,7 @@ class PostWriteController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> post(BuildContext context) async {
|
||||
Future<void> sendPost(BuildContext context) async {
|
||||
if (isBusy || publisher == null) return;
|
||||
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
@ -305,12 +308,14 @@ class PostWriteController extends ChangeNotifier {
|
||||
place.$2,
|
||||
onProgress: (progress) {
|
||||
// Calculate overall progress for attachments
|
||||
progress = ((i + progress) / attachments.length) * kAttachmentProgressWeight;
|
||||
progress = math.max(((i + progress) / attachments.length) * kAttachmentProgressWeight, progress);
|
||||
notifyListeners();
|
||||
},
|
||||
);
|
||||
|
||||
progress = (i + 1) / attachments.length * kAttachmentProgressWeight;
|
||||
attachments[i] = PostWriteMedia(item);
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (err) {
|
||||
isBusy = false;
|
||||
@ -334,6 +339,7 @@ class PostWriteController extends ChangeNotifier {
|
||||
data: {
|
||||
'publisher': publisher!.id,
|
||||
'content': contentController.text,
|
||||
if (aliasController.text.isNotEmpty) 'alias': aliasController.text,
|
||||
if (titleController.text.isNotEmpty) 'title': titleController.text,
|
||||
if (descriptionController.text.isNotEmpty) 'description': descriptionController.text,
|
||||
if (thumbnail != null && thumbnail!.attachment != null) 'thumbnail': thumbnail!.attachment!.rid,
|
||||
|
@ -41,8 +41,7 @@ class SnAttachmentProvider {
|
||||
return out;
|
||||
}
|
||||
|
||||
Future<List<SnAttachment?>> getMultiple(List<String> rids,
|
||||
{noCache = false}) async {
|
||||
Future<List<SnAttachment?>> getMultiple(List<String> rids, {noCache = false}) async {
|
||||
final result = List<SnAttachment?>.filled(rids.length, null);
|
||||
final Map<String, int> randomMapping = {};
|
||||
for (int i = 0; i < rids.length; i++) {
|
||||
@ -63,9 +62,7 @@ class SnAttachmentProvider {
|
||||
'id': pendingFetch.join(','),
|
||||
},
|
||||
);
|
||||
final out = resp.data['data']
|
||||
.map((e) => e['id'] == 0 ? null : SnAttachment.fromJson(e))
|
||||
.toList();
|
||||
final out = resp.data['data'].map((e) => e['id'] == 0 ? null : SnAttachment.fromJson(e)).toList();
|
||||
|
||||
for (final item in out) {
|
||||
if (item == null) continue;
|
||||
@ -79,10 +76,7 @@ class SnAttachmentProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
static Map<String, String> mimetypeOverrides = {
|
||||
'mov': 'video/quicktime',
|
||||
'mp4': 'video/mp4'
|
||||
};
|
||||
static Map<String, String> mimetypeOverrides = {'mov': 'video/quicktime', 'mp4': 'video/mp4'};
|
||||
|
||||
Future<SnAttachment> directUploadOne(
|
||||
Uint8List data,
|
||||
@ -93,11 +87,8 @@ class SnAttachmentProvider {
|
||||
Function(double progress)? onProgress,
|
||||
}) async {
|
||||
final filePayload = MultipartFile.fromBytes(data, filename: filename);
|
||||
final fileAlt = filename.contains('.')
|
||||
? filename.substring(0, filename.lastIndexOf('.'))
|
||||
: filename;
|
||||
final fileExt =
|
||||
filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
|
||||
final fileAlt = filename.contains('.') ? filename.substring(0, filename.lastIndexOf('.')) : filename;
|
||||
final fileExt = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
|
||||
|
||||
String? mimetypeOverride;
|
||||
if (mimetype != null) {
|
||||
@ -133,11 +124,8 @@ class SnAttachmentProvider {
|
||||
Map<String, dynamic>? metadata, {
|
||||
String? mimetype,
|
||||
}) async {
|
||||
final fileAlt = filename.contains('.')
|
||||
? filename.substring(0, filename.lastIndexOf('.'))
|
||||
: filename;
|
||||
final fileExt =
|
||||
filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
|
||||
final fileAlt = filename.contains('.') ? filename.substring(0, filename.lastIndexOf('.')) : filename;
|
||||
final fileExt = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
|
||||
|
||||
String? mimetypeOverride;
|
||||
if (mimetype == null && mimetypeOverrides.keys.contains(fileExt)) {
|
||||
@ -155,10 +143,7 @@ class SnAttachmentProvider {
|
||||
if (mimetypeOverride != null) 'mimetype': mimetypeOverride,
|
||||
});
|
||||
|
||||
return (
|
||||
SnAttachment.fromJson(resp.data['meta']),
|
||||
resp.data['chunk_size'] as int
|
||||
);
|
||||
return (SnAttachment.fromJson(resp.data['meta']), resp.data['chunk_size'] as int);
|
||||
}
|
||||
|
||||
Future<SnAttachment> _chunkedUploadOnePart(
|
||||
@ -200,24 +185,17 @@ class SnAttachmentProvider {
|
||||
(entry.value + 1) * chunkSize,
|
||||
await file.length(),
|
||||
);
|
||||
final data = Uint8List.fromList(await file
|
||||
.openRead(beginCursor, endCursor)
|
||||
.expand((chunk) => chunk)
|
||||
.toList());
|
||||
final data = Uint8List.fromList(await file.openRead(beginCursor, endCursor).expand((chunk) => chunk).toList());
|
||||
|
||||
place = await _chunkedUploadOnePart(
|
||||
data,
|
||||
place.rid,
|
||||
entry.key,
|
||||
onProgress: (chunkProgress) {
|
||||
final overallProgress =
|
||||
(currentTask + chunkProgress) / chunks.length;
|
||||
if (onProgress != null) {
|
||||
onProgress(overallProgress);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
final overallProgress = currentTask / chunks.length;
|
||||
onProgress?.call(overallProgress);
|
||||
|
||||
currentTask++;
|
||||
}());
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ class _HomeDashUpdateWidget extends StatelessWidget {
|
||||
final model = UpdateModel(
|
||||
'https://files.solsynth.dev/d/production01/solian/app-arm64-v8a-release.apk',
|
||||
'solian-app-release-${config.updatableVersion!}.apk',
|
||||
'ic_notification',
|
||||
'ic_launcher',
|
||||
'https://apps.apple.com/us/app/solian/id6499032345',
|
||||
);
|
||||
AzhonAppUpdate.update(model);
|
||||
|
@ -13,6 +13,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:pasteboard/pasteboard.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/controllers/post_write_controller.dart';
|
||||
import 'package:surface/providers/config.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/types/post.dart';
|
||||
import 'package:surface/widgets/account/account_image.dart';
|
||||
@ -71,11 +72,14 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
||||
|
||||
try {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final config = context.read<ConfigProvider>();
|
||||
final resp = await sn.client.get('/cgi/co/publishers/me');
|
||||
_publishers = List<SnPublisher>.from(
|
||||
resp.data?.map((e) => SnPublisher.fromJson(e)) ?? [],
|
||||
);
|
||||
_writeController.setPublisher(_publishers?.firstOrNull);
|
||||
final beforeId = config.prefs.getInt('int_last_publisher_id');
|
||||
_writeController
|
||||
.setPublisher(_publishers?.where((ele) => ele.id == beforeId).firstOrNull ?? _publishers?.firstOrNull);
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
context.showErrorDialog(err);
|
||||
@ -265,6 +269,8 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
||||
});
|
||||
} else {
|
||||
_writeController.setPublisher(value);
|
||||
final config = context.read<ConfigProvider>();
|
||||
config.prefs.setInt('int_last_publisher_id', value.id);
|
||||
}
|
||||
},
|
||||
buttonStyleData: const ButtonStyleData(
|
||||
@ -496,7 +502,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
||||
onPressed: (_writeController.isBusy || _writeController.publisher == null)
|
||||
? null
|
||||
: () {
|
||||
_writeController.post(context).then((_) {
|
||||
_writeController.sendPost(context).then((_) {
|
||||
if (!context.mounted) return;
|
||||
Navigator.pop(context, true);
|
||||
});
|
||||
|
@ -17,6 +17,8 @@ import 'package:responsive_framework/responsive_framework.dart';
|
||||
import 'package:screenshot/screenshot.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/providers/config.dart';
|
||||
import 'package:surface/providers/link_preview.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/providers/userinfo.dart';
|
||||
import 'package:surface/types/post.dart';
|
||||
@ -83,6 +85,8 @@ class PostItem extends StatelessWidget {
|
||||
child: MultiProvider(
|
||||
providers: [
|
||||
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
||||
Provider<SnLinkPreviewProvider>(create: (_) => context.read()),
|
||||
ChangeNotifierProvider<ConfigProvider>(create: (_) => context.read()),
|
||||
],
|
||||
child: ResponsiveBreakpoints.builder(
|
||||
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
||||
@ -410,7 +414,7 @@ class PostShareImageWidget extends StatelessWidget {
|
||||
size: Size(28, 28),
|
||||
),
|
||||
eyeStyle: QrEyeStyle(
|
||||
eyeShape: QrEyeShape.square,
|
||||
eyeShape: QrEyeShape.circle,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
dataModuleStyle: QrDataModuleStyle(
|
||||
|
@ -189,16 +189,19 @@ class PostMediaPendingList extends StatelessWidget {
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: switch (thumbnail!.type) {
|
||||
PostWriteMediaType.image => LayoutBuilder(builder: (context, constraints) {
|
||||
return Image(
|
||||
image: thumbnail!.getImageProvider(
|
||||
context,
|
||||
width: (constraints.maxWidth * devicePixelRatio).round(),
|
||||
height: (constraints.maxHeight * devicePixelRatio).round(),
|
||||
)!,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
}),
|
||||
PostWriteMediaType.image => Container(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
child: LayoutBuilder(builder: (context, constraints) {
|
||||
return Image(
|
||||
image: thumbnail!.getImageProvider(
|
||||
context,
|
||||
width: (constraints.maxWidth * devicePixelRatio).round(),
|
||||
height: (constraints.maxHeight * devicePixelRatio).round(),
|
||||
)!,
|
||||
fit: BoxFit.contain,
|
||||
);
|
||||
}),
|
||||
),
|
||||
_ => Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: const Icon(Symbols.docs).center(),
|
||||
@ -236,18 +239,21 @@ class PostMediaPendingList extends StatelessWidget {
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: switch (media.type) {
|
||||
PostWriteMediaType.image => LayoutBuilder(builder: (context, constraints) {
|
||||
return Image(
|
||||
image: media.getImageProvider(
|
||||
context,
|
||||
width: (constraints.maxWidth * devicePixelRatio).round(),
|
||||
height: (constraints.maxHeight * devicePixelRatio).round(),
|
||||
)!,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
}),
|
||||
PostWriteMediaType.image => Container(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
child: LayoutBuilder(builder: (context, constraints) {
|
||||
return Image(
|
||||
image: media.getImageProvider(
|
||||
context,
|
||||
width: (constraints.maxWidth * devicePixelRatio).round(),
|
||||
height: (constraints.maxHeight * devicePixelRatio).round(),
|
||||
)!,
|
||||
fit: BoxFit.contain,
|
||||
);
|
||||
}),
|
||||
),
|
||||
_ => Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
child: const Icon(Symbols.docs).center(),
|
||||
),
|
||||
},
|
||||
|
@ -114,6 +114,18 @@ class PostMetaEditor extends StatelessWidget {
|
||||
controller.setTags(value);
|
||||
},
|
||||
).padding(horizontal: 24),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: controller.aliasController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'fieldPostAlias'.tr(),
|
||||
helperText: 'fieldPostAliasHint'.tr(),
|
||||
helperMaxLines: 2,
|
||||
border: UnderlineInputBorder(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
).padding(horizontal: 24),
|
||||
const Gap(12),
|
||||
ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
|
@ -7,6 +7,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/controllers/post_write_controller.dart';
|
||||
import 'package:surface/providers/config.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/types/post.dart';
|
||||
import 'package:surface/widgets/account/account_image.dart';
|
||||
@ -16,6 +17,7 @@ import 'package:surface/widgets/loading_indicator.dart';
|
||||
class PostMiniEditor extends StatefulWidget {
|
||||
final int? postReplyId;
|
||||
final Function? onPost;
|
||||
|
||||
const PostMiniEditor({super.key, this.postReplyId, this.onPost});
|
||||
|
||||
@override
|
||||
@ -26,6 +28,7 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
final PostWriteController _writeController = PostWriteController();
|
||||
|
||||
bool _isFetching = false;
|
||||
|
||||
bool get _isLoading => _isFetching || _writeController.isLoading;
|
||||
|
||||
List<SnPublisher>? _publishers;
|
||||
@ -35,11 +38,14 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
|
||||
try {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final config = context.read<ConfigProvider>();
|
||||
final resp = await sn.client.get('/cgi/co/publishers/me');
|
||||
_publishers = List<SnPublisher>.from(
|
||||
resp.data?.map((e) => SnPublisher.fromJson(e)) ?? [],
|
||||
);
|
||||
_writeController.setPublisher(_publishers?.firstOrNull);
|
||||
final beforeId = config.prefs.getInt('int_last_publisher_id');
|
||||
_writeController
|
||||
.setPublisher(_publishers?.where((ele) => ele.id == beforeId).firstOrNull ?? _publishers?.firstOrNull);
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
context.showErrorDialog(err);
|
||||
@ -93,17 +99,11 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(item.nick).textStyle(
|
||||
Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!),
|
||||
Text(item.nick).textStyle(Theme.of(context).textTheme.bodyMedium!),
|
||||
Text('@${item.name}')
|
||||
.textStyle(Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!)
|
||||
.textStyle(Theme.of(context).textTheme.bodySmall!)
|
||||
.fontSize(12),
|
||||
],
|
||||
),
|
||||
@ -120,8 +120,7 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
CircleAvatar(
|
||||
radius: 16,
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.onSurface,
|
||||
foregroundColor: Theme.of(context).colorScheme.onSurface,
|
||||
child: const Icon(Symbols.add),
|
||||
),
|
||||
const Gap(8),
|
||||
@ -130,8 +129,7 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('publishersNew').tr().textStyle(
|
||||
Theme.of(context).textTheme.bodyMedium!),
|
||||
Text('publishersNew').tr().textStyle(Theme.of(context).textTheme.bodyMedium!),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -142,9 +140,7 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
value: _writeController.publisher,
|
||||
onChanged: (SnPublisher? value) {
|
||||
if (value == null) {
|
||||
GoRouter.of(context)
|
||||
.pushNamed('accountPublisherNew')
|
||||
.then((value) {
|
||||
GoRouter.of(context).pushNamed('accountPublisherNew').then((value) {
|
||||
if (value == true) {
|
||||
_publishers = null;
|
||||
_fetchPublishers();
|
||||
@ -152,6 +148,8 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
});
|
||||
} else {
|
||||
_writeController.setPublisher(value);
|
||||
final config = context.read<ConfigProvider>();
|
||||
config.prefs.setInt('int_last_publisher_id', value.id);
|
||||
}
|
||||
},
|
||||
buttonStyleData: const ButtonStyleData(
|
||||
@ -178,8 +176,7 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
@ -188,8 +185,7 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 0, end: _writeController.progress),
|
||||
duration: Duration(milliseconds: 300),
|
||||
builder: (context, value, _) =>
|
||||
LinearProgressIndicator(value: value, minHeight: 2),
|
||||
builder: (context, value, _) => LinearProgressIndicator(value: value, minHeight: 2),
|
||||
)
|
||||
else if (_writeController.isBusy)
|
||||
const LinearProgressIndicator(value: null, minHeight: 2),
|
||||
@ -206,18 +202,16 @@ class _PostMiniEditorState extends State<PostMiniEditor> {
|
||||
'postEditor',
|
||||
pathParameters: {'mode': 'stories'},
|
||||
queryParameters: {
|
||||
if (widget.postReplyId != null)
|
||||
'replying': widget.postReplyId.toString(),
|
||||
if (widget.postReplyId != null) 'replying': widget.postReplyId.toString(),
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: (_writeController.isBusy ||
|
||||
_writeController.publisher == null)
|
||||
onPressed: (_writeController.isBusy || _writeController.publisher == null)
|
||||
? null
|
||||
: () {
|
||||
_writeController.post(context).then((_) {
|
||||
_writeController.sendPost(context).then((_) {
|
||||
if (!context.mounted) return;
|
||||
if (widget.onPost != null) widget.onPost!();
|
||||
context.showSnackbar('postPosted'.tr());
|
||||
|
@ -132,6 +132,8 @@ PODS:
|
||||
- GoogleUtilities/UserDefaults (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- in_app_review (2.0.0):
|
||||
- FlutterMacOS
|
||||
- livekit_client (2.3.2):
|
||||
- flutter_webrtc
|
||||
- FlutterMacOS
|
||||
@ -186,6 +188,7 @@ DEPENDENCIES:
|
||||
- flutter_webrtc (from `Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`)
|
||||
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
|
||||
- livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`)
|
||||
- media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`)
|
||||
- media_kit_native_event_loop (from `Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos`)
|
||||
@ -243,6 +246,8 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral
|
||||
gal:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/gal/darwin
|
||||
in_app_review:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
|
||||
livekit_client:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos
|
||||
media_kit_libs_macos_video:
|
||||
@ -286,13 +291,14 @@ SPEC CHECKSUMS:
|
||||
FirebaseCoreInternal: d98ab91e2d80a56d7b246856a8885443b302c0c2
|
||||
FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414
|
||||
FirebaseMessaging: f8a160d99c2c2e5babbbcc90c4a3e15db036aee2
|
||||
flutter_udid: 6b2b89780c3dfeecf0047bdf93f622d6416b1c07
|
||||
flutter_udid: 2e7b3da4b5fdfba86a396b97898f5fe8f4ec1a52
|
||||
flutter_webrtc: 53c9e1285ab32dfb58afb1e1471416a877e23d7a
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
gal: 6a522c75909f1244732d4596d11d6a2f86ff37a5
|
||||
GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
in_app_review: a6a031b9acd03c7d103e341aa334adf2c493fb93
|
||||
livekit_client: 9fdcb22df3de55e6d4b24bdc3b5eb1c0269d774a
|
||||
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
||||
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
||||
|
@ -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
|
||||
# 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.
|
||||
version: 2.1.1+35
|
||||
version: 2.1.1+37
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.4
|
||||
|