Compare commits

...

6 Commits

Author SHA1 Message Date
LittleSheep
a3aa694076 🔀 Merge pull request #20 from Texas0295/master
🐛 change -Werror to -Wextra
2025-04-11 00:37:42 +08:00
Texas0295
e98ee562ef 🐛 change -Werror to -Wextra 2025-04-10 20:12:18 +08:00
63ff6df93a 🐛 Fix android build failed 2025-04-07 23:59:38 +08:00
f95eadd3e6 🐛 Fix bugs 2025-04-07 20:56:34 +08:00
9a8e40b288 🚀 Launch 2.5.2+92 2025-04-07 00:53:30 +08:00
cb0986efee 🐛 Bug fixes on live stream post 2025-04-07 00:49:43 +08:00
14 changed files with 141 additions and 48 deletions

2
android/.gitignore vendored
View File

@@ -11,3 +11,5 @@ GeneratedPluginRegistrant.java
key.properties key.properties
**/*.keystore **/*.keystore
**/*.jks **/*.jks
app/.cxx

View File

@@ -10,10 +10,15 @@ plugins {
} }
dependencies { dependencies {
// implementation('org.jitsi.react:jitsi-meet-sdk:11.1.1') { transitive = true }
// implementation 'com.facebook.fresco:webpsupport:2.6.0'
// implementation 'com.facebook.fresco:animated-webp:2.6.0'
// implementation 'com.facebook.react:react-android:0.75.5'
// implementation 'com.facebook.react:hermes-android:0.75.5'
implementation 'com.google.android.material:material:1.12.0' implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.glance:glance:1.1.1' implementation 'androidx.glance:glance:1.1.1'
implementation 'androidx.glance:glance-appwidget:1.1.1' implementation 'androidx.glance:glance-appwidget:1.1.1'
implementation 'androidx.compose.foundation:foundation-layout-android:1.7.6' implementation 'androidx.compose.foundation:foundation-layout-android:1.7.8'
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.squareup.okhttp3:okhttp:4.12.0' implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'io.coil-kt.coil3:coil-compose:3.0.4' implementation 'io.coil-kt.coil3:coil-compose:3.0.4'
@@ -73,8 +78,10 @@ android {
} }
release { release {
signingConfig = signingConfigs.release signingConfig = signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
} }
} }

96
android/app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,96 @@
-keepclassmembers class kotlin.Metadata { *; }
-keep class dev.solsynth.solian.** { *; }
-keep public class dev.solsynth.solian.data.** { public *; }
-keepclassmembers class dev.solsynth.solian.data.** { *; }
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes EnclosingMethod
-keep class com.google.gson.** { *; }
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-dontwarn com.facebook.imagepipeline.nativecode.WebpTranscoder
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.proguard.annotations.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.proguard.annotations.DoNotStrip *;
}
-keep @com.facebook.proguard.annotations.DoNotStripAny class * {
*;
}
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
void set*(***);
*** get*();
}
-keep class * implements com.facebook.react.bridge.JavaScriptModule { *; }
-keep class * implements com.facebook.react.bridge.NativeModule { *; }
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
-dontwarn com.facebook.react.**
-keep,includedescriptorclasses class com.facebook.react.bridge.** { *; }
-keep,includedescriptorclasses class com.facebook.react.turbomodule.core.** { *; }
# hermes
-keep class com.facebook.jni.** { *; }
# okio
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
# yoga
-keep,allowobfuscation @interface com.facebook.yoga.annotations.DoNotStrip
-keep @com.facebook.yoga.annotations.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.yoga.annotations.DoNotStrip *;
}
# WebRTC
-keep class org.webrtc.** { *; }
-dontwarn org.chromium.build.BuildHooksAndroid
# Jisti Meet SDK
-keep class org.jitsi.meet.** { *; }
-keep class org.jitsi.meet.sdk.** { *; }
# We added the following when we switched minifyEnabled on. Probably because we
# ran the app and hit problems...
-keep class com.facebook.react.bridge.CatalystInstanceImpl { *; }
-keep class com.facebook.react.bridge.ExecutorToken { *; }
-keep class com.facebook.react.bridge.JavaScriptExecutor { *; }
-keep class com.facebook.react.bridge.ModuleRegistryHolder { *; }
-keep class com.facebook.react.bridge.ReadableType { *; }
-keep class com.facebook.react.bridge.queue.NativeRunnable { *; }
-keep class com.facebook.react.devsupport.** { *; }
-dontwarn com.facebook.react.devsupport.**
-dontwarn com.google.appengine.**
-dontwarn com.squareup.okhttp.**
-dontwarn javax.servlet.**
# ^^^ We added the above when we switched minifyEnabled on.
# Rule to avoid build errors related to SVGs.
-keep public class com.horcrux.svg.** {*;}
# https://github.com/facebook/fresco/issues/2638
-keep public class com.facebook.imageutils.** {
public *;
}

View File

@@ -1,4 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" /> <uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />

View File

@@ -1,14 +0,0 @@
-keepclassmembers class kotlin.Metadata { *; }
-keep class dev.solsynth.solian.** { *; }
-keep public class dev.solsynth.solian.data.** { public *; }
-keepclassmembers class dev.solsynth.solian.data.** { *; }
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes EnclosingMethod
-keep class com.google.gson.** { *; }
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip

View File

@@ -10,18 +10,22 @@ pluginManagement {
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories { repositories {
maven {
url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases"
}
google() google()
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
maven { url 'https://www.jitpack.io' }
} }
} }
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.7.3' apply false id "com.android.application" version '8.9.1' apply false
// START: FlutterFire Configuration // START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false id "com.google.gms.google-services" version "4.4.2" apply false
id "com.google.firebase.crashlytics" version "2.8.1" apply false id "com.google.firebase.crashlytics" version "3.0.3" apply false
// END: FlutterFire Configuration // END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "1.8.22" apply false id "org.jetbrains.kotlin.android" version "1.8.22" apply false
} }

View File

@@ -964,6 +964,6 @@
"postVideoLiveDescription": "This is a live video, you can embed the source site by yourself.", "postVideoLiveDescription": "This is a live video, you can embed the source site by yourself.",
"postVideoRendererWeb": "WebView Rendering", "postVideoRendererWeb": "WebView Rendering",
"postVideoRendererWebDescription": "Use WebView to render the content", "postVideoRendererWebDescription": "Use WebView to render the content",
"fieldPostVideoStreamUrl": "Live Stream URL", "fieldPostVideoUrl": "Video URL",
"fieldPostVideoStreamUrlDescription": "Live stream URL, can be HLS or webpage; use webpage renderer if you want to embed the webpage." "fieldPostVideoUrlDescription": "The URL of the video content, it can be a webpage, and will be rendered by iFrame / WebView."
} }

View File

@@ -961,6 +961,6 @@
"postVideoLiveDescription": "这是一条直播影片,允许用户自行嵌入源站。", "postVideoLiveDescription": "这是一条直播影片,允许用户自行嵌入源站。",
"postVideoRendererWeb": "网页渲染器", "postVideoRendererWeb": "网页渲染器",
"postVideoRendererWebDescription": "使用 WebView 渲染内容。", "postVideoRendererWebDescription": "使用 WebView 渲染内容。",
"fieldPostVideoStreamUrl": "直播流地址", "fieldPostVideoUrl": "视频流地址",
"fieldPostVideoStreamUrlDescription": "直播流地址,可以为 HLS或者网页使用网页嵌入请启用网页渲染。" "fieldPostVideoUrlDescription": "视频内容的地址,可以为网页,将会使用 iFrame / WebView 渲染。"
} }

View File

@@ -243,9 +243,13 @@ class PostWriteController extends ChangeNotifier {
contentController.text = post.body['content'] ?? ''; contentController.text = post.body['content'] ?? '';
aliasController.text = post.alias ?? ''; aliasController.text = post.alias ?? '';
rewardController.text = post.body['reward']?.toString() ?? ''; rewardController.text = post.body['reward']?.toString() ?? '';
videoAttachment = post.body['video'] != null if (post.body['video'] != null) {
? SnAttachment.fromJson(post.body['video']) if (post.body['video'] is String) {
: null; videoUrl = post.body['video'];
} else {
videoAttachment = SnAttachment.fromJson(post.body['video']);
}
}
publishedAt = post.publishedAt; publishedAt = post.publishedAt;
publishedUntil = post.publishedUntil; publishedUntil = post.publishedUntil;
visibleUsers = List.from(post.visibleUsersList ?? [], growable: true); visibleUsers = List.from(post.visibleUsersList ?? [], growable: true);
@@ -264,6 +268,7 @@ class PostWriteController extends ChangeNotifier {
); );
poll = post.poll; poll = post.poll;
videoLive = post.body['is_live'] ?? false;
editingDraft = post.isDraft; editingDraft = post.isDraft;
if (post.body['thumbnail'] != null) { if (post.body['thumbnail'] != null) {
@@ -604,6 +609,7 @@ class PostWriteController extends ChangeNotifier {
'video': videoUrl.isNotEmpty ? videoUrl : videoAttachment!.rid, 'video': videoUrl.isNotEmpty ? videoUrl : videoAttachment!.rid,
if (poll != null) 'poll': poll!.id, if (poll != null) 'poll': poll!.id,
if (realm != null) 'realm': realm!.id, if (realm != null) 'realm': realm!.id,
if (videoLive) 'is_live': videoLive,
'is_draft': saveAsDraft, 'is_draft': saveAsDraft,
}, },
onSendProgress: (count, total) { onSendProgress: (count, total) {
@@ -746,6 +752,7 @@ class PostWriteController extends ChangeNotifier {
void setVideoUrl(String value) { void setVideoUrl(String value) {
videoUrl = value; videoUrl = value;
notifyListeners();
} }
void setVideoLive(bool value) { void setVideoLive(bool value) {

View File

@@ -1118,8 +1118,6 @@ class _PostVideoEditor extends StatefulWidget {
} }
class _PostVideoEditorState extends State<_PostVideoEditor> { class _PostVideoEditorState extends State<_PostVideoEditor> {
String? _renderer;
final TextEditingController _streamUrlController = TextEditingController(); final TextEditingController _streamUrlController = TextEditingController();
void _selectVideo() async { void _selectVideo() async {
@@ -1221,19 +1219,21 @@ class _PostVideoEditorState extends State<_PostVideoEditor> {
FocusManager.instance.primaryFocus?.unfocus(), FocusManager.instance.primaryFocus?.unfocus(),
).padding(horizontal: 16), ).padding(horizontal: 16),
const Gap(12), const Gap(12),
if (widget.controller.videoLive) if (widget.controller.videoLive ||
widget.controller.videoAttachment == null)
TextField( TextField(
controller: _streamUrlController, controller: _streamUrlController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'fieldPostVideoStreamUrl'.tr(), labelText: 'fieldPostVideoUrl'.tr(),
helperText: 'fieldPostVideoStreamUrlDescription'.tr(), helperText: 'fieldPostVideoUrlDescription'.tr(),
border: OutlineInputBorder(), border: OutlineInputBorder(),
isDense: true, isDense: true,
), ),
onTapOutside: (_) => onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(), FocusManager.instance.primaryFocus?.unfocus(),
).padding(horizontal: 12) ).padding(horizontal: 16, bottom: 12, top: 2),
else if (!widget.controller.videoLive &&
_streamUrlController.text.isEmpty)
Container( Container(
margin: const EdgeInsets.only(left: 16, right: 16), margin: const EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -1296,15 +1296,6 @@ class _PostVideoEditorState extends State<_PostVideoEditor> {
onChanged: (value) => onChanged: (value) =>
widget.controller.setVideoLive(value ?? false), widget.controller.setVideoLive(value ?? false),
), ),
CheckboxListTile(
secondary: const Icon(Symbols.web),
title: Text('postVideoRendererWeb').tr(),
subtitle: Text('postVideoRendererWebDescription').tr(),
value: _renderer == 'web',
onChanged: (value) => setState(
() => _renderer = (value ?? false) ? 'web' : null,
),
),
], ],
), ),
), ),

View File

@@ -232,7 +232,7 @@ class _UserNameCardInlineSyntax extends markdown.InlineSyntax {
final alias = match[0]!; final alias = match[0]!;
final anchor = markdown.Element.text('a', alias) final anchor = markdown.Element.text('a', alias)
..attributes['href'] = Uri.encodeFull( ..attributes['href'] = Uri.encodeFull(
'solink://account/${alias.substring(1)}', 'solink://accounts/${alias.substring(1)}',
); );
parser.addNode(anchor); parser.addNode(anchor);

View File

@@ -41,7 +41,7 @@ endif()
# of modifying this function. # of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET) function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE -Wall -Wextra)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>") target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>") target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction() endfunction()

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 2.5.2+91 version: 2.5.2+92
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4