Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
1ad42e6505 | |||
1cec1bf82e | |||
a4ecf30c5b | |||
5da7ccc8ef | |||
b5f42863ce | |||
69d5e95565 | |||
3e3442fc89 | |||
8181010b0b | |||
269caf7555 | |||
ae0809ad35 | |||
4005f03cf8 | |||
4bd8ec54f1 | |||
51a387851f | |||
8ed847d870 | |||
dfe13de220 | |||
b02a54c1e9 | |||
55a7e7d900 | |||
3585941ccb | |||
7c6f2cc4ab | |||
61dbf92909 | |||
b69e4002e0 | |||
49aa24b79d | |||
ddd0a4c3d3 | |||
99e07de243 | |||
10bf0883e5 |
16
.github/workflows/nightly.yml
vendored
16
.github/workflows/nightly.yml
vendored
@ -48,7 +48,6 @@ jobs:
|
|||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: stable
|
channel: stable
|
||||||
cache: true
|
|
||||||
- run: |
|
- run: |
|
||||||
sudo apt-get update -y
|
sudo apt-get update -y
|
||||||
sudo apt-get install -y ninja-build libgtk-3-dev
|
sudo apt-get install -y ninja-build libgtk-3-dev
|
||||||
@ -65,3 +64,18 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: build-output-linux
|
name: build-output-linux
|
||||||
path: build/linux/x64/release/bundle
|
path: build/linux/x64/release/bundle
|
||||||
|
- name: Build AppImage
|
||||||
|
run: |
|
||||||
|
rm -r Solian.AppDir | true
|
||||||
|
mkdir Solian.AppDir
|
||||||
|
cp -r build/linux/x64/release/bundle/* Solian.AppDir
|
||||||
|
cp -r buildtools/appimage_config/* Solian.AppDir
|
||||||
|
cp assets/icon/icon-light-radius.png Solian.AppDir
|
||||||
|
sudo chmod +x buildtools/appimagetool-x86_64.AppImage
|
||||||
|
sudo chmod +x Solian.AppDir/AppRun
|
||||||
|
./buildtools/appimagetool-x86_64.AppImage Solian.AppDir
|
||||||
|
- name: Archive production artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-output-linux-appimage
|
||||||
|
path: './*.AppImage*'
|
||||||
|
34
CODE_OF_CONDUCT.md
Normal file
34
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
Welcome to the Solar Network / HyperNet project!
|
||||||
|
|
||||||
|
We're welcome for any contribution, from bug reports to feature requests to code contributions.
|
||||||
|
|
||||||
|
To get started, start from fork the repository.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
The current repository you're visiting is the front-end project for the Solar Network project. It's built by Flutter and also manages all feature requests and issues reports in this repository.
|
||||||
|
|
||||||
|
The backend of the Solar Network is written in Go and is a microservices app. The code is stored separately in different repositories. They're linked in the README.MD, you can have a look and try to contribute if you want.
|
||||||
|
|
||||||
|
## Commit Messages
|
||||||
|
|
||||||
|
We're using the gitmoji to clarify the reason and changes of the commit. To learn more about gitmoji, visit https://gitmoji.dev
|
||||||
|
|
||||||
|
## Translations & Localization
|
||||||
|
|
||||||
|
We're not accepting translation and localization improvements, or fixes on the GitHub or Solsynth Git Repository. If you want to contribute to those, please head to our Weblate: https://i18n.solsynth.dev. You will able to sign up / in via your Solar Network Account (Solarpass)
|
||||||
|
|
||||||
|
## New Features
|
||||||
|
|
||||||
|
To contribute new features, please create an issue or mention the feature you want in our official development chat channel. You should discuss the feature with us and the community first. You shouldn't just create a Pull Request for the feature you want, it will not be merged.
|
||||||
|
|
||||||
|
## Bug Reports / Ask for help
|
||||||
|
|
||||||
|
Read the error message, check for the update (including pre-releases), and wiki before creating an issue. At the same time, be respectful and don't argue with our developers and contributors in the development chat or GitHub issue. Otherwise your issue may got deleted and your Solar Network Account may got a strike.
|
||||||
|
|
||||||
|
-----------
|
||||||
|
|
||||||
|
We appreciate every single commit you contributed. Let's work together and create a better Solar Network!
|
||||||
|
|
51
README.md
51
README.md
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Hello there! Welcome to the main repository of the HyperNet (also known as the Solar Network). The code here is mainly about the frontend app (also known as Solian). But you can still post issues here to get help and request new features!
|
Hello there! Welcome to the main repository of the HyperNet (also known as the Solar Network). The code here is mainly about the front-end app (also known as Solian). But you can still post issues here to get help and request new features!
|
||||||
|
|
||||||
## Sub Projects
|
## Sub Projects
|
||||||
|
|
||||||
@ -14,14 +14,55 @@ HyperNet, the Solar Network is a microservices project in which the backends are
|
|||||||
- The Messaging Service: [Messaging](https://github.com/Solsynth/HyperNet.Messaging)
|
- The Messaging Service: [Messaging](https://github.com/Solsynth/HyperNet.Messaging)
|
||||||
- The Wallet Service: [Wallet](https://github.com/Solsynth/HyperNet.Wallet)
|
- The Wallet Service: [Wallet](https://github.com/Solsynth/HyperNet.Wallet)
|
||||||
- The Crawler: [Reader](https://github.com/Solsynth/HyperNet.Reader)
|
- The Crawler: [Reader](https://github.com/Solsynth/HyperNet.Reader)
|
||||||
- Some others may not be listed, you can search in the organization with `HyperNet.` the prefix of all HyperNet projects.
|
- The Attachments Service: [Paperclip](https://github.com/Solsynth/HyperNet.Paperclip)
|
||||||
|
- Some others may not be listed, you can search in the organization with `HyperNet.` It's the prefix of all HyperNet projects.
|
||||||
|
|
||||||
## Tech Stack
|
## Tech Stack
|
||||||
|
|
||||||
For those people who want to know the tech stack of this project, the frontend was built by Flutter, which provides the cross-platform ability.
|
For those people who want to know the tech stack of this project, the front-end was built by Flutter, which provides cross-platform ability.
|
||||||
|
|
||||||
The backend was built in Go and PostgreSQL with our very own microservice framework included in the nexus.
|
The backend was built in Go and PostgreSQL with our very own microservice framework included in the nexus.
|
||||||
|
|
||||||
-----
|
If you want to contribute to the project, learn more about the [Code of Conduct](./CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
The content below will lead you to the world of Solar Network.
|
||||||
|
|
||||||
|
### For Normal Users
|
||||||
|
|
||||||
|
1. Go to the Github Releases page, and download the latest release / pre-release according to your platform.
|
||||||
|
- **What's the difference between stable and pre-release?** The pre-release is untested by the other users and includes the new cutting-edge features, usually the pre-release is the feature drop. At the same time, due to we're not doing the API versioning, some breaking changes may break the stable release, so use the pre-release one instead.
|
||||||
|
2. Create an account on the Solar Network
|
||||||
|
3. Go to your email inbox to confirm your registration
|
||||||
|
4. Start exploring!
|
||||||
|
|
||||||
|
### For Developers
|
||||||
|
|
||||||
|
To make the Solar Network App run in debug mode on your machine, you need to install the flutter development environment, for more environments, head to https://flutter.dev.
|
||||||
|
|
||||||
|
For the Linux platform, you need to install those extra development libs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y ninja-build libgtk-3-dev
|
||||||
|
sudo apt-get install -y libmpv-dev mpv
|
||||||
|
sudo apt-get install -y libayatana-appindicator3-dev
|
||||||
|
sudo apt-get install -y keybinder-3.0
|
||||||
|
sudo apt-get install -y libnotify-dev
|
||||||
|
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
|
||||||
|
sudo apt-get install -y gstreamer-1.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, use the flutter run for the app running in debug mode.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flutter pub get
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to build the release version, use the flutter build command. Learn more from the flutter docs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flutter build <platform>
|
||||||
|
```
|
||||||
|
|
||||||
The readme will be updated in the future, to be determined. For now, you can check out the link of this repository to learn more on our official website.
|
|
19
api/Passport/Give Punishment.bru
Normal file
19
api/Passport/Give Punishment.bru
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
meta {
|
||||||
|
name: Give Punishment
|
||||||
|
type: http
|
||||||
|
seq: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{endpoint}}/cgi/id/punishments
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"reason": "侮辱 Solar Network 商标,煽动颠覆中华羊国政权,制造不实信息,传播谣言,制造恐慌,寻衅滋事。",
|
||||||
|
"type": 0,
|
||||||
|
"account_id": 5
|
||||||
|
}
|
||||||
|
}
|
@ -941,5 +941,12 @@
|
|||||||
"settingsResetMemorizedWindowSize": "Reset Window Size",
|
"settingsResetMemorizedWindowSize": "Reset Window Size",
|
||||||
"settingsResetMemorizedWindowSizeDescription": "Reset the memorized window size, and set it to the default size.",
|
"settingsResetMemorizedWindowSizeDescription": "Reset the memorized window size, and set it to the default size.",
|
||||||
"chatDirect": "Direct Messages",
|
"chatDirect": "Direct Messages",
|
||||||
"back": "返回"
|
"back": "Back",
|
||||||
|
"badgeProgramDeveloper": "Developer Program Member",
|
||||||
|
"badgeProgramStellar": "A Stellar",
|
||||||
|
"badgeProgramModerator": "Community Moderator",
|
||||||
|
"postEditedHint": "edited",
|
||||||
|
"splashScreenServer": "Server",
|
||||||
|
"splashScreenServerName": "Potato",
|
||||||
|
"splashScreenCaption": "Trying to establishing connection with HyperNet™"
|
||||||
}
|
}
|
||||||
|
@ -938,5 +938,12 @@
|
|||||||
"settingsResetMemorizedWindowSize": "重置窗口大小",
|
"settingsResetMemorizedWindowSize": "重置窗口大小",
|
||||||
"settingsResetMemorizedWindowSizeDescription": "重置记忆的窗口大小,以重新设置为默认大小。",
|
"settingsResetMemorizedWindowSizeDescription": "重置记忆的窗口大小,以重新设置为默认大小。",
|
||||||
"chatDirect": "私信",
|
"chatDirect": "私信",
|
||||||
"back": "返回"
|
"back": "返回",
|
||||||
|
"badgeProgramDeveloper": "开发者计划成员",
|
||||||
|
"badgeProgramStellar": "一颗恒星",
|
||||||
|
"badgeProgramModerator": "社区管理员",
|
||||||
|
"postEditedHint": "已编辑",
|
||||||
|
"splashScreenServer": "服务器",
|
||||||
|
"splashScreenServerName": "土豆",
|
||||||
|
"splashScreenCaption": "正在尝试与 HyperNet™ 取得太阳链连接"
|
||||||
}
|
}
|
||||||
|
4
buildtools/appimage_config/AppRun
Executable file
4
buildtools/appimage_config/AppRun
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
exec ./surface
|
8
buildtools/appimage_config/Solian.desktop
Normal file
8
buildtools/appimage_config/Solian.desktop
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Terminal=false
|
||||||
|
Name=Solian
|
||||||
|
Exec=surface %u
|
||||||
|
Icon=icon-light-radius
|
||||||
|
Categories=Network;
|
BIN
buildtools/appimagetool-x86_64.AppImage
Executable file
BIN
buildtools/appimagetool-x86_64.AppImage
Executable file
Binary file not shown.
105
ios/Podfile.lock
105
ios/Podfile.lock
@ -46,58 +46,58 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- file_saver (0.0.1):
|
- file_saver (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Firebase/Analytics (11.8.0):
|
- Firebase/Analytics (11.10.0):
|
||||||
- Firebase/Core
|
- Firebase/Core
|
||||||
- Firebase/Core (11.8.0):
|
- Firebase/Core (11.10.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseAnalytics (~> 11.8.0)
|
- FirebaseAnalytics (~> 11.10.0)
|
||||||
- Firebase/CoreOnly (11.8.0):
|
- Firebase/CoreOnly (11.10.0):
|
||||||
- FirebaseCore (~> 11.8.0)
|
- FirebaseCore (~> 11.10.0)
|
||||||
- Firebase/Messaging (11.8.0):
|
- Firebase/Messaging (11.10.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseMessaging (~> 11.8.0)
|
- FirebaseMessaging (~> 11.10.0)
|
||||||
- firebase_analytics (11.4.4):
|
- firebase_analytics (11.4.5):
|
||||||
- Firebase/Analytics (= 11.8.0)
|
- Firebase/Analytics (= 11.10.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_core (3.12.1):
|
- firebase_core (3.13.0):
|
||||||
- Firebase/CoreOnly (= 11.8.0)
|
- Firebase/CoreOnly (= 11.10.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_messaging (15.2.4):
|
- firebase_messaging (15.2.5):
|
||||||
- Firebase/Messaging (= 11.8.0)
|
- Firebase/Messaging (= 11.10.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- FirebaseAnalytics (11.8.0):
|
- FirebaseAnalytics (11.10.0):
|
||||||
- FirebaseAnalytics/AdIdSupport (= 11.8.0)
|
- FirebaseAnalytics/AdIdSupport (= 11.10.0)
|
||||||
- FirebaseCore (~> 11.8.0)
|
- FirebaseCore (~> 11.10.0)
|
||||||
- FirebaseInstallations (~> 11.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 8.0)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseAnalytics/AdIdSupport (11.8.0):
|
- FirebaseAnalytics/AdIdSupport (11.10.0):
|
||||||
- FirebaseCore (~> 11.8.0)
|
- FirebaseCore (~> 11.10.0)
|
||||||
- FirebaseInstallations (~> 11.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleAppMeasurement (= 11.8.0)
|
- GoogleAppMeasurement (= 11.10.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 8.0)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseCore (11.8.1):
|
- FirebaseCore (11.10.0):
|
||||||
- FirebaseCoreInternal (~> 11.8.0)
|
- FirebaseCoreInternal (~> 11.10.0)
|
||||||
- GoogleUtilities/Environment (~> 8.0)
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
- GoogleUtilities/Logger (~> 8.0)
|
- GoogleUtilities/Logger (~> 8.0)
|
||||||
- FirebaseCoreInternal (11.8.0):
|
- FirebaseCoreInternal (11.10.0):
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- FirebaseInstallations (11.8.0):
|
- FirebaseInstallations (11.10.0):
|
||||||
- FirebaseCore (~> 11.8.0)
|
- FirebaseCore (~> 11.10.0)
|
||||||
- GoogleUtilities/Environment (~> 8.0)
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||||
- PromisesObjC (~> 2.4)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseMessaging (11.8.0):
|
- FirebaseMessaging (11.10.0):
|
||||||
- FirebaseCore (~> 11.8.0)
|
- FirebaseCore (~> 11.10.0)
|
||||||
- FirebaseInstallations (~> 11.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleDataTransport (~> 10.0)
|
- GoogleDataTransport (~> 10.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
@ -128,21 +128,21 @@ PODS:
|
|||||||
- gal (1.0.0):
|
- gal (1.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- GoogleAppMeasurement (11.8.0):
|
- GoogleAppMeasurement (11.10.0):
|
||||||
- GoogleAppMeasurement/AdIdSupport (= 11.8.0)
|
- GoogleAppMeasurement/AdIdSupport (= 11.10.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 8.0)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/AdIdSupport (11.8.0):
|
- GoogleAppMeasurement/AdIdSupport (11.10.0):
|
||||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 11.8.0)
|
- GoogleAppMeasurement/WithoutAdIdSupport (= 11.10.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 8.0)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/WithoutAdIdSupport (11.8.0):
|
- GoogleAppMeasurement/WithoutAdIdSupport (11.10.0):
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 8.0)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
@ -184,11 +184,16 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- in_app_review (2.0.0):
|
- in_app_review (2.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Kingfisher (8.2.0)
|
- Kingfisher (8.3.1)
|
||||||
- livekit_client (2.4.1):
|
- livekit_client (2.4.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_webrtc
|
- flutter_webrtc
|
||||||
- WebRTC-SDK (= 125.6422.06)
|
- WebRTC-SDK (= 125.6422.06)
|
||||||
|
- livekit_noise_filter (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- flutter_webrtc
|
||||||
|
- LiveKitKrispNoiseFilter (= 0.0.7)
|
||||||
|
- LiveKitKrispNoiseFilter (0.0.7)
|
||||||
- media_kit_libs_ios_video (1.0.4):
|
- media_kit_libs_ios_video (1.0.4):
|
||||||
- Flutter
|
- Flutter
|
||||||
- media_kit_video (0.0.1):
|
- media_kit_video (0.0.1):
|
||||||
@ -212,9 +217,9 @@ PODS:
|
|||||||
- receive_sharing_intent (1.8.1):
|
- receive_sharing_intent (1.8.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- SAMKeychain (1.5.3)
|
- SAMKeychain (1.5.3)
|
||||||
- SDWebImage (5.20.1):
|
- SDWebImage (5.21.0):
|
||||||
- SDWebImage/Core (= 5.20.1)
|
- SDWebImage/Core (= 5.21.0)
|
||||||
- SDWebImage/Core (5.20.1)
|
- SDWebImage/Core (5.21.0)
|
||||||
- share_plus (0.0.1):
|
- share_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
@ -283,6 +288,7 @@ DEPENDENCIES:
|
|||||||
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
||||||
- Kingfisher (~> 8.0)
|
- Kingfisher (~> 8.0)
|
||||||
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
||||||
|
- livekit_noise_filter (from `.symlinks/plugins/livekit_noise_filter/ios`)
|
||||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
@ -315,6 +321,7 @@ SPEC REPOS:
|
|||||||
- GoogleDataTransport
|
- GoogleDataTransport
|
||||||
- GoogleUtilities
|
- GoogleUtilities
|
||||||
- Kingfisher
|
- Kingfisher
|
||||||
|
- LiveKitKrispNoiseFilter
|
||||||
- nanopb
|
- nanopb
|
||||||
- OrderedSet
|
- OrderedSet
|
||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
@ -369,6 +376,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/in_app_review/ios"
|
:path: ".symlinks/plugins/in_app_review/ios"
|
||||||
livekit_client:
|
livekit_client:
|
||||||
:path: ".symlinks/plugins/livekit_client/ios"
|
:path: ".symlinks/plugins/livekit_client/ios"
|
||||||
|
livekit_noise_filter:
|
||||||
|
:path: ".symlinks/plugins/livekit_noise_filter/ios"
|
||||||
media_kit_libs_ios_video:
|
media_kit_libs_ios_video:
|
||||||
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
||||||
media_kit_video:
|
media_kit_video:
|
||||||
@ -413,15 +422,15 @@ SPEC CHECKSUMS:
|
|||||||
fast_rsa: d99f8e1809a4a312fa9216d830186869b2e9eb65
|
fast_rsa: d99f8e1809a4a312fa9216d830186869b2e9eb65
|
||||||
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
||||||
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
|
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
|
||||||
Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf
|
Firebase: 1fe1c0a7d9aaea32efe01fbea5f0ebd8d70e53a2
|
||||||
firebase_analytics: 4e93dbe66872104d28ae9750fec1800e1fd66858
|
firebase_analytics: 1998960b8fa16fd0cd9e77a6f9fd35a2009ad65e
|
||||||
firebase_core: 8d552814f6c01ccde5d88939fced4ec26f2f5510
|
firebase_core: 2d4534e7b489907dcede540c835b48981d890943
|
||||||
firebase_messaging: 8b96a4f09841c15a16b96973ef5c3dcfc1a064e4
|
firebase_messaging: 75bc93a4df25faccad67f6662ae872ac9ae69b64
|
||||||
FirebaseAnalytics: 4fd42def128146e24e480e89f310e3d8534ea42b
|
FirebaseAnalytics: 4e42333f02cf78ed93703a5c36f36dd518aebdef
|
||||||
FirebaseCore: 99fe0c4b44a39f37d99e6404e02009d2db5d718d
|
FirebaseCore: 8344daef5e2661eb004b177488d6f9f0f24251b7
|
||||||
FirebaseCoreInternal: df24ce5af28864660ecbd13596fc8dd3a8c34629
|
FirebaseCoreInternal: ef4505d2afb1d0ebbc33162cb3795382904b5679
|
||||||
FirebaseInstallations: 6c963bd2a86aca0481eef4f48f5a4df783ae5917
|
FirebaseInstallations: 9980995bdd06ec8081dfb6ab364162bdd64245c3
|
||||||
FirebaseMessaging: 487b634ccdf6f7b7ff180fdcb2a9935490f764e8
|
FirebaseMessaging: 2b9f56aa4ed286e1f0ce2ee1d413aabb8f9f5cb9
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
|
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
|
||||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||||
@ -430,14 +439,16 @@ SPEC CHECKSUMS:
|
|||||||
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
|
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
|
||||||
flutter_webrtc: 57f32415b8744e806f9c2a96ccdb60c6a627ba33
|
flutter_webrtc: 57f32415b8744e806f9c2a96ccdb60c6a627ba33
|
||||||
gal: baecd024ebfd13c441269ca7404792a7152fde89
|
gal: baecd024ebfd13c441269ca7404792a7152fde89
|
||||||
GoogleAppMeasurement: fc0817122bd4d4189164f85374e06773b9561896
|
GoogleAppMeasurement: 36684bfb3ee034e2b42b4321eb19da3a1b81e65d
|
||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||||
home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f
|
home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f
|
||||||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||||
in_app_review: 5596fe56fab799e8edb3561c03d053363ab13457
|
in_app_review: 5596fe56fab799e8edb3561c03d053363ab13457
|
||||||
Kingfisher: 323e5c4ec7983aaace12af655a7b51a7f88a599d
|
Kingfisher: 3204d23de16b5ea53541c44ca5a8efb55741dec3
|
||||||
livekit_client: 08755cabfa4da4ed455642f460cfbb39bc518070
|
livekit_client: 08755cabfa4da4ed455642f460cfbb39bc518070
|
||||||
|
livekit_noise_filter: a26aeb1c1eae6db0a023fd2f6ea3ff108c3ecbb0
|
||||||
|
LiveKitKrispNoiseFilter: efe418ceca28163ace0ff222bd2cc02384645d84
|
||||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
@ -449,7 +460,7 @@ SPEC CHECKSUMS:
|
|||||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
||||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||||
SDWebImage: 33d0f23bddeb5d209ae959153883247be6703713
|
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
|
||||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||||
|
@ -241,7 +241,9 @@ 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.preload?.video;
|
videoAttachment = post.body['video'] != null
|
||||||
|
? SnAttachment.fromJson(post.body['video'])
|
||||||
|
: null;
|
||||||
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);
|
||||||
@ -252,17 +254,21 @@ class PostWriteController extends ChangeNotifier {
|
|||||||
categories =
|
categories =
|
||||||
List.from(post.categories.map((ele) => ele.alias), growable: true);
|
List.from(post.categories.map((ele) => ele.alias), growable: true);
|
||||||
attachments.addAll(
|
attachments.addAll(
|
||||||
post.preload?.attachments?.map((ele) => PostWriteMedia(ele)) ?? []);
|
post.body['attachments']
|
||||||
poll = post.preload?.poll;
|
?.where((ele) => SnAttachment.fromJson(ele))
|
||||||
|
?.map(PostWriteMedia) ??
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
poll = post.poll;
|
||||||
|
|
||||||
editingDraft = post.isDraft;
|
editingDraft = post.isDraft;
|
||||||
|
|
||||||
if (post.preload?.thumbnail != null &&
|
if (post.body['thumbnail'] != null) {
|
||||||
(post.preload?.thumbnail?.rid.isNotEmpty ?? false)) {
|
thumbnail =
|
||||||
thumbnail = PostWriteMedia(post.preload!.thumbnail);
|
PostWriteMedia(SnAttachment.fromJson(post.body['thumbnail']));
|
||||||
}
|
}
|
||||||
if (post.preload?.realm != null) {
|
if (post.realm != null) {
|
||||||
realm = post.preload!.realm!;
|
realm = post.realm!;
|
||||||
}
|
}
|
||||||
|
|
||||||
editingPost = post;
|
editingPost = post;
|
||||||
|
253
lib/main.dart
253
lib/main.dart
@ -15,6 +15,7 @@ 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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -49,6 +50,7 @@ import 'package:surface/router.dart';
|
|||||||
import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy;
|
import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy;
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/menu_bar.dart';
|
import 'package:surface/widgets/menu_bar.dart';
|
||||||
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
import 'package:surface/widgets/version_label.dart';
|
import 'package:surface/widgets/version_label.dart';
|
||||||
import 'package:tray_manager/tray_manager.dart';
|
import 'package:tray_manager/tray_manager.dart';
|
||||||
import 'package:version/version.dart';
|
import 'package:version/version.dart';
|
||||||
@ -57,6 +59,7 @@ import 'package:in_app_review/in_app_review.dart';
|
|||||||
import 'package:image_picker_android/image_picker_android.dart';
|
import 'package:image_picker_android/image_picker_android.dart';
|
||||||
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
|
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
|
||||||
import 'package:local_notifier/local_notifier.dart';
|
import 'package:local_notifier/local_notifier.dart';
|
||||||
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
|
|
||||||
@pragma('vm:entry-point')
|
@pragma('vm:entry-point')
|
||||||
void appBackgroundDispatcher() {
|
void appBackgroundDispatcher() {
|
||||||
@ -257,6 +260,7 @@ class _AppSplashScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
||||||
bool _isBusy = false;
|
bool _isBusy = false;
|
||||||
|
double _initPercentage = 0;
|
||||||
String _phaseText = 'appInitStarting';
|
String _phaseText = 'appInitStarting';
|
||||||
|
|
||||||
void _tryRequestRating() async {
|
void _tryRequestRating() async {
|
||||||
@ -331,20 +335,24 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
// The Network initialization must be done after the HomeWidget initialization
|
// The Network initialization must be done after the HomeWidget initialization
|
||||||
// The Network initialization will save the server url to the HomeWidget
|
// The Network initialization will save the server url to the HomeWidget
|
||||||
// The Network initialization will also save initialize the Config, so it not need to be initialized again
|
// The Network initialization will also save initialize the Config, so it not need to be initialized again
|
||||||
|
_initPercentage = 0.1;
|
||||||
_setPhaseText('network');
|
_setPhaseText('network');
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
await sn.initializeUserAgent();
|
await sn.initializeUserAgent();
|
||||||
await sn.setConfigWithNative();
|
await sn.setConfigWithNative();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_initPercentage = 0.2;
|
||||||
_setPhaseText('userdata');
|
_setPhaseText('userdata');
|
||||||
final ua = context.read<UserProvider>();
|
final ua = context.read<UserProvider>();
|
||||||
await ua.initialize();
|
await ua.initialize();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_initPercentage = 0.3;
|
||||||
_setPhaseText('websocket');
|
_setPhaseText('websocket');
|
||||||
final ws = context.read<WebSocketProvider>();
|
final ws = context.read<WebSocketProvider>();
|
||||||
await ws.tryConnect();
|
await ws.tryConnect();
|
||||||
try {
|
try {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_initPercentage = 0.9;
|
||||||
_setPhaseText('keyPair');
|
_setPhaseText('keyPair');
|
||||||
final kp = context.read<KeyPairProvider>();
|
final kp = context.read<KeyPairProvider>();
|
||||||
kp.reloadActive();
|
kp.reloadActive();
|
||||||
@ -357,7 +365,6 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
notify.listen();
|
notify.listen();
|
||||||
try {
|
try {
|
||||||
notify.registerPushNotifications();
|
notify.registerPushNotifications();
|
||||||
} catch (_) {}
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_setPhaseText('stickers');
|
_setPhaseText('stickers');
|
||||||
final sticker = context.read<SnStickerProvider>();
|
final sticker = context.read<SnStickerProvider>();
|
||||||
@ -374,7 +381,9 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
_setPhaseText('chat');
|
_setPhaseText('chat');
|
||||||
final ct = context.read<ChatChannelProvider>();
|
final ct = context.read<ChatChannelProvider>();
|
||||||
await ct.refreshAvailableChannels();
|
await ct.refreshAvailableChannels();
|
||||||
|
_initPercentage = 1;
|
||||||
_setPhaseText('done');
|
_setPhaseText('done');
|
||||||
|
} catch (_) {}
|
||||||
_playIntro();
|
_playIntro();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -396,8 +405,22 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
final cfg = context.read<ConfigProvider>();
|
final cfg = context.read<ConfigProvider>();
|
||||||
if (!cfg.soundEffects) return;
|
if (!cfg.soundEffects) return;
|
||||||
|
|
||||||
|
final date = DateTime.now();
|
||||||
final player = AudioPlayer(playerId: 'launch-done-player');
|
final player = AudioPlayer(playerId: 'launch-done-player');
|
||||||
await player.play(AssetSource('audio/sfx/launch-done.mp3'), volume: 0.8);
|
await player.play(
|
||||||
|
(cfg.aprilFoolFeatures && date.month == 4 && date.day == 1)
|
||||||
|
? AssetSource('audio/sfx/launch-intro.mp3')
|
||||||
|
: AssetSource('audio/sfx/launch-done.mp3'),
|
||||||
|
volume: 0.8,
|
||||||
|
ctx: AudioContext(
|
||||||
|
android: AudioContextAndroid(
|
||||||
|
contentType: AndroidContentType.sonification,
|
||||||
|
usageType: AndroidUsageType.notificationEvent,
|
||||||
|
),
|
||||||
|
iOS: AudioContextIOS(category: AVAudioSessionCategory.ambient),
|
||||||
|
),
|
||||||
|
mode: PlayerMode.lowLatency,
|
||||||
|
);
|
||||||
player.onPlayerComplete.listen((_) {
|
player.onPlayerComplete.listen((_) {
|
||||||
player.dispose();
|
player.dispose();
|
||||||
});
|
});
|
||||||
@ -456,6 +479,7 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
AppLifecycleListener(onExitRequested: _onExitRequested);
|
AppLifecycleListener(onExitRequested: _onExitRequested);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
_trayInitialization();
|
_trayInitialization();
|
||||||
_hotkeyInitialization();
|
_hotkeyInitialization();
|
||||||
_notifyInitialization();
|
_notifyInitialization();
|
||||||
@ -464,7 +488,13 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
_tryRequestRating();
|
_tryRequestRating();
|
||||||
_checkForUpdate();
|
_checkForUpdate();
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
|
}).catchError((err) {
|
||||||
|
logging.error('[Bootstrap] Unable to initialize app', err);
|
||||||
|
setState(() => _isBusy = false);
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
logging.error('[Bootstrap] Unable to initialize (pre-stage) app', err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AppExitResponse> _onExitRequested() async {
|
Future<AppExitResponse> _onExitRequested() async {
|
||||||
@ -555,8 +585,205 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
});
|
});
|
||||||
return SizeChangedLayoutNotifier(
|
return SizeChangedLayoutNotifier(
|
||||||
child: _isBusy
|
child: _isBusy
|
||||||
? Material(
|
? _AppLoadingScreen(
|
||||||
key: Key('app-splash-screen-$_isBusy'),
|
isBusy: _isBusy,
|
||||||
|
initPercentage: _initPercentage,
|
||||||
|
phaseText: _phaseText,
|
||||||
|
)
|
||||||
|
: widget.child,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppLoadingScreen extends StatelessWidget {
|
||||||
|
const _AppLoadingScreen({
|
||||||
|
required this.isBusy,
|
||||||
|
required this.initPercentage,
|
||||||
|
required this.phaseText,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool isBusy;
|
||||||
|
final double initPercentage;
|
||||||
|
final String phaseText;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (ResponsiveScaffold.getIsExpand(context)) {
|
||||||
|
return Material(
|
||||||
|
key: Key('app-splash-screen-$isBusy'),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('assets/icon/kanban-1st.jpg'),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.1,
|
||||||
|
),
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
backgroundBlendMode: BlendMode.darken,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0, end: initPercentage),
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
builder: (context, value, _) => Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('${(value * 100).toStringAsFixed(0)}%')
|
||||||
|
.padding(left: 32, bottom: 4),
|
||||||
|
LinearProgressIndicator(
|
||||||
|
value: value,
|
||||||
|
borderRadius: const BorderRadius.all(
|
||||||
|
Radius.circular(0),
|
||||||
|
),
|
||||||
|
stopIndicatorColor: Colors.transparent,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
),
|
||||||
|
const Gap(24),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0, end: initPercentage),
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
builder: (context, value, _) => Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text('${(value * 100).toStringAsFixed(0)}%')
|
||||||
|
.padding(right: 32, bottom: 4),
|
||||||
|
Transform.flip(
|
||||||
|
flipX: true,
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
value: value,
|
||||||
|
borderRadius: const BorderRadius.all(
|
||||||
|
Radius.circular(0),
|
||||||
|
),
|
||||||
|
stopIndicatorColor: Colors.transparent,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(24),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 240, minWidth: 160),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 24),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.surface.withOpacity(0.85),
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).dividerColor,
|
||||||
|
width: 3,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'splashScreenServer',
|
||||||
|
style: GoogleFonts.notoSerifHk(height: 1, fontSize: 11),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr().opacity(0.85),
|
||||||
|
Text(
|
||||||
|
'splashScreenServerName',
|
||||||
|
style: GoogleFonts.notoSerifHk(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr().opacity(0.85),
|
||||||
|
Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
text: '#',
|
||||||
|
style: GoogleFonts.notoSerifHk(),
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '0',
|
||||||
|
style: GoogleFonts.notoSerifHk(
|
||||||
|
fontSize: 80,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).padding(vertical: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: MediaQuery.of(context).size.height * 0.2,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
phaseText,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
AnimateWidgetExtensions(Text(
|
||||||
|
'splashScreenCaption',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr())
|
||||||
|
.animate(onPlay: (e) => e.repeat())
|
||||||
|
.fadeIn(duration: 500.ms, curve: Curves.easeOut)
|
||||||
|
.then()
|
||||||
|
.fadeOut(
|
||||||
|
duration: 500.ms,
|
||||||
|
delay: 1000.ms,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 8,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/icon/icon.png',
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
).padding(all: 4),
|
||||||
|
const Gap(4),
|
||||||
|
Text('Solar Network').bold(),
|
||||||
|
Expanded(child: const SizedBox()),
|
||||||
|
AppVersionLabel(),
|
||||||
|
const Gap(12),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Material(
|
||||||
|
key: Key('app-splash-screen-$isBusy'),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
@ -580,27 +807,25 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
'assets/icon/icon.png',
|
'assets/icon/icon.png',
|
||||||
width: 64,
|
width: 64,
|
||||||
height: 64,
|
height: 64,
|
||||||
color:
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
),
|
||||||
Text('Solar Network').bold(),
|
Text('Solar Network').bold(),
|
||||||
AppVersionLabel(),
|
AppVersionLabel(),
|
||||||
Gap(8),
|
Gap(8),
|
||||||
Text(_phaseText, textAlign: TextAlign.center),
|
Text(phaseText, textAlign: TextAlign.center),
|
||||||
Gap(16),
|
Gap(16),
|
||||||
const LinearProgressIndicator(),
|
TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0, end: initPercentage),
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
builder: (context, value, _) =>
|
||||||
|
LinearProgressIndicator(value: value),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
|
||||||
: widget.child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:livekit_client/livekit_client.dart';
|
import 'package:livekit_client/livekit_client.dart';
|
||||||
|
import 'package:livekit_noise_filter/livekit_noise_filter.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
@ -131,10 +132,14 @@ class ChatCallProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
void initRoom() {
|
void initRoom() {
|
||||||
initHardware();
|
initHardware();
|
||||||
|
final timeout = const Duration(seconds: 60);
|
||||||
_room = Room(
|
_room = Room(
|
||||||
roomOptions: const RoomOptions(
|
roomOptions: RoomOptions(
|
||||||
dynacast: true,
|
dynacast: true,
|
||||||
adaptiveStream: true,
|
adaptiveStream: true,
|
||||||
|
defaultAudioCaptureOptions: AudioCaptureOptions(
|
||||||
|
processor: LiveKitNoiseFilter(),
|
||||||
|
),
|
||||||
defaultAudioPublishOptions: AudioPublishOptions(
|
defaultAudioPublishOptions: AudioPublishOptions(
|
||||||
name: 'call_voice',
|
name: 'call_voice',
|
||||||
stream: 'call_stream',
|
stream: 'call_stream',
|
||||||
@ -154,6 +159,16 @@ class ChatCallProvider extends ChangeNotifier {
|
|||||||
params: VideoParametersPresets.h1080_169,
|
params: VideoParametersPresets.h1080_169,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
connectOptions: ConnectOptions(
|
||||||
|
autoSubscribe: true,
|
||||||
|
timeouts: Timeouts(
|
||||||
|
connection: timeout,
|
||||||
|
debounce: timeout,
|
||||||
|
publish: timeout,
|
||||||
|
peerConnection: timeout,
|
||||||
|
iceRestart: timeout,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
_listener = _room.createListener();
|
_listener = _room.createListener();
|
||||||
WakelockPlus.enable();
|
WakelockPlus.enable();
|
||||||
|
@ -152,7 +152,7 @@ class KeyPairProvider {
|
|||||||
|
|
||||||
Future<SnKeyPair?> reloadActive({bool autoEnroll = true}) async {
|
Future<SnKeyPair?> reloadActive({bool autoEnroll = true}) async {
|
||||||
final kp = await (_dt.db.snLocalKeyPair.select()
|
final kp = await (_dt.db.snLocalKeyPair.select()
|
||||||
..where((e) => e.accountId.equals(_ua.user!.id))
|
..where((e) => e.accountId.equals(_ua.user?.id ?? 0))
|
||||||
..where((e) => e.privateKey.isNotNull())
|
..where((e) => e.privateKey.isNotNull())
|
||||||
..where((e) => e.isActive.equals(true))
|
..where((e) => e.isActive.equals(true))
|
||||||
..limit(1))
|
..limit(1))
|
||||||
|
@ -106,6 +106,14 @@ class NotificationProvider extends ChangeNotifier {
|
|||||||
_notifySoundPlayer.play(
|
_notifySoundPlayer.play(
|
||||||
AssetSource('audio/notify/metal-pipe.mp3'),
|
AssetSource('audio/notify/metal-pipe.mp3'),
|
||||||
volume: 0.6,
|
volume: 0.6,
|
||||||
|
ctx: AudioContext(
|
||||||
|
android: AudioContextAndroid(
|
||||||
|
contentType: AndroidContentType.sonification,
|
||||||
|
usageType: AndroidUsageType.notificationEvent,
|
||||||
|
),
|
||||||
|
iOS: AudioContextIOS(category: AVAudioSessionCategory.ambient),
|
||||||
|
),
|
||||||
|
mode: PlayerMode.lowLatency,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,144 +1,31 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:surface/providers/sn_attachment.dart';
|
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/sn_realm.dart';
|
|
||||||
import 'package:surface/providers/user_directory.dart';
|
|
||||||
import 'package:surface/types/poll.dart';
|
|
||||||
import 'package:surface/types/post.dart';
|
import 'package:surface/types/post.dart';
|
||||||
import 'package:surface/types/realm.dart';
|
|
||||||
|
|
||||||
class SnPostContentProvider {
|
class SnPostContentProvider {
|
||||||
late final SnNetworkProvider _sn;
|
late final SnNetworkProvider _sn;
|
||||||
late final UserDirectoryProvider _ud;
|
|
||||||
late final SnAttachmentProvider _attach;
|
|
||||||
late final SnRealmProvider _realm;
|
|
||||||
|
|
||||||
SnPostContentProvider(BuildContext context) {
|
SnPostContentProvider(BuildContext context) {
|
||||||
_sn = context.read<SnNetworkProvider>();
|
_sn = context.read<SnNetworkProvider>();
|
||||||
_ud = context.read<UserDirectoryProvider>();
|
|
||||||
_attach = context.read<SnAttachmentProvider>();
|
|
||||||
_realm = context.read<SnRealmProvider>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<SnPoll> _fetchPoll(int id) async {
|
|
||||||
final resp = await _sn.client.get('/cgi/co/polls/$id');
|
|
||||||
return SnPoll.fromJson(resp.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SnPost>> _preloadRelatedDataInBatch(List<SnPost> out) async {
|
Future<List<SnPost>> _preloadRelatedDataInBatch(List<SnPost> out) async {
|
||||||
Set<String> rids = {};
|
|
||||||
Set<int> uids = {};
|
|
||||||
for (var i = 0; i < out.length; i++) {
|
|
||||||
rids.addAll(out[i].body['attachments']?.cast<String>() ?? []);
|
|
||||||
if (out[i].body['thumbnail'] != null) {
|
|
||||||
rids.add(out[i].body['thumbnail']);
|
|
||||||
}
|
|
||||||
if (out[i].body['video'] != null) {
|
|
||||||
rids.add(out[i].body['video']);
|
|
||||||
}
|
|
||||||
if (out[i].repostTo != null) {
|
|
||||||
out[i] = out[i].copyWith(
|
|
||||||
repostTo: await _preloadRelatedDataSingle(out[i].repostTo!),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (out[i].publisher.type == 0) {
|
|
||||||
uids.add(out[i].publisher.accountId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final attachments = await _attach.getMultiple(rids.toList());
|
|
||||||
for (var i = 0; i < out.length; i++) {
|
|
||||||
SnPoll? poll;
|
|
||||||
SnRealm? realm;
|
|
||||||
if (out[i].pollId != null) {
|
|
||||||
poll = await _fetchPoll(out[i].pollId!);
|
|
||||||
}
|
|
||||||
if (out[i].realmId != null) {
|
|
||||||
realm = await _realm.getRealm(out[i].realmId!);
|
|
||||||
}
|
|
||||||
|
|
||||||
out[i] = out[i].copyWith(
|
|
||||||
preload: SnPostPreload(
|
|
||||||
thumbnail: attachments
|
|
||||||
.where((ele) => ele?.rid == out[i].body['thumbnail'])
|
|
||||||
.firstOrNull,
|
|
||||||
attachments: attachments
|
|
||||||
.where((ele) =>
|
|
||||||
out[i].body['attachments']?.contains(ele?.rid) ?? false)
|
|
||||||
.toList(),
|
|
||||||
video: attachments
|
|
||||||
.where((ele) => ele?.rid == out[i].body['video'])
|
|
||||||
.firstOrNull,
|
|
||||||
poll: poll,
|
|
||||||
realm: realm,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
uids.addAll(
|
|
||||||
attachments.where((ele) => ele != null).map((ele) => ele!.accountId));
|
|
||||||
await _ud.listAccount(uids);
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SnPost> _preloadRelatedDataSingle(SnPost out) async {
|
Future<SnPost> _preloadRelatedDataSingle(SnPost out) async {
|
||||||
Set<String> rids = {};
|
|
||||||
Set<int> uids = {};
|
|
||||||
rids.addAll(out.body['attachments']?.cast<String>() ?? []);
|
|
||||||
if (out.body['thumbnail'] != null) {
|
|
||||||
rids.add(out.body['thumbnail']);
|
|
||||||
}
|
|
||||||
if (out.body['video'] != null) {
|
|
||||||
rids.add(out.body['video']);
|
|
||||||
}
|
|
||||||
if (out.repostTo != null) {
|
|
||||||
out = out.copyWith(
|
|
||||||
repostTo: await _preloadRelatedDataSingle(out.repostTo!),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (out.publisher.type == 0) {
|
|
||||||
uids.add(out.publisher.accountId);
|
|
||||||
}
|
|
||||||
|
|
||||||
final attachments = await _attach.getMultiple(rids.toList());
|
|
||||||
|
|
||||||
SnPoll? poll;
|
|
||||||
SnRealm? realm;
|
|
||||||
if (out.pollId != null) {
|
|
||||||
poll = await _fetchPoll(out.pollId!);
|
|
||||||
}
|
|
||||||
if (out.realmId != null) {
|
|
||||||
realm = await _realm.getRealm(out.realmId!);
|
|
||||||
}
|
|
||||||
|
|
||||||
out = out.copyWith(
|
|
||||||
preload: SnPostPreload(
|
|
||||||
thumbnail: attachments
|
|
||||||
.where((ele) => ele?.rid == out.body['thumbnail'])
|
|
||||||
.firstOrNull,
|
|
||||||
attachments: attachments
|
|
||||||
.where(
|
|
||||||
(ele) => out.body['attachments']?.contains(ele?.rid) ?? false)
|
|
||||||
.toList(),
|
|
||||||
video: attachments
|
|
||||||
.where((ele) => ele?.rid == out.body['video'])
|
|
||||||
.firstOrNull,
|
|
||||||
poll: poll,
|
|
||||||
realm: realm,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
uids.addAll(
|
|
||||||
attachments.where((ele) => ele != null).map((ele) => ele!.accountId));
|
|
||||||
await _ud.listAccount(uids);
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SnPost>> listRecommendations() async {
|
Future<List<SnPost>> listRecommendations() async {
|
||||||
final resp = await _sn.client.get('/cgi/co/recommendations');
|
final resp = await _sn.client.get(
|
||||||
|
'/cgi/co/recommendations',
|
||||||
|
options: Options(headers: {
|
||||||
|
'X-API-Version': '2',
|
||||||
|
}),
|
||||||
|
);
|
||||||
final out = _preloadRelatedDataInBatch(
|
final out = _preloadRelatedDataInBatch(
|
||||||
List.from(resp.data.map((ele) => SnPost.fromJson(ele))),
|
List.from(resp.data.map((ele) => SnPost.fromJson(ele))),
|
||||||
);
|
);
|
||||||
@ -146,11 +33,14 @@ class SnPostContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SnFeedEntry>> getFeed({int take = 20, DateTime? cursor}) async {
|
Future<List<SnFeedEntry>> getFeed({int take = 20, DateTime? cursor}) async {
|
||||||
final resp =
|
final resp = await _sn.client.get(
|
||||||
await _sn.client.get('/cgi/co/recommendations/feed', queryParameters: {
|
'/cgi/co/recommendations/feed',
|
||||||
|
queryParameters: {
|
||||||
'take': take,
|
'take': take,
|
||||||
if (cursor != null) 'cursor': cursor.toUtc().millisecondsSinceEpoch,
|
if (cursor != null) 'cursor': cursor.toUtc().millisecondsSinceEpoch,
|
||||||
});
|
},
|
||||||
|
options: Options(headers: {'X-API-Version': '2'}),
|
||||||
|
);
|
||||||
final List<SnFeedEntry> out =
|
final List<SnFeedEntry> out =
|
||||||
List.from(resp.data.map((ele) => SnFeedEntry.fromJson(ele)));
|
List.from(resp.data.map((ele) => SnFeedEntry.fromJson(ele)));
|
||||||
|
|
||||||
@ -202,6 +92,9 @@ class SnPostContentProvider {
|
|||||||
if (realm != null) 'realm': realm,
|
if (realm != null) 'realm': realm,
|
||||||
if (channel != null) 'channel': channel,
|
if (channel != null) 'channel': channel,
|
||||||
},
|
},
|
||||||
|
options: Options(headers: {
|
||||||
|
'X-API-Version': '2',
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
final List<SnPost> out = await _preloadRelatedDataInBatch(
|
final List<SnPost> out = await _preloadRelatedDataInBatch(
|
||||||
List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
|
List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
|
||||||
@ -215,11 +108,16 @@ class SnPostContentProvider {
|
|||||||
int take = 10,
|
int take = 10,
|
||||||
int offset = 0,
|
int offset = 0,
|
||||||
}) async {
|
}) async {
|
||||||
final resp = await _sn.client
|
final resp = await _sn.client.get(
|
||||||
.get('/cgi/co/posts/$parentId/replies', queryParameters: {
|
'/cgi/co/posts/$parentId/replies',
|
||||||
|
queryParameters: {
|
||||||
'take': take,
|
'take': take,
|
||||||
'offset': offset,
|
'offset': offset,
|
||||||
});
|
},
|
||||||
|
options: Options(headers: {
|
||||||
|
'X-API-Version': '2',
|
||||||
|
}),
|
||||||
|
);
|
||||||
final List<SnPost> out = await _preloadRelatedDataInBatch(
|
final List<SnPost> out = await _preloadRelatedDataInBatch(
|
||||||
List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
|
List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
|
||||||
);
|
);
|
||||||
@ -234,13 +132,20 @@ class SnPostContentProvider {
|
|||||||
Iterable<String>? tags,
|
Iterable<String>? tags,
|
||||||
Iterable<String>? categories,
|
Iterable<String>? categories,
|
||||||
}) async {
|
}) async {
|
||||||
final resp = await _sn.client.get('/cgi/co/posts/search', queryParameters: {
|
final resp = await _sn.client.get(
|
||||||
|
'/cgi/co/posts/search',
|
||||||
|
queryParameters: {
|
||||||
'take': take,
|
'take': take,
|
||||||
'offset': offset,
|
'offset': offset,
|
||||||
'probe': searchTerm,
|
'probe': searchTerm,
|
||||||
if (tags?.isNotEmpty ?? false) 'tags': tags!.join(','),
|
if (tags?.isNotEmpty ?? false) 'tags': tags!.join(','),
|
||||||
if (categories?.isNotEmpty ?? false) 'categories': categories!.join(','),
|
if (categories?.isNotEmpty ?? false)
|
||||||
});
|
'categories': categories!.join(','),
|
||||||
|
},
|
||||||
|
options: Options(headers: {
|
||||||
|
'X-API-Version': '2',
|
||||||
|
}),
|
||||||
|
);
|
||||||
final List<SnPost> out = await _preloadRelatedDataInBatch(
|
final List<SnPost> out = await _preloadRelatedDataInBatch(
|
||||||
List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
|
List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
|
||||||
);
|
);
|
||||||
@ -249,7 +154,12 @@ class SnPostContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<SnPost> getPost(dynamic id) async {
|
Future<SnPost> getPost(dynamic id) async {
|
||||||
final resp = await _sn.client.get('/cgi/co/posts/$id');
|
final resp = await _sn.client.get(
|
||||||
|
'/cgi/co/posts/$id',
|
||||||
|
options: Options(headers: {
|
||||||
|
'X-API-Version': '2',
|
||||||
|
}),
|
||||||
|
);
|
||||||
final out = _preloadRelatedDataSingle(
|
final out = _preloadRelatedDataSingle(
|
||||||
SnPost.fromJson(resp.data),
|
SnPost.fromJson(resp.data),
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:animations/animations.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:surface/screens/abuse_report.dart';
|
import 'package:surface/screens/abuse_report.dart';
|
||||||
@ -54,16 +53,6 @@ import 'package:surface/types/post.dart';
|
|||||||
import 'package:surface/widgets/about.dart';
|
import 'package:surface/widgets/about.dart';
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
|
||||||
Widget _fadeThroughTransition(BuildContext context, Animation<double> animation,
|
|
||||||
Animation<double> secondaryAnimation, Widget child) {
|
|
||||||
return FadeThroughTransition(
|
|
||||||
animation: animation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final _appRoutes = [
|
final _appRoutes = [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
@ -305,10 +294,7 @@ final _appRoutes = [
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/realm',
|
path: '/realm',
|
||||||
name: 'realm',
|
name: 'realm',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => const RealmScreen(),
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
|
||||||
child: const RealmScreen(),
|
|
||||||
),
|
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/:alias/community',
|
path: '/:alias/community',
|
||||||
|
@ -110,7 +110,7 @@ class AccountScreen extends StatelessWidget {
|
|||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: AutoAppBarLeading(),
|
leading: AutoAppBarLeading(),
|
||||||
title: Text("screenAccount").tr(),
|
title: Text("screenAccount").tr(),
|
||||||
|
@ -59,7 +59,7 @@ class _ActionEventScreenState extends State<ActionEventScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('accountActionEvent').tr(),
|
title: Text('accountActionEvent').tr(),
|
||||||
|
@ -91,7 +91,7 @@ class _AccountAuthTicketState extends State<AccountAuthTicket> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('accountAuthTickets').tr(),
|
title: Text('accountAuthTickets').tr(),
|
||||||
|
@ -70,7 +70,7 @@ class _AccountBadgesScreenState extends State<AccountBadgesScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('screenAccountBadges').tr(),
|
title: Text('screenAccountBadges').tr(),
|
||||||
),
|
),
|
||||||
|
@ -69,7 +69,7 @@ class _AccountContactMethodState extends State<AccountContactMethod> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('accountContactMethods').tr(),
|
title: Text('accountContactMethods').tr(),
|
||||||
|
@ -62,7 +62,7 @@ class _FactorSettingsScreenState extends State<FactorSettingsScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: PageBackButton(),
|
leading: PageBackButton(),
|
||||||
title: Text('screenFactorSettings').tr(),
|
title: Text('screenFactorSettings').tr(),
|
||||||
|
@ -37,7 +37,7 @@ class _KeyPairScreenState extends State<KeyPairScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('screenKeyPairs').tr(),
|
title: Text('screenKeyPairs').tr(),
|
||||||
),
|
),
|
||||||
|
@ -75,7 +75,7 @@ class _AccountNotifyPrefsScreenState extends State<AccountNotifyPrefsScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('accountSettingsNotify').tr(),
|
title: Text('accountSettingsNotify').tr(),
|
||||||
|
@ -70,7 +70,7 @@ class _AccountSecurityPrefsScreenState
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('accountSettingsSecurity').tr(),
|
title: Text('accountSettingsSecurity').tr(),
|
||||||
|
@ -244,7 +244,7 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
|||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('screenAccountProfileEdit').tr()),
|
title: Text('screenAccountProfileEdit').tr()),
|
||||||
@ -263,7 +263,7 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
|||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 7,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
|
@ -61,6 +61,21 @@ final Map<String, (String, IconData, Color)> kBadgesMeta = {
|
|||||||
Symbols.thumb_up,
|
Symbols.thumb_up,
|
||||||
Colors.lightGreen,
|
Colors.lightGreen,
|
||||||
),
|
),
|
||||||
|
'programs.developers': (
|
||||||
|
'badgeProgramDeveloper',
|
||||||
|
Symbols.code,
|
||||||
|
Colors.blue,
|
||||||
|
),
|
||||||
|
'programs.stellar': (
|
||||||
|
'badgeProgramStellar',
|
||||||
|
Symbols.family_star,
|
||||||
|
Colors.orange,
|
||||||
|
),
|
||||||
|
'programs.moderator': (
|
||||||
|
'badgeProgramModerator',
|
||||||
|
Symbols.sword_rose,
|
||||||
|
Colors.blue,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
class UserScreen extends StatefulWidget {
|
class UserScreen extends StatefulWidget {
|
||||||
|
@ -70,7 +70,7 @@ class _AccountProgramScreenState extends State<AccountProgramScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('accountProgram').tr(),
|
title: Text('accountProgram').tr(),
|
||||||
),
|
),
|
||||||
|
@ -196,7 +196,7 @@ class _AccountPublisherEditScreenState
|
|||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: PageBackButton(),
|
leading: PageBackButton(),
|
||||||
title: Text('screenAccountPublisherEdit').tr()),
|
title: Text('screenAccountPublisherEdit').tr()),
|
||||||
@ -214,7 +214,7 @@ class _AccountPublisherEditScreenState
|
|||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 7,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
|
@ -26,7 +26,7 @@ class _AccountPublisherNewScreenState extends State<AccountPublisherNewScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('screenAccountPublisherNew').tr(),
|
title: Text('screenAccountPublisherNew').tr(),
|
||||||
|
@ -82,7 +82,7 @@ class _PublisherScreenState extends State<PublisherScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: const PageBackButton(),
|
leading: const PageBackButton(),
|
||||||
title: Text('screenAccountPublishers').tr(),
|
title: Text('screenAccountPublishers').tr(),
|
||||||
|
@ -55,7 +55,7 @@ class _PunishmentsScreenState extends State<PunishmentsScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('accountPunishments').tr(),
|
title: Text('accountPunishments').tr(),
|
||||||
leading: PageBackButton(),
|
leading: PageBackButton(),
|
||||||
|
@ -37,7 +37,7 @@ class AccountSettingsScreen extends StatelessWidget {
|
|||||||
final ua = context.watch<UserProvider>();
|
final ua = context.watch<UserProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: PageBackButton(),
|
leading: PageBackButton(),
|
||||||
title: Text('screenAccountSettings').tr(),
|
title: Text('screenAccountSettings').tr(),
|
||||||
|
@ -8,7 +8,6 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/user_directory.dart';
|
|
||||||
import 'package:surface/types/attachment.dart';
|
import 'package:surface/types/attachment.dart';
|
||||||
import 'package:surface/widgets/attachment/attachment_zoom.dart';
|
import 'package:surface/widgets/attachment/attachment_zoom.dart';
|
||||||
import 'package:surface/widgets/attachment/attachment_item.dart';
|
import 'package:surface/widgets/attachment/attachment_item.dart';
|
||||||
@ -53,7 +52,6 @@ class _AlbumScreenState extends State<AlbumScreen> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final ud = context.read<UserDirectoryProvider>();
|
|
||||||
final resp = await sn.client.get('/cgi/uc/attachments', queryParameters: {
|
final resp = await sn.client.get('/cgi/uc/attachments', queryParameters: {
|
||||||
'take': 10,
|
'take': 10,
|
||||||
'offset': _attachments.length,
|
'offset': _attachments.length,
|
||||||
@ -64,8 +62,6 @@ class _AlbumScreenState extends State<AlbumScreen> {
|
|||||||
_attachments.addAll(attachments);
|
_attachments.addAll(attachments);
|
||||||
_heroTags.addAll(_attachments.map((_) => uuid.v4()));
|
_heroTags.addAll(_attachments.map((_) => uuid.v4()));
|
||||||
|
|
||||||
await ud.listAccount(attachments.map((e) => e.accountId).toSet());
|
|
||||||
|
|
||||||
_totalCount = resp.data['count'] as int?;
|
_totalCount = resp.data['count'] as int?;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
@ -223,7 +223,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: AutoAppBarLeading(),
|
leading: AutoAppBarLeading(),
|
||||||
title: Text('screenChat').tr(),
|
title: Text('screenChat').tr(),
|
||||||
@ -389,7 +389,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
children: [
|
children: [
|
||||||
if (_focusedRealm!.banner != null)
|
if (_focusedRealm!.banner != null)
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 7,
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(
|
sn.getAttachmentUrl(
|
||||||
_focusedRealm!.banner!,
|
_focusedRealm!.banner!,
|
||||||
|
@ -32,7 +32,7 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildListLayout() {
|
Widget _buildMeetLayout() {
|
||||||
final call = context.read<ChatCallProvider>();
|
final call = context.read<ChatCallProvider>();
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
@ -41,9 +41,7 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
Theme.of(context).colorScheme.surfaceContainer.withOpacity(0.75),
|
Theme.of(context).colorScheme.surfaceContainer.withOpacity(0.75),
|
||||||
child: call.focusTrack != null
|
child: call.focusTrack != null
|
||||||
? InteractiveParticipantWidget(
|
? InteractiveParticipantWidget(
|
||||||
isFixedAvatar: false,
|
|
||||||
participant: call.focusTrack!,
|
participant: call.focusTrack!,
|
||||||
onTap: () {},
|
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
@ -62,16 +60,12 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Padding(
|
return SizedBox(
|
||||||
padding: const EdgeInsets.only(top: 8, left: 8),
|
height: 128,
|
||||||
child: ClipRRect(
|
width: 128,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
|
||||||
child: InteractiveParticipantWidget(
|
child: InteractiveParticipantWidget(
|
||||||
isFixedAvatar: true,
|
|
||||||
width: 120,
|
|
||||||
height: 120,
|
|
||||||
color: Theme.of(context).cardColor,
|
|
||||||
participant: track,
|
participant: track,
|
||||||
|
avatarSize: 32,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (track.participant.sid !=
|
if (track.participant.sid !=
|
||||||
call.focusTrack?.participant.sid) {
|
call.focusTrack?.participant.sid) {
|
||||||
@ -79,7 +73,6 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -89,50 +82,26 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildGridLayout() {
|
Widget _buildListLayout() {
|
||||||
final call = context.read<ChatCallProvider>();
|
final call = context.read<ChatCallProvider>();
|
||||||
|
|
||||||
return LayoutBuilder(builder: (context, constraints) {
|
return LayoutBuilder(
|
||||||
double screenWidth = constraints.maxWidth;
|
builder: (context, constraints) {
|
||||||
double screenHeight = constraints.maxHeight;
|
return ListView.builder(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
int columns = (math.sqrt(call.participantTracks.length)).ceil();
|
|
||||||
int rows = (call.participantTracks.length / columns).ceil();
|
|
||||||
|
|
||||||
double tileWidth = screenWidth / columns;
|
|
||||||
double tileHeight = screenHeight / rows;
|
|
||||||
|
|
||||||
return StyledWidget(GridView.builder(
|
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: columns,
|
|
||||||
childAspectRatio: tileWidth / tileHeight,
|
|
||||||
crossAxisSpacing: 8,
|
|
||||||
mainAxisSpacing: 8,
|
|
||||||
),
|
|
||||||
itemCount: math.max(0, call.participantTracks.length),
|
itemCount: math.max(0, call.participantTracks.length),
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
final track = call.participantTracks[index];
|
final track = call.participantTracks[index];
|
||||||
return Card(
|
return InteractiveParticipantWidget(
|
||||||
child: ClipRRect(
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
isList: true,
|
||||||
child: InteractiveParticipantWidget(
|
avatarSize: 24,
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.surfaceContainerHigh
|
|
||||||
.withOpacity(0.75),
|
|
||||||
participant: track,
|
participant: track,
|
||||||
onTap: () {
|
|
||||||
if (track.participant.sid !=
|
|
||||||
call.focusTrack?.participant.sid) {
|
|
||||||
call.setFocusTrack(track);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)).padding(all: 8);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -155,7 +124,7 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
listenable: call,
|
listenable: call,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: RichText(
|
title: RichText(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
@ -176,9 +145,7 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: GestureDetector(
|
body: Column(
|
||||||
behavior: HitTestBehavior.translucent,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
@ -252,6 +219,7 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
).padding(all: 3),
|
).padding(all: 3),
|
||||||
],
|
],
|
||||||
@ -282,9 +250,9 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
builder: (context) {
|
builder: (context) {
|
||||||
switch (_layoutMode) {
|
switch (_layoutMode) {
|
||||||
case 1:
|
case 1:
|
||||||
return _buildGridLayout();
|
|
||||||
default:
|
|
||||||
return _buildListLayout();
|
return _buildListLayout();
|
||||||
|
default:
|
||||||
|
return _buildMeetLayout();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -298,10 +266,9 @@ class _CallRoomScreenState extends State<CallRoomScreen> {
|
|||||||
call.room.localParticipant!,
|
call.room.localParticipant!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Gap(MediaQuery.of(context).padding.bottom),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
|
|||||||
final isOwned = ua.isAuthorized && _channel?.accountId == ua.user?.id;
|
final isOwned = ua.isAuthorized && _channel?.accountId == ua.user?.id;
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: _channel != null ? Text(_channel!.name) : Text('loading').tr(),
|
title: _channel != null ? Text(_channel!.name) : Text('loading').tr(),
|
||||||
),
|
),
|
||||||
|
@ -141,7 +141,7 @@ class _ChatManageScreenState extends State<ChatManageScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: widget.editingChannelAlias != null
|
title: widget.editingChannelAlias != null
|
||||||
? Text('screenChatManage').tr()
|
? Text('screenChatManage').tr()
|
||||||
|
@ -304,7 +304,7 @@ class _ChatRoomScreenState extends State<ChatRoomScreen> {
|
|||||||
final ud = context.read<UserDirectoryProvider>();
|
final ud = context.read<UserDirectoryProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
_channel?.type == 1
|
_channel?.type == 1
|
||||||
|
@ -157,7 +157,7 @@ class _ExploreScreenState extends State<ExploreScreen>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final cfg = context.watch<ConfigProvider>();
|
final cfg = context.watch<ConfigProvider>();
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
floatingActionButtonLocation: ExpandableFab.location,
|
floatingActionButtonLocation: ExpandableFab.location,
|
||||||
floatingActionButton: ExpandableFab(
|
floatingActionButton: ExpandableFab(
|
||||||
key: _fabKey,
|
key: _fabKey,
|
||||||
|
@ -11,13 +11,11 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
import 'package:surface/providers/notification.dart';
|
import 'package:surface/providers/notification.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/types/notification.dart';
|
import 'package:surface/types/notification.dart';
|
||||||
import 'package:surface/types/post.dart';
|
|
||||||
import 'package:surface/widgets/app_bar_leading.dart';
|
import 'package:surface/widgets/app_bar_leading.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/loading_indicator.dart';
|
import 'package:surface/widgets/loading_indicator.dart';
|
||||||
import 'package:surface/widgets/markdown_content.dart';
|
import 'package:surface/widgets/markdown_content.dart';
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
import 'package:surface/widgets/post/post_item.dart';
|
|
||||||
import 'package:very_good_infinite_list/very_good_infinite_list.dart';
|
import 'package:very_good_infinite_list/very_good_infinite_list.dart';
|
||||||
|
|
||||||
import '../providers/userinfo.dart';
|
import '../providers/userinfo.dart';
|
||||||
@ -219,34 +217,24 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
'interactive.subscription',
|
'interactive.subscription',
|
||||||
].contains(nty.topic) &&
|
].contains(nty.topic) &&
|
||||||
nty.metadata['related_post'] != null)
|
nty.metadata['related_post'] != null)
|
||||||
GestureDetector(
|
TextButton(
|
||||||
child: Container(
|
style: ButtonStyle(
|
||||||
decoration: BoxDecoration(
|
padding: WidgetStatePropertyAll(
|
||||||
borderRadius: const BorderRadius.all(
|
EdgeInsets.zero,
|
||||||
Radius.circular(8)),
|
|
||||||
border: Border.all(
|
|
||||||
color: Theme.of(context).dividerColor,
|
|
||||||
width: 1),
|
|
||||||
),
|
),
|
||||||
child: PostItem(
|
visualDensity: VisualDensity.compact,
|
||||||
data: SnPost.fromJson(
|
|
||||||
nty.metadata['related_post']!),
|
|
||||||
showComments: false,
|
|
||||||
showReactions: false,
|
|
||||||
showMenu: false,
|
|
||||||
).padding(vertical: 4),
|
|
||||||
),
|
),
|
||||||
onTap: () {
|
child: Text('postReadMore').tr(),
|
||||||
|
onPressed: () {
|
||||||
GoRouter.of(context).pushNamed(
|
GoRouter.of(context).pushNamed(
|
||||||
'postDetail',
|
'postDetail',
|
||||||
pathParameters: {
|
pathParameters: {
|
||||||
'slug': nty
|
'slug': nty.metadata['related_post']['id']
|
||||||
.metadata['related_post']!['id']
|
.toString(),
|
||||||
.toString()
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
).padding(top: 8),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
@ -66,7 +66,7 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
|
|||||||
final double maxWidth = _data?.type == 'video' ? double.infinity : 640;
|
final double maxWidth = _data?.type == 'video' ? double.infinity : 640;
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: BackButton(
|
leading: BackButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
@ -346,9 +346,15 @@ class _PostEditorScreenState extends State<PostEditorScreen>
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Icons.edit, size: 16),
|
const Icon(Icons.edit, size: 16),
|
||||||
const Gap(10),
|
const Gap(10),
|
||||||
Text('postEditingNotice').tr(args: [
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'postEditingNotice',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
).tr(args: [
|
||||||
'@${_writeController.editingPost!.publisher.name}'
|
'@${_writeController.editingPost!.publisher.name}'
|
||||||
]),
|
]),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -79,6 +79,7 @@ class _PostShuffleScreenState extends State<PostShuffleScreen> {
|
|||||||
key: ValueKey(ele),
|
key: ValueKey(ele),
|
||||||
data: ele,
|
data: ele,
|
||||||
maxWidth: 640,
|
maxWidth: 640,
|
||||||
|
useReplace: true,
|
||||||
onChanged: (ele) {
|
onChanged: (ele) {
|
||||||
_posts[idx] = ele;
|
_posts[idx] = ele;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
@ -286,7 +286,7 @@ class _PostPublisherScreenState extends State<PostPublisherScreen>
|
|||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
body: NestedScrollView(
|
body: NestedScrollView(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||||
|
@ -45,7 +45,7 @@ class _WalletScreenState extends State<WalletScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: PageBackButton(), title: Text('screenAccountWallet').tr()),
|
leading: PageBackButton(), title: Text('screenAccountWallet').tr()),
|
||||||
body: Column(
|
body: Column(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:surface/types/account.dart';
|
||||||
|
|
||||||
part 'attachment.freezed.dart';
|
part 'attachment.freezed.dart';
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ abstract class SnAttachment with _$SnAttachment {
|
|||||||
required int? refId,
|
required int? refId,
|
||||||
required SnAttachmentPool? pool,
|
required SnAttachmentPool? pool,
|
||||||
required int? poolId,
|
required int? poolId,
|
||||||
|
required SnAccount? account,
|
||||||
required int accountId,
|
required int accountId,
|
||||||
int? thumbnailId,
|
int? thumbnailId,
|
||||||
SnAttachment? thumbnail,
|
SnAttachment? thumbnail,
|
||||||
@ -49,7 +51,8 @@ abstract class SnAttachment with _$SnAttachment {
|
|||||||
@Default({}) Map<String, dynamic> metadata,
|
@Default({}) Map<String, dynamic> metadata,
|
||||||
}) = _SnAttachment;
|
}) = _SnAttachment;
|
||||||
|
|
||||||
factory SnAttachment.fromJson(Map<String, Object?> json) => _$SnAttachmentFromJson(json);
|
factory SnAttachment.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnAttachmentFromJson(json);
|
||||||
|
|
||||||
Map<String, dynamic> get data => {
|
Map<String, dynamic> get data => {
|
||||||
...metadata,
|
...metadata,
|
||||||
@ -85,7 +88,8 @@ abstract class SnAttachmentFragment with _$SnAttachmentFragment {
|
|||||||
@Default([]) List<String> fileChunksMissing,
|
@Default([]) List<String> fileChunksMissing,
|
||||||
}) = _SnAttachmentFragment;
|
}) = _SnAttachmentFragment;
|
||||||
|
|
||||||
factory SnAttachmentFragment.fromJson(Map<String, Object?> json) => _$SnAttachmentFragmentFromJson(json);
|
factory SnAttachmentFragment.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnAttachmentFragmentFromJson(json);
|
||||||
|
|
||||||
SnMediaType get mediaType => switch (mimetype.split('/').firstOrNull) {
|
SnMediaType get mediaType => switch (mimetype.split('/').firstOrNull) {
|
||||||
'image' => SnMediaType.image,
|
'image' => SnMediaType.image,
|
||||||
@ -109,7 +113,8 @@ abstract class SnAttachmentPool with _$SnAttachmentPool {
|
|||||||
required int? accountId,
|
required int? accountId,
|
||||||
}) = _SnAttachmentPool;
|
}) = _SnAttachmentPool;
|
||||||
|
|
||||||
factory SnAttachmentPool.fromJson(Map<String, Object?> json) => _$SnAttachmentPoolFromJson(json);
|
factory SnAttachmentPool.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnAttachmentPoolFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -122,7 +127,8 @@ abstract class SnAttachmentDestination with _$SnAttachmentDestination {
|
|||||||
required bool isBoost,
|
required bool isBoost,
|
||||||
}) = _SnAttachmentDestination;
|
}) = _SnAttachmentDestination;
|
||||||
|
|
||||||
factory SnAttachmentDestination.fromJson(Map<String, Object?> json) => _$SnAttachmentDestinationFromJson(json);
|
factory SnAttachmentDestination.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnAttachmentDestinationFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -139,7 +145,8 @@ abstract class SnAttachmentBoost with _$SnAttachmentBoost {
|
|||||||
required int account,
|
required int account,
|
||||||
}) = _SnAttachmentBoost;
|
}) = _SnAttachmentBoost;
|
||||||
|
|
||||||
factory SnAttachmentBoost.fromJson(Map<String, Object?> json) => _$SnAttachmentBoostFromJson(json);
|
factory SnAttachmentBoost.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnAttachmentBoostFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -158,7 +165,8 @@ abstract class SnSticker with _$SnSticker {
|
|||||||
required int accountId,
|
required int accountId,
|
||||||
}) = _SnSticker;
|
}) = _SnSticker;
|
||||||
|
|
||||||
factory SnSticker.fromJson(Map<String, Object?> json) => _$SnStickerFromJson(json);
|
factory SnSticker.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnStickerFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -175,7 +183,8 @@ abstract class SnStickerPack with _$SnStickerPack {
|
|||||||
required int accountId,
|
required int accountId,
|
||||||
}) = _SnStickerPack;
|
}) = _SnStickerPack;
|
||||||
|
|
||||||
factory SnStickerPack.fromJson(Map<String, Object?> json) => _$SnStickerPackFromJson(json);
|
factory SnStickerPack.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnStickerPackFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -186,5 +195,6 @@ abstract class SnAttachmentBilling with _$SnAttachmentBilling {
|
|||||||
required double includedRatio,
|
required double includedRatio,
|
||||||
}) = _SnAttachmentBilling;
|
}) = _SnAttachmentBilling;
|
||||||
|
|
||||||
factory SnAttachmentBilling.fromJson(Map<String, Object?> json) => _$SnAttachmentBillingFromJson(json);
|
factory SnAttachmentBilling.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnAttachmentBillingFromJson(json);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ mixin _$SnAttachment {
|
|||||||
int? get refId;
|
int? get refId;
|
||||||
SnAttachmentPool? get pool;
|
SnAttachmentPool? get pool;
|
||||||
int? get poolId;
|
int? get poolId;
|
||||||
|
SnAccount? get account;
|
||||||
int get accountId;
|
int get accountId;
|
||||||
int? get thumbnailId;
|
int? get thumbnailId;
|
||||||
SnAttachment? get thumbnail;
|
SnAttachment? get thumbnail;
|
||||||
@ -98,6 +99,7 @@ mixin _$SnAttachment {
|
|||||||
(identical(other.refId, refId) || other.refId == refId) &&
|
(identical(other.refId, refId) || other.refId == refId) &&
|
||||||
(identical(other.pool, pool) || other.pool == pool) &&
|
(identical(other.pool, pool) || other.pool == pool) &&
|
||||||
(identical(other.poolId, poolId) || other.poolId == poolId) &&
|
(identical(other.poolId, poolId) || other.poolId == poolId) &&
|
||||||
|
(identical(other.account, account) || other.account == account) &&
|
||||||
(identical(other.accountId, accountId) ||
|
(identical(other.accountId, accountId) ||
|
||||||
other.accountId == accountId) &&
|
other.accountId == accountId) &&
|
||||||
(identical(other.thumbnailId, thumbnailId) ||
|
(identical(other.thumbnailId, thumbnailId) ||
|
||||||
@ -140,6 +142,7 @@ mixin _$SnAttachment {
|
|||||||
refId,
|
refId,
|
||||||
pool,
|
pool,
|
||||||
poolId,
|
poolId,
|
||||||
|
account,
|
||||||
accountId,
|
accountId,
|
||||||
thumbnailId,
|
thumbnailId,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
@ -152,7 +155,7 @@ mixin _$SnAttachment {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isSelfRef: $isSelfRef, isIndexable: $isIndexable, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, accountId: $accountId, thumbnailId: $thumbnailId, thumbnail: $thumbnail, compressedId: $compressedId, compressed: $compressed, boosts: $boosts, usermeta: $usermeta, metadata: $metadata)';
|
return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isSelfRef: $isSelfRef, isIndexable: $isIndexable, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, account: $account, accountId: $accountId, thumbnailId: $thumbnailId, thumbnail: $thumbnail, compressedId: $compressedId, compressed: $compressed, boosts: $boosts, usermeta: $usermeta, metadata: $metadata)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +189,7 @@ abstract mixin class $SnAttachmentCopyWith<$Res> {
|
|||||||
int? refId,
|
int? refId,
|
||||||
SnAttachmentPool? pool,
|
SnAttachmentPool? pool,
|
||||||
int? poolId,
|
int? poolId,
|
||||||
|
SnAccount? account,
|
||||||
int accountId,
|
int accountId,
|
||||||
int? thumbnailId,
|
int? thumbnailId,
|
||||||
SnAttachment? thumbnail,
|
SnAttachment? thumbnail,
|
||||||
@ -197,6 +201,7 @@ abstract mixin class $SnAttachmentCopyWith<$Res> {
|
|||||||
|
|
||||||
$SnAttachmentCopyWith<$Res>? get ref;
|
$SnAttachmentCopyWith<$Res>? get ref;
|
||||||
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
$SnAttachmentCopyWith<$Res>? get thumbnail;
|
$SnAttachmentCopyWith<$Res>? get thumbnail;
|
||||||
$SnAttachmentCopyWith<$Res>? get compressed;
|
$SnAttachmentCopyWith<$Res>? get compressed;
|
||||||
}
|
}
|
||||||
@ -236,6 +241,7 @@ class _$SnAttachmentCopyWithImpl<$Res> implements $SnAttachmentCopyWith<$Res> {
|
|||||||
Object? refId = freezed,
|
Object? refId = freezed,
|
||||||
Object? pool = freezed,
|
Object? pool = freezed,
|
||||||
Object? poolId = freezed,
|
Object? poolId = freezed,
|
||||||
|
Object? account = freezed,
|
||||||
Object? accountId = null,
|
Object? accountId = null,
|
||||||
Object? thumbnailId = freezed,
|
Object? thumbnailId = freezed,
|
||||||
Object? thumbnail = freezed,
|
Object? thumbnail = freezed,
|
||||||
@ -338,6 +344,10 @@ class _$SnAttachmentCopyWithImpl<$Res> implements $SnAttachmentCopyWith<$Res> {
|
|||||||
? _self.poolId
|
? _self.poolId
|
||||||
: poolId // ignore: cast_nullable_to_non_nullable
|
: poolId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
account: freezed == account
|
||||||
|
? _self.account
|
||||||
|
: account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
accountId: null == accountId
|
accountId: null == accountId
|
||||||
? _self.accountId
|
? _self.accountId
|
||||||
: accountId // ignore: cast_nullable_to_non_nullable
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
@ -401,6 +411,20 @@ class _$SnAttachmentCopyWithImpl<$Res> implements $SnAttachmentCopyWith<$Res> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnAttachment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a copy of SnAttachment
|
/// Create a copy of SnAttachment
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@ -457,6 +481,7 @@ class _SnAttachment extends SnAttachment {
|
|||||||
required this.refId,
|
required this.refId,
|
||||||
required this.pool,
|
required this.pool,
|
||||||
required this.poolId,
|
required this.poolId,
|
||||||
|
required this.account,
|
||||||
required this.accountId,
|
required this.accountId,
|
||||||
this.thumbnailId,
|
this.thumbnailId,
|
||||||
this.thumbnail,
|
this.thumbnail,
|
||||||
@ -521,6 +546,8 @@ class _SnAttachment extends SnAttachment {
|
|||||||
@override
|
@override
|
||||||
final int? poolId;
|
final int? poolId;
|
||||||
@override
|
@override
|
||||||
|
final SnAccount? account;
|
||||||
|
@override
|
||||||
final int accountId;
|
final int accountId;
|
||||||
@override
|
@override
|
||||||
final int? thumbnailId;
|
final int? thumbnailId;
|
||||||
@ -612,6 +639,7 @@ class _SnAttachment extends SnAttachment {
|
|||||||
(identical(other.refId, refId) || other.refId == refId) &&
|
(identical(other.refId, refId) || other.refId == refId) &&
|
||||||
(identical(other.pool, pool) || other.pool == pool) &&
|
(identical(other.pool, pool) || other.pool == pool) &&
|
||||||
(identical(other.poolId, poolId) || other.poolId == poolId) &&
|
(identical(other.poolId, poolId) || other.poolId == poolId) &&
|
||||||
|
(identical(other.account, account) || other.account == account) &&
|
||||||
(identical(other.accountId, accountId) ||
|
(identical(other.accountId, accountId) ||
|
||||||
other.accountId == accountId) &&
|
other.accountId == accountId) &&
|
||||||
(identical(other.thumbnailId, thumbnailId) ||
|
(identical(other.thumbnailId, thumbnailId) ||
|
||||||
@ -654,6 +682,7 @@ class _SnAttachment extends SnAttachment {
|
|||||||
refId,
|
refId,
|
||||||
pool,
|
pool,
|
||||||
poolId,
|
poolId,
|
||||||
|
account,
|
||||||
accountId,
|
accountId,
|
||||||
thumbnailId,
|
thumbnailId,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
@ -666,7 +695,7 @@ class _SnAttachment extends SnAttachment {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isSelfRef: $isSelfRef, isIndexable: $isIndexable, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, accountId: $accountId, thumbnailId: $thumbnailId, thumbnail: $thumbnail, compressedId: $compressedId, compressed: $compressed, boosts: $boosts, usermeta: $usermeta, metadata: $metadata)';
|
return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isSelfRef: $isSelfRef, isIndexable: $isIndexable, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, account: $account, accountId: $accountId, thumbnailId: $thumbnailId, thumbnail: $thumbnail, compressedId: $compressedId, compressed: $compressed, boosts: $boosts, usermeta: $usermeta, metadata: $metadata)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,6 +731,7 @@ abstract mixin class _$SnAttachmentCopyWith<$Res>
|
|||||||
int? refId,
|
int? refId,
|
||||||
SnAttachmentPool? pool,
|
SnAttachmentPool? pool,
|
||||||
int? poolId,
|
int? poolId,
|
||||||
|
SnAccount? account,
|
||||||
int accountId,
|
int accountId,
|
||||||
int? thumbnailId,
|
int? thumbnailId,
|
||||||
SnAttachment? thumbnail,
|
SnAttachment? thumbnail,
|
||||||
@ -716,6 +746,8 @@ abstract mixin class _$SnAttachmentCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
||||||
@override
|
@override
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
|
@override
|
||||||
$SnAttachmentCopyWith<$Res>? get thumbnail;
|
$SnAttachmentCopyWith<$Res>? get thumbnail;
|
||||||
@override
|
@override
|
||||||
$SnAttachmentCopyWith<$Res>? get compressed;
|
$SnAttachmentCopyWith<$Res>? get compressed;
|
||||||
@ -757,6 +789,7 @@ class __$SnAttachmentCopyWithImpl<$Res>
|
|||||||
Object? refId = freezed,
|
Object? refId = freezed,
|
||||||
Object? pool = freezed,
|
Object? pool = freezed,
|
||||||
Object? poolId = freezed,
|
Object? poolId = freezed,
|
||||||
|
Object? account = freezed,
|
||||||
Object? accountId = null,
|
Object? accountId = null,
|
||||||
Object? thumbnailId = freezed,
|
Object? thumbnailId = freezed,
|
||||||
Object? thumbnail = freezed,
|
Object? thumbnail = freezed,
|
||||||
@ -859,6 +892,10 @@ class __$SnAttachmentCopyWithImpl<$Res>
|
|||||||
? _self.poolId
|
? _self.poolId
|
||||||
: poolId // ignore: cast_nullable_to_non_nullable
|
: poolId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
account: freezed == account
|
||||||
|
? _self.account
|
||||||
|
: account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
accountId: null == accountId
|
accountId: null == accountId
|
||||||
? _self.accountId
|
? _self.accountId
|
||||||
: accountId // ignore: cast_nullable_to_non_nullable
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
@ -922,6 +959,20 @@ class __$SnAttachmentCopyWithImpl<$Res>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnAttachment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a copy of SnAttachment
|
/// Create a copy of SnAttachment
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
|
@ -39,6 +39,9 @@ _SnAttachment _$SnAttachmentFromJson(Map<String, dynamic> json) =>
|
|||||||
? null
|
? null
|
||||||
: SnAttachmentPool.fromJson(json['pool'] as Map<String, dynamic>),
|
: SnAttachmentPool.fromJson(json['pool'] as Map<String, dynamic>),
|
||||||
poolId: (json['pool_id'] as num?)?.toInt(),
|
poolId: (json['pool_id'] as num?)?.toInt(),
|
||||||
|
account: json['account'] == null
|
||||||
|
? null
|
||||||
|
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
accountId: (json['account_id'] as num).toInt(),
|
accountId: (json['account_id'] as num).toInt(),
|
||||||
thumbnailId: (json['thumbnail_id'] as num?)?.toInt(),
|
thumbnailId: (json['thumbnail_id'] as num?)?.toInt(),
|
||||||
thumbnail: json['thumbnail'] == null
|
thumbnail: json['thumbnail'] == null
|
||||||
@ -82,6 +85,7 @@ Map<String, dynamic> _$SnAttachmentToJson(_SnAttachment instance) =>
|
|||||||
'ref_id': instance.refId,
|
'ref_id': instance.refId,
|
||||||
'pool': instance.pool?.toJson(),
|
'pool': instance.pool?.toJson(),
|
||||||
'pool_id': instance.poolId,
|
'pool_id': instance.poolId,
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
'thumbnail_id': instance.thumbnailId,
|
'thumbnail_id': instance.thumbnailId,
|
||||||
'thumbnail': instance.thumbnail?.toJson(),
|
'thumbnail': instance.thumbnail?.toJson(),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:surface/types/account.dart';
|
||||||
import 'package:surface/types/attachment.dart';
|
import 'package:surface/types/attachment.dart';
|
||||||
import 'package:surface/types/poll.dart';
|
import 'package:surface/types/poll.dart';
|
||||||
import 'package:surface/types/realm.dart';
|
import 'package:surface/types/realm.dart';
|
||||||
@ -26,6 +27,7 @@ abstract class SnPost with _$SnPost {
|
|||||||
required int? replyId,
|
required int? replyId,
|
||||||
required int? repostId,
|
required int? repostId,
|
||||||
required int? realmId,
|
required int? realmId,
|
||||||
|
required SnRealm? realm,
|
||||||
required SnPost? replyTo,
|
required SnPost? replyTo,
|
||||||
required SnPost? repostTo,
|
required SnPost? repostTo,
|
||||||
required List<int>? visibleUsersList,
|
required List<int>? visibleUsersList,
|
||||||
@ -43,9 +45,9 @@ abstract class SnPost with _$SnPost {
|
|||||||
@Default(0) int totalAggregatedViews,
|
@Default(0) int totalAggregatedViews,
|
||||||
required int publisherId,
|
required int publisherId,
|
||||||
required int? pollId,
|
required int? pollId,
|
||||||
|
required SnPoll? poll,
|
||||||
required SnPublisher publisher,
|
required SnPublisher publisher,
|
||||||
required SnMetric metric,
|
required SnMetric metric,
|
||||||
SnPostPreload? preload,
|
|
||||||
}) = _SnPost;
|
}) = _SnPost;
|
||||||
|
|
||||||
factory SnPost.fromJson(Map<String, Object?> json) => _$SnPostFromJson(json);
|
factory SnPost.fromJson(Map<String, Object?> json) => _$SnPostFromJson(json);
|
||||||
@ -146,6 +148,7 @@ abstract class SnPublisher with _$SnPublisher {
|
|||||||
required int totalDownvote,
|
required int totalDownvote,
|
||||||
required int? realmId,
|
required int? realmId,
|
||||||
required int accountId,
|
required int accountId,
|
||||||
|
required SnAccount? account,
|
||||||
}) = _SnPublisher;
|
}) = _SnPublisher;
|
||||||
|
|
||||||
factory SnPublisher.fromJson(Map<String, Object?> json) =>
|
factory SnPublisher.fromJson(Map<String, Object?> json) =>
|
||||||
|
@ -30,6 +30,7 @@ mixin _$SnPost {
|
|||||||
int? get replyId;
|
int? get replyId;
|
||||||
int? get repostId;
|
int? get repostId;
|
||||||
int? get realmId;
|
int? get realmId;
|
||||||
|
SnRealm? get realm;
|
||||||
SnPost? get replyTo;
|
SnPost? get replyTo;
|
||||||
SnPost? get repostTo;
|
SnPost? get repostTo;
|
||||||
List<int>? get visibleUsersList;
|
List<int>? get visibleUsersList;
|
||||||
@ -47,9 +48,9 @@ mixin _$SnPost {
|
|||||||
int get totalAggregatedViews;
|
int get totalAggregatedViews;
|
||||||
int get publisherId;
|
int get publisherId;
|
||||||
int? get pollId;
|
int? get pollId;
|
||||||
|
SnPoll? get poll;
|
||||||
SnPublisher get publisher;
|
SnPublisher get publisher;
|
||||||
SnMetric get metric;
|
SnMetric get metric;
|
||||||
SnPostPreload? get preload;
|
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -88,6 +89,7 @@ mixin _$SnPost {
|
|||||||
(identical(other.repostId, repostId) ||
|
(identical(other.repostId, repostId) ||
|
||||||
other.repostId == repostId) &&
|
other.repostId == repostId) &&
|
||||||
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
||||||
|
(identical(other.realm, realm) || other.realm == realm) &&
|
||||||
(identical(other.replyTo, replyTo) || other.replyTo == replyTo) &&
|
(identical(other.replyTo, replyTo) || other.replyTo == replyTo) &&
|
||||||
(identical(other.repostTo, repostTo) ||
|
(identical(other.repostTo, repostTo) ||
|
||||||
other.repostTo == repostTo) &&
|
other.repostTo == repostTo) &&
|
||||||
@ -119,10 +121,10 @@ mixin _$SnPost {
|
|||||||
(identical(other.publisherId, publisherId) ||
|
(identical(other.publisherId, publisherId) ||
|
||||||
other.publisherId == publisherId) &&
|
other.publisherId == publisherId) &&
|
||||||
(identical(other.pollId, pollId) || other.pollId == pollId) &&
|
(identical(other.pollId, pollId) || other.pollId == pollId) &&
|
||||||
|
(identical(other.poll, poll) || other.poll == poll) &&
|
||||||
(identical(other.publisher, publisher) ||
|
(identical(other.publisher, publisher) ||
|
||||||
other.publisher == publisher) &&
|
other.publisher == publisher) &&
|
||||||
(identical(other.metric, metric) || other.metric == metric) &&
|
(identical(other.metric, metric) || other.metric == metric));
|
||||||
(identical(other.preload, preload) || other.preload == preload));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -144,6 +146,7 @@ mixin _$SnPost {
|
|||||||
replyId,
|
replyId,
|
||||||
repostId,
|
repostId,
|
||||||
realmId,
|
realmId,
|
||||||
|
realm,
|
||||||
replyTo,
|
replyTo,
|
||||||
repostTo,
|
repostTo,
|
||||||
const DeepCollectionEquality().hash(visibleUsersList),
|
const DeepCollectionEquality().hash(visibleUsersList),
|
||||||
@ -161,14 +164,14 @@ mixin _$SnPost {
|
|||||||
totalAggregatedViews,
|
totalAggregatedViews,
|
||||||
publisherId,
|
publisherId,
|
||||||
pollId,
|
pollId,
|
||||||
|
poll,
|
||||||
publisher,
|
publisher,
|
||||||
metric,
|
metric
|
||||||
preload
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, body: $body, language: $language, alias: $alias, aliasPrefix: $aliasPrefix, tags: $tags, categories: $categories, replies: $replies, replyId: $replyId, repostId: $repostId, realmId: $realmId, replyTo: $replyTo, repostTo: $repostTo, visibleUsersList: $visibleUsersList, invisibleUsersList: $invisibleUsersList, visibility: $visibility, editedAt: $editedAt, pinnedAt: $pinnedAt, lockedAt: $lockedAt, isDraft: $isDraft, publishedAt: $publishedAt, publishedUntil: $publishedUntil, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, totalViews: $totalViews, totalAggregatedViews: $totalAggregatedViews, publisherId: $publisherId, pollId: $pollId, publisher: $publisher, metric: $metric, preload: $preload)';
|
return 'SnPost(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, body: $body, language: $language, alias: $alias, aliasPrefix: $aliasPrefix, tags: $tags, categories: $categories, replies: $replies, replyId: $replyId, repostId: $repostId, realmId: $realmId, realm: $realm, replyTo: $replyTo, repostTo: $repostTo, visibleUsersList: $visibleUsersList, invisibleUsersList: $invisibleUsersList, visibility: $visibility, editedAt: $editedAt, pinnedAt: $pinnedAt, lockedAt: $lockedAt, isDraft: $isDraft, publishedAt: $publishedAt, publishedUntil: $publishedUntil, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, totalViews: $totalViews, totalAggregatedViews: $totalAggregatedViews, publisherId: $publisherId, pollId: $pollId, poll: $poll, publisher: $publisher, metric: $metric)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +196,7 @@ abstract mixin class $SnPostCopyWith<$Res> {
|
|||||||
int? replyId,
|
int? replyId,
|
||||||
int? repostId,
|
int? repostId,
|
||||||
int? realmId,
|
int? realmId,
|
||||||
|
SnRealm? realm,
|
||||||
SnPost? replyTo,
|
SnPost? replyTo,
|
||||||
SnPost? repostTo,
|
SnPost? repostTo,
|
||||||
List<int>? visibleUsersList,
|
List<int>? visibleUsersList,
|
||||||
@ -210,15 +214,16 @@ abstract mixin class $SnPostCopyWith<$Res> {
|
|||||||
int totalAggregatedViews,
|
int totalAggregatedViews,
|
||||||
int publisherId,
|
int publisherId,
|
||||||
int? pollId,
|
int? pollId,
|
||||||
|
SnPoll? poll,
|
||||||
SnPublisher publisher,
|
SnPublisher publisher,
|
||||||
SnMetric metric,
|
SnMetric metric});
|
||||||
SnPostPreload? preload});
|
|
||||||
|
|
||||||
|
$SnRealmCopyWith<$Res>? get realm;
|
||||||
$SnPostCopyWith<$Res>? get replyTo;
|
$SnPostCopyWith<$Res>? get replyTo;
|
||||||
$SnPostCopyWith<$Res>? get repostTo;
|
$SnPostCopyWith<$Res>? get repostTo;
|
||||||
|
$SnPollCopyWith<$Res>? get poll;
|
||||||
$SnPublisherCopyWith<$Res> get publisher;
|
$SnPublisherCopyWith<$Res> get publisher;
|
||||||
$SnMetricCopyWith<$Res> get metric;
|
$SnMetricCopyWith<$Res> get metric;
|
||||||
$SnPostPreloadCopyWith<$Res>? get preload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -248,6 +253,7 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
Object? replyId = freezed,
|
Object? replyId = freezed,
|
||||||
Object? repostId = freezed,
|
Object? repostId = freezed,
|
||||||
Object? realmId = freezed,
|
Object? realmId = freezed,
|
||||||
|
Object? realm = freezed,
|
||||||
Object? replyTo = freezed,
|
Object? replyTo = freezed,
|
||||||
Object? repostTo = freezed,
|
Object? repostTo = freezed,
|
||||||
Object? visibleUsersList = freezed,
|
Object? visibleUsersList = freezed,
|
||||||
@ -265,9 +271,9 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
Object? totalAggregatedViews = null,
|
Object? totalAggregatedViews = null,
|
||||||
Object? publisherId = null,
|
Object? publisherId = null,
|
||||||
Object? pollId = freezed,
|
Object? pollId = freezed,
|
||||||
|
Object? poll = freezed,
|
||||||
Object? publisher = null,
|
Object? publisher = null,
|
||||||
Object? metric = null,
|
Object? metric = null,
|
||||||
Object? preload = freezed,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id
|
id: null == id
|
||||||
@ -330,6 +336,10 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
? _self.realmId
|
? _self.realmId
|
||||||
: realmId // ignore: cast_nullable_to_non_nullable
|
: realmId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
realm: freezed == realm
|
||||||
|
? _self.realm
|
||||||
|
: realm // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnRealm?,
|
||||||
replyTo: freezed == replyTo
|
replyTo: freezed == replyTo
|
||||||
? _self.replyTo
|
? _self.replyTo
|
||||||
: replyTo // ignore: cast_nullable_to_non_nullable
|
: replyTo // ignore: cast_nullable_to_non_nullable
|
||||||
@ -398,6 +408,10 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
? _self.pollId
|
? _self.pollId
|
||||||
: pollId // ignore: cast_nullable_to_non_nullable
|
: pollId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
poll: freezed == poll
|
||||||
|
? _self.poll
|
||||||
|
: poll // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnPoll?,
|
||||||
publisher: null == publisher
|
publisher: null == publisher
|
||||||
? _self.publisher
|
? _self.publisher
|
||||||
: publisher // ignore: cast_nullable_to_non_nullable
|
: publisher // ignore: cast_nullable_to_non_nullable
|
||||||
@ -406,13 +420,23 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
? _self.metric
|
? _self.metric
|
||||||
: metric // ignore: cast_nullable_to_non_nullable
|
: metric // ignore: cast_nullable_to_non_nullable
|
||||||
as SnMetric,
|
as SnMetric,
|
||||||
preload: freezed == preload
|
|
||||||
? _self.preload
|
|
||||||
: preload // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnPostPreload?,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPost
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnRealmCopyWith<$Res>? get realm {
|
||||||
|
if (_self.realm == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnRealmCopyWith<$Res>(_self.realm!, (value) {
|
||||||
|
return _then(_self.copyWith(realm: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@ -441,6 +465,20 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPost
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPollCopyWith<$Res>? get poll {
|
||||||
|
if (_self.poll == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnPollCopyWith<$Res>(_self.poll!, (value) {
|
||||||
|
return _then(_self.copyWith(poll: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@ -460,20 +498,6 @@ class _$SnPostCopyWithImpl<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
return _then(_self.copyWith(metric: value));
|
return _then(_self.copyWith(metric: value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SnPostPreloadCopyWith<$Res>? get preload {
|
|
||||||
if (_self.preload == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SnPostPreloadCopyWith<$Res>(_self.preload!, (value) {
|
|
||||||
return _then(_self.copyWith(preload: value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -495,6 +519,7 @@ class _SnPost extends SnPost {
|
|||||||
required this.replyId,
|
required this.replyId,
|
||||||
required this.repostId,
|
required this.repostId,
|
||||||
required this.realmId,
|
required this.realmId,
|
||||||
|
required this.realm,
|
||||||
required this.replyTo,
|
required this.replyTo,
|
||||||
required this.repostTo,
|
required this.repostTo,
|
||||||
required final List<int>? visibleUsersList,
|
required final List<int>? visibleUsersList,
|
||||||
@ -512,9 +537,9 @@ class _SnPost extends SnPost {
|
|||||||
this.totalAggregatedViews = 0,
|
this.totalAggregatedViews = 0,
|
||||||
required this.publisherId,
|
required this.publisherId,
|
||||||
required this.pollId,
|
required this.pollId,
|
||||||
|
required this.poll,
|
||||||
required this.publisher,
|
required this.publisher,
|
||||||
required this.metric,
|
required this.metric})
|
||||||
this.preload})
|
|
||||||
: _body = body,
|
: _body = body,
|
||||||
_tags = tags,
|
_tags = tags,
|
||||||
_categories = categories,
|
_categories = categories,
|
||||||
@ -583,6 +608,8 @@ class _SnPost extends SnPost {
|
|||||||
@override
|
@override
|
||||||
final int? realmId;
|
final int? realmId;
|
||||||
@override
|
@override
|
||||||
|
final SnRealm? realm;
|
||||||
|
@override
|
||||||
final SnPost? replyTo;
|
final SnPost? replyTo;
|
||||||
@override
|
@override
|
||||||
final SnPost? repostTo;
|
final SnPost? repostTo;
|
||||||
@ -637,11 +664,11 @@ class _SnPost extends SnPost {
|
|||||||
@override
|
@override
|
||||||
final int? pollId;
|
final int? pollId;
|
||||||
@override
|
@override
|
||||||
|
final SnPoll? poll;
|
||||||
|
@override
|
||||||
final SnPublisher publisher;
|
final SnPublisher publisher;
|
||||||
@override
|
@override
|
||||||
final SnMetric metric;
|
final SnMetric metric;
|
||||||
@override
|
|
||||||
final SnPostPreload? preload;
|
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -685,6 +712,7 @@ class _SnPost extends SnPost {
|
|||||||
(identical(other.repostId, repostId) ||
|
(identical(other.repostId, repostId) ||
|
||||||
other.repostId == repostId) &&
|
other.repostId == repostId) &&
|
||||||
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
||||||
|
(identical(other.realm, realm) || other.realm == realm) &&
|
||||||
(identical(other.replyTo, replyTo) || other.replyTo == replyTo) &&
|
(identical(other.replyTo, replyTo) || other.replyTo == replyTo) &&
|
||||||
(identical(other.repostTo, repostTo) ||
|
(identical(other.repostTo, repostTo) ||
|
||||||
other.repostTo == repostTo) &&
|
other.repostTo == repostTo) &&
|
||||||
@ -716,10 +744,10 @@ class _SnPost extends SnPost {
|
|||||||
(identical(other.publisherId, publisherId) ||
|
(identical(other.publisherId, publisherId) ||
|
||||||
other.publisherId == publisherId) &&
|
other.publisherId == publisherId) &&
|
||||||
(identical(other.pollId, pollId) || other.pollId == pollId) &&
|
(identical(other.pollId, pollId) || other.pollId == pollId) &&
|
||||||
|
(identical(other.poll, poll) || other.poll == poll) &&
|
||||||
(identical(other.publisher, publisher) ||
|
(identical(other.publisher, publisher) ||
|
||||||
other.publisher == publisher) &&
|
other.publisher == publisher) &&
|
||||||
(identical(other.metric, metric) || other.metric == metric) &&
|
(identical(other.metric, metric) || other.metric == metric));
|
||||||
(identical(other.preload, preload) || other.preload == preload));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -741,6 +769,7 @@ class _SnPost extends SnPost {
|
|||||||
replyId,
|
replyId,
|
||||||
repostId,
|
repostId,
|
||||||
realmId,
|
realmId,
|
||||||
|
realm,
|
||||||
replyTo,
|
replyTo,
|
||||||
repostTo,
|
repostTo,
|
||||||
const DeepCollectionEquality().hash(_visibleUsersList),
|
const DeepCollectionEquality().hash(_visibleUsersList),
|
||||||
@ -758,14 +787,14 @@ class _SnPost extends SnPost {
|
|||||||
totalAggregatedViews,
|
totalAggregatedViews,
|
||||||
publisherId,
|
publisherId,
|
||||||
pollId,
|
pollId,
|
||||||
|
poll,
|
||||||
publisher,
|
publisher,
|
||||||
metric,
|
metric
|
||||||
preload
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, body: $body, language: $language, alias: $alias, aliasPrefix: $aliasPrefix, tags: $tags, categories: $categories, replies: $replies, replyId: $replyId, repostId: $repostId, realmId: $realmId, replyTo: $replyTo, repostTo: $repostTo, visibleUsersList: $visibleUsersList, invisibleUsersList: $invisibleUsersList, visibility: $visibility, editedAt: $editedAt, pinnedAt: $pinnedAt, lockedAt: $lockedAt, isDraft: $isDraft, publishedAt: $publishedAt, publishedUntil: $publishedUntil, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, totalViews: $totalViews, totalAggregatedViews: $totalAggregatedViews, publisherId: $publisherId, pollId: $pollId, publisher: $publisher, metric: $metric, preload: $preload)';
|
return 'SnPost(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, body: $body, language: $language, alias: $alias, aliasPrefix: $aliasPrefix, tags: $tags, categories: $categories, replies: $replies, replyId: $replyId, repostId: $repostId, realmId: $realmId, realm: $realm, replyTo: $replyTo, repostTo: $repostTo, visibleUsersList: $visibleUsersList, invisibleUsersList: $invisibleUsersList, visibility: $visibility, editedAt: $editedAt, pinnedAt: $pinnedAt, lockedAt: $lockedAt, isDraft: $isDraft, publishedAt: $publishedAt, publishedUntil: $publishedUntil, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, totalViews: $totalViews, totalAggregatedViews: $totalAggregatedViews, publisherId: $publisherId, pollId: $pollId, poll: $poll, publisher: $publisher, metric: $metric)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,6 +820,7 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
int? replyId,
|
int? replyId,
|
||||||
int? repostId,
|
int? repostId,
|
||||||
int? realmId,
|
int? realmId,
|
||||||
|
SnRealm? realm,
|
||||||
SnPost? replyTo,
|
SnPost? replyTo,
|
||||||
SnPost? repostTo,
|
SnPost? repostTo,
|
||||||
List<int>? visibleUsersList,
|
List<int>? visibleUsersList,
|
||||||
@ -808,20 +838,22 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
int totalAggregatedViews,
|
int totalAggregatedViews,
|
||||||
int publisherId,
|
int publisherId,
|
||||||
int? pollId,
|
int? pollId,
|
||||||
|
SnPoll? poll,
|
||||||
SnPublisher publisher,
|
SnPublisher publisher,
|
||||||
SnMetric metric,
|
SnMetric metric});
|
||||||
SnPostPreload? preload});
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
$SnRealmCopyWith<$Res>? get realm;
|
||||||
@override
|
@override
|
||||||
$SnPostCopyWith<$Res>? get replyTo;
|
$SnPostCopyWith<$Res>? get replyTo;
|
||||||
@override
|
@override
|
||||||
$SnPostCopyWith<$Res>? get repostTo;
|
$SnPostCopyWith<$Res>? get repostTo;
|
||||||
@override
|
@override
|
||||||
|
$SnPollCopyWith<$Res>? get poll;
|
||||||
|
@override
|
||||||
$SnPublisherCopyWith<$Res> get publisher;
|
$SnPublisherCopyWith<$Res> get publisher;
|
||||||
@override
|
@override
|
||||||
$SnMetricCopyWith<$Res> get metric;
|
$SnMetricCopyWith<$Res> get metric;
|
||||||
@override
|
|
||||||
$SnPostPreloadCopyWith<$Res>? get preload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -851,6 +883,7 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
Object? replyId = freezed,
|
Object? replyId = freezed,
|
||||||
Object? repostId = freezed,
|
Object? repostId = freezed,
|
||||||
Object? realmId = freezed,
|
Object? realmId = freezed,
|
||||||
|
Object? realm = freezed,
|
||||||
Object? replyTo = freezed,
|
Object? replyTo = freezed,
|
||||||
Object? repostTo = freezed,
|
Object? repostTo = freezed,
|
||||||
Object? visibleUsersList = freezed,
|
Object? visibleUsersList = freezed,
|
||||||
@ -868,9 +901,9 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
Object? totalAggregatedViews = null,
|
Object? totalAggregatedViews = null,
|
||||||
Object? publisherId = null,
|
Object? publisherId = null,
|
||||||
Object? pollId = freezed,
|
Object? pollId = freezed,
|
||||||
|
Object? poll = freezed,
|
||||||
Object? publisher = null,
|
Object? publisher = null,
|
||||||
Object? metric = null,
|
Object? metric = null,
|
||||||
Object? preload = freezed,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_SnPost(
|
return _then(_SnPost(
|
||||||
id: null == id
|
id: null == id
|
||||||
@ -933,6 +966,10 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
? _self.realmId
|
? _self.realmId
|
||||||
: realmId // ignore: cast_nullable_to_non_nullable
|
: realmId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
realm: freezed == realm
|
||||||
|
? _self.realm
|
||||||
|
: realm // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnRealm?,
|
||||||
replyTo: freezed == replyTo
|
replyTo: freezed == replyTo
|
||||||
? _self.replyTo
|
? _self.replyTo
|
||||||
: replyTo // ignore: cast_nullable_to_non_nullable
|
: replyTo // ignore: cast_nullable_to_non_nullable
|
||||||
@ -1001,6 +1038,10 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
? _self.pollId
|
? _self.pollId
|
||||||
: pollId // ignore: cast_nullable_to_non_nullable
|
: pollId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
poll: freezed == poll
|
||||||
|
? _self.poll
|
||||||
|
: poll // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnPoll?,
|
||||||
publisher: null == publisher
|
publisher: null == publisher
|
||||||
? _self.publisher
|
? _self.publisher
|
||||||
: publisher // ignore: cast_nullable_to_non_nullable
|
: publisher // ignore: cast_nullable_to_non_nullable
|
||||||
@ -1009,13 +1050,23 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
? _self.metric
|
? _self.metric
|
||||||
: metric // ignore: cast_nullable_to_non_nullable
|
: metric // ignore: cast_nullable_to_non_nullable
|
||||||
as SnMetric,
|
as SnMetric,
|
||||||
preload: freezed == preload
|
|
||||||
? _self.preload
|
|
||||||
: preload // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnPostPreload?,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPost
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnRealmCopyWith<$Res>? get realm {
|
||||||
|
if (_self.realm == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnRealmCopyWith<$Res>(_self.realm!, (value) {
|
||||||
|
return _then(_self.copyWith(realm: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@ -1044,6 +1095,20 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPost
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPollCopyWith<$Res>? get poll {
|
||||||
|
if (_self.poll == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnPollCopyWith<$Res>(_self.poll!, (value) {
|
||||||
|
return _then(_self.copyWith(poll: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@ -1063,20 +1128,6 @@ class __$SnPostCopyWithImpl<$Res> implements _$SnPostCopyWith<$Res> {
|
|||||||
return _then(_self.copyWith(metric: value));
|
return _then(_self.copyWith(metric: value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of SnPost
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SnPostPreloadCopyWith<$Res>? get preload {
|
|
||||||
if (_self.preload == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SnPostPreloadCopyWith<$Res>(_self.preload!, (value) {
|
|
||||||
return _then(_self.copyWith(preload: value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -2465,6 +2516,7 @@ mixin _$SnPublisher {
|
|||||||
int get totalDownvote;
|
int get totalDownvote;
|
||||||
int? get realmId;
|
int? get realmId;
|
||||||
int get accountId;
|
int get accountId;
|
||||||
|
SnAccount? get account;
|
||||||
|
|
||||||
/// Create a copy of SnPublisher
|
/// Create a copy of SnPublisher
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -2501,7 +2553,8 @@ mixin _$SnPublisher {
|
|||||||
other.totalDownvote == totalDownvote) &&
|
other.totalDownvote == totalDownvote) &&
|
||||||
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
||||||
(identical(other.accountId, accountId) ||
|
(identical(other.accountId, accountId) ||
|
||||||
other.accountId == accountId));
|
other.accountId == accountId) &&
|
||||||
|
(identical(other.account, account) || other.account == account));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -2521,11 +2574,12 @@ mixin _$SnPublisher {
|
|||||||
totalUpvote,
|
totalUpvote,
|
||||||
totalDownvote,
|
totalDownvote,
|
||||||
realmId,
|
realmId,
|
||||||
accountId);
|
accountId,
|
||||||
|
account);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPublisher(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, name: $name, nick: $nick, description: $description, avatar: $avatar, banner: $banner, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, realmId: $realmId, accountId: $accountId)';
|
return 'SnPublisher(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, name: $name, nick: $nick, description: $description, avatar: $avatar, banner: $banner, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, realmId: $realmId, accountId: $accountId, account: $account)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2549,7 +2603,10 @@ abstract mixin class $SnPublisherCopyWith<$Res> {
|
|||||||
int totalUpvote,
|
int totalUpvote,
|
||||||
int totalDownvote,
|
int totalDownvote,
|
||||||
int? realmId,
|
int? realmId,
|
||||||
int accountId});
|
int accountId,
|
||||||
|
SnAccount? account});
|
||||||
|
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -2578,6 +2635,7 @@ class _$SnPublisherCopyWithImpl<$Res> implements $SnPublisherCopyWith<$Res> {
|
|||||||
Object? totalDownvote = null,
|
Object? totalDownvote = null,
|
||||||
Object? realmId = freezed,
|
Object? realmId = freezed,
|
||||||
Object? accountId = null,
|
Object? accountId = null,
|
||||||
|
Object? account = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id
|
id: null == id
|
||||||
@ -2636,8 +2694,26 @@ class _$SnPublisherCopyWithImpl<$Res> implements $SnPublisherCopyWith<$Res> {
|
|||||||
? _self.accountId
|
? _self.accountId
|
||||||
: accountId // ignore: cast_nullable_to_non_nullable
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
account: freezed == account
|
||||||
|
? _self.account
|
||||||
|
: account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPublisher
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -2657,7 +2733,8 @@ class _SnPublisher implements SnPublisher {
|
|||||||
required this.totalUpvote,
|
required this.totalUpvote,
|
||||||
required this.totalDownvote,
|
required this.totalDownvote,
|
||||||
required this.realmId,
|
required this.realmId,
|
||||||
required this.accountId});
|
required this.accountId,
|
||||||
|
required this.account});
|
||||||
factory _SnPublisher.fromJson(Map<String, dynamic> json) =>
|
factory _SnPublisher.fromJson(Map<String, dynamic> json) =>
|
||||||
_$SnPublisherFromJson(json);
|
_$SnPublisherFromJson(json);
|
||||||
|
|
||||||
@ -2689,6 +2766,8 @@ class _SnPublisher implements SnPublisher {
|
|||||||
final int? realmId;
|
final int? realmId;
|
||||||
@override
|
@override
|
||||||
final int accountId;
|
final int accountId;
|
||||||
|
@override
|
||||||
|
final SnAccount? account;
|
||||||
|
|
||||||
/// Create a copy of SnPublisher
|
/// Create a copy of SnPublisher
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -2730,7 +2809,8 @@ class _SnPublisher implements SnPublisher {
|
|||||||
other.totalDownvote == totalDownvote) &&
|
other.totalDownvote == totalDownvote) &&
|
||||||
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
||||||
(identical(other.accountId, accountId) ||
|
(identical(other.accountId, accountId) ||
|
||||||
other.accountId == accountId));
|
other.accountId == accountId) &&
|
||||||
|
(identical(other.account, account) || other.account == account));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -2750,11 +2830,12 @@ class _SnPublisher implements SnPublisher {
|
|||||||
totalUpvote,
|
totalUpvote,
|
||||||
totalDownvote,
|
totalDownvote,
|
||||||
realmId,
|
realmId,
|
||||||
accountId);
|
accountId,
|
||||||
|
account);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPublisher(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, name: $name, nick: $nick, description: $description, avatar: $avatar, banner: $banner, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, realmId: $realmId, accountId: $accountId)';
|
return 'SnPublisher(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, name: $name, nick: $nick, description: $description, avatar: $avatar, banner: $banner, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, realmId: $realmId, accountId: $accountId, account: $account)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2780,7 +2861,11 @@ abstract mixin class _$SnPublisherCopyWith<$Res>
|
|||||||
int totalUpvote,
|
int totalUpvote,
|
||||||
int totalDownvote,
|
int totalDownvote,
|
||||||
int? realmId,
|
int? realmId,
|
||||||
int accountId});
|
int accountId,
|
||||||
|
SnAccount? account});
|
||||||
|
|
||||||
|
@override
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -2809,6 +2894,7 @@ class __$SnPublisherCopyWithImpl<$Res> implements _$SnPublisherCopyWith<$Res> {
|
|||||||
Object? totalDownvote = null,
|
Object? totalDownvote = null,
|
||||||
Object? realmId = freezed,
|
Object? realmId = freezed,
|
||||||
Object? accountId = null,
|
Object? accountId = null,
|
||||||
|
Object? account = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_SnPublisher(
|
return _then(_SnPublisher(
|
||||||
id: null == id
|
id: null == id
|
||||||
@ -2867,8 +2953,26 @@ class __$SnPublisherCopyWithImpl<$Res> implements _$SnPublisherCopyWith<$Res> {
|
|||||||
? _self.accountId
|
? _self.accountId
|
||||||
: accountId // ignore: cast_nullable_to_non_nullable
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
account: freezed == account
|
||||||
|
? _self.account
|
||||||
|
: account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPublisher
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
@ -32,6 +32,9 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
|
|||||||
replyId: (json['reply_id'] as num?)?.toInt(),
|
replyId: (json['reply_id'] as num?)?.toInt(),
|
||||||
repostId: (json['repost_id'] as num?)?.toInt(),
|
repostId: (json['repost_id'] as num?)?.toInt(),
|
||||||
realmId: (json['realm_id'] as num?)?.toInt(),
|
realmId: (json['realm_id'] as num?)?.toInt(),
|
||||||
|
realm: json['realm'] == null
|
||||||
|
? null
|
||||||
|
: SnRealm.fromJson(json['realm'] as Map<String, dynamic>),
|
||||||
replyTo: json['reply_to'] == null
|
replyTo: json['reply_to'] == null
|
||||||
? null
|
? null
|
||||||
: SnPost.fromJson(json['reply_to'] as Map<String, dynamic>),
|
: SnPost.fromJson(json['reply_to'] as Map<String, dynamic>),
|
||||||
@ -68,12 +71,12 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
|
|||||||
(json['total_aggregated_views'] as num?)?.toInt() ?? 0,
|
(json['total_aggregated_views'] as num?)?.toInt() ?? 0,
|
||||||
publisherId: (json['publisher_id'] as num).toInt(),
|
publisherId: (json['publisher_id'] as num).toInt(),
|
||||||
pollId: (json['poll_id'] as num?)?.toInt(),
|
pollId: (json['poll_id'] as num?)?.toInt(),
|
||||||
|
poll: json['poll'] == null
|
||||||
|
? null
|
||||||
|
: SnPoll.fromJson(json['poll'] as Map<String, dynamic>),
|
||||||
publisher:
|
publisher:
|
||||||
SnPublisher.fromJson(json['publisher'] as Map<String, dynamic>),
|
SnPublisher.fromJson(json['publisher'] as Map<String, dynamic>),
|
||||||
metric: SnMetric.fromJson(json['metric'] as Map<String, dynamic>),
|
metric: SnMetric.fromJson(json['metric'] as Map<String, dynamic>),
|
||||||
preload: json['preload'] == null
|
|
||||||
? null
|
|
||||||
: SnPostPreload.fromJson(json['preload'] as Map<String, dynamic>),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
||||||
@ -92,6 +95,7 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
|||||||
'reply_id': instance.replyId,
|
'reply_id': instance.replyId,
|
||||||
'repost_id': instance.repostId,
|
'repost_id': instance.repostId,
|
||||||
'realm_id': instance.realmId,
|
'realm_id': instance.realmId,
|
||||||
|
'realm': instance.realm?.toJson(),
|
||||||
'reply_to': instance.replyTo?.toJson(),
|
'reply_to': instance.replyTo?.toJson(),
|
||||||
'repost_to': instance.repostTo?.toJson(),
|
'repost_to': instance.repostTo?.toJson(),
|
||||||
'visible_users_list': instance.visibleUsersList,
|
'visible_users_list': instance.visibleUsersList,
|
||||||
@ -109,9 +113,9 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
|||||||
'total_aggregated_views': instance.totalAggregatedViews,
|
'total_aggregated_views': instance.totalAggregatedViews,
|
||||||
'publisher_id': instance.publisherId,
|
'publisher_id': instance.publisherId,
|
||||||
'poll_id': instance.pollId,
|
'poll_id': instance.pollId,
|
||||||
|
'poll': instance.poll?.toJson(),
|
||||||
'publisher': instance.publisher.toJson(),
|
'publisher': instance.publisher.toJson(),
|
||||||
'metric': instance.metric.toJson(),
|
'metric': instance.metric.toJson(),
|
||||||
'preload': instance.preload?.toJson(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_SnPostTag _$SnPostTagFromJson(Map<String, dynamic> json) => _SnPostTag(
|
_SnPostTag _$SnPostTagFromJson(Map<String, dynamic> json) => _SnPostTag(
|
||||||
@ -241,6 +245,9 @@ _SnPublisher _$SnPublisherFromJson(Map<String, dynamic> json) => _SnPublisher(
|
|||||||
totalDownvote: (json['total_downvote'] as num).toInt(),
|
totalDownvote: (json['total_downvote'] as num).toInt(),
|
||||||
realmId: (json['realm_id'] as num?)?.toInt(),
|
realmId: (json['realm_id'] as num?)?.toInt(),
|
||||||
accountId: (json['account_id'] as num).toInt(),
|
accountId: (json['account_id'] as num).toInt(),
|
||||||
|
account: json['account'] == null
|
||||||
|
? null
|
||||||
|
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$SnPublisherToJson(_SnPublisher instance) =>
|
Map<String, dynamic> _$SnPublisherToJson(_SnPublisher instance) =>
|
||||||
@ -259,6 +266,7 @@ Map<String, dynamic> _$SnPublisherToJson(_SnPublisher instance) =>
|
|||||||
'total_downvote': instance.totalDownvote,
|
'total_downvote': instance.totalDownvote,
|
||||||
'realm_id': instance.realmId,
|
'realm_id': instance.realmId,
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
};
|
};
|
||||||
|
|
||||||
_SnSubscription _$SnSubscriptionFromJson(Map<String, dynamic> json) =>
|
_SnSubscription _$SnSubscriptionFromJson(Map<String, dynamic> json) =>
|
||||||
|
@ -17,4 +17,5 @@ const Map<String, ReactInfo> kTemplateReactions = {
|
|||||||
'party': ReactInfo(icon: '🎉', attitude: 1),
|
'party': ReactInfo(icon: '🎉', attitude: 1),
|
||||||
'joy': ReactInfo(icon: '🤣', attitude: 1),
|
'joy': ReactInfo(icon: '🤣', attitude: 1),
|
||||||
'pray': ReactInfo(icon: '🙏', attitude: 1),
|
'pray': ReactInfo(icon: '🙏', attitude: 1),
|
||||||
|
'heart': ReactInfo(icon: '❤️', attitude: 1),
|
||||||
};
|
};
|
||||||
|
@ -54,11 +54,15 @@ class AccountImage extends StatelessWidget {
|
|||||||
))
|
))
|
||||||
.center(),
|
.center(),
|
||||||
)
|
)
|
||||||
: AutoResizeUniversalImage(
|
: UniversalImage(
|
||||||
sn.getAttachmentUrl(url),
|
sn.getAttachmentUrl(url),
|
||||||
filterQuality: filterQuality,
|
filterQuality: filterQuality,
|
||||||
key: Key('attachment-${content.hashCode}'),
|
key: Key('attachment-${content.hashCode}'),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
width: (radius != null ? radius! : 20) * 2,
|
||||||
|
height: (radius != null ? radius! : 20) * 2,
|
||||||
|
cacheWidth: (radius != null ? radius! : 20) * 2,
|
||||||
|
cacheHeight: (radius != null ? radius! : 20) * 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -16,7 +16,6 @@ import 'package:photo_view/photo_view_gallery.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/user_directory.dart';
|
|
||||||
import 'package:surface/types/attachment.dart';
|
import 'package:surface/types/attachment.dart';
|
||||||
import 'package:surface/widgets/account/account_image.dart';
|
import 'package:surface/widgets/account/account_image.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
@ -418,8 +417,7 @@ class _AttachmentZoomDetailPopup extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ud = context.read<UserDirectoryProvider>();
|
final account = data.account!;
|
||||||
final account = ud.getFromCache(data.accountId);
|
|
||||||
|
|
||||||
const tableGap = TableRow(
|
const tableGap = TableRow(
|
||||||
children: [
|
children: [
|
||||||
@ -461,12 +459,12 @@ class _AttachmentZoomDetailPopup extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
if (data.accountId > 0)
|
if (data.accountId > 0)
|
||||||
AccountImage(
|
AccountImage(
|
||||||
content: account?.avatar,
|
content: account.avatar,
|
||||||
radius: 8,
|
radius: 8,
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Text(data.accountId > 0
|
Text(data.accountId > 0
|
||||||
? account?.nick ?? 'unknown'.tr()
|
? account.nick
|
||||||
: 'unknown'.tr()),
|
: 'unknown'.tr()),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Text('#${data.accountId}',
|
Text('#${data.accountId}',
|
||||||
|
@ -8,12 +8,12 @@ import 'package:surface/widgets/account/account_image.dart';
|
|||||||
class NoContentWidget extends StatefulWidget {
|
class NoContentWidget extends StatefulWidget {
|
||||||
final SnAccount? userinfo;
|
final SnAccount? userinfo;
|
||||||
final bool isSpeaking;
|
final bool isSpeaking;
|
||||||
final bool isFixed;
|
final double? avatarSize;
|
||||||
|
|
||||||
const NoContentWidget({
|
const NoContentWidget({
|
||||||
super.key,
|
super.key,
|
||||||
this.userinfo,
|
this.userinfo,
|
||||||
this.isFixed = false,
|
this.avatarSize,
|
||||||
required this.isSpeaking,
|
required this.isSpeaking,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -45,17 +45,13 @@ class _NoContentWidgetState extends State<NoContentWidget>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double radius = widget.isFixed
|
final double radius = widget.avatarSize ??
|
||||||
? 32
|
math.min(
|
||||||
: math.min(
|
|
||||||
MediaQuery.of(context).size.width * 0.1,
|
MediaQuery.of(context).size.width * 0.1,
|
||||||
MediaQuery.of(context).size.height * 0.1,
|
MediaQuery.of(context).size.height * 0.1,
|
||||||
);
|
);
|
||||||
|
|
||||||
return Container(
|
return Animate(
|
||||||
alignment: Alignment.center,
|
|
||||||
child: Center(
|
|
||||||
child: Animate(
|
|
||||||
autoPlay: false,
|
autoPlay: false,
|
||||||
controller: _animationController,
|
controller: _animationController,
|
||||||
effects: [
|
effects: [
|
||||||
@ -79,8 +75,6 @@ class _NoContentWidgetState extends State<NoContentWidget>
|
|||||||
content: widget.userinfo?.avatar,
|
content: widget.userinfo?.avatar,
|
||||||
radius: radius,
|
radius: radius,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
import 'package:livekit_client/livekit_client.dart';
|
import 'package:livekit_client/livekit_client.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/types/account.dart';
|
import 'package:surface/types/account.dart';
|
||||||
import 'package:surface/types/chat.dart';
|
import 'package:surface/types/chat.dart';
|
||||||
import 'package:surface/widgets/chat/call/call_no_content.dart';
|
import 'package:surface/widgets/chat/call/call_no_content.dart';
|
||||||
@ -11,23 +13,32 @@ import 'package:surface/widgets/chat/call/call_participant_menu.dart';
|
|||||||
import 'package:surface/widgets/chat/call/call_participant_stats.dart';
|
import 'package:surface/widgets/chat/call/call_participant_stats.dart';
|
||||||
|
|
||||||
abstract class ParticipantWidget extends StatefulWidget {
|
abstract class ParticipantWidget extends StatefulWidget {
|
||||||
static ParticipantWidget widgetFor(ParticipantTrack participantTrack,
|
static ParticipantWidget widgetFor(
|
||||||
{bool isFixed = false, bool showStatsLayer = false}) {
|
ParticipantTrack participantTrack, {
|
||||||
|
double? avatarSize,
|
||||||
|
EdgeInsets? padding,
|
||||||
|
bool showStatsLayer = false,
|
||||||
|
bool isList = false,
|
||||||
|
}) {
|
||||||
if (participantTrack.participant is LocalParticipant) {
|
if (participantTrack.participant is LocalParticipant) {
|
||||||
return LocalParticipantWidget(
|
return LocalParticipantWidget(
|
||||||
participantTrack.participant as LocalParticipant,
|
participantTrack.participant as LocalParticipant,
|
||||||
participantTrack.videoTrack,
|
participantTrack.videoTrack,
|
||||||
isFixed,
|
avatarSize,
|
||||||
participantTrack.isScreenShare,
|
participantTrack.isScreenShare,
|
||||||
showStatsLayer,
|
showStatsLayer,
|
||||||
|
isList,
|
||||||
|
padding,
|
||||||
);
|
);
|
||||||
} else if (participantTrack.participant is RemoteParticipant) {
|
} else if (participantTrack.participant is RemoteParticipant) {
|
||||||
return RemoteParticipantWidget(
|
return RemoteParticipantWidget(
|
||||||
participantTrack.participant as RemoteParticipant,
|
participantTrack.participant as RemoteParticipant,
|
||||||
participantTrack.videoTrack,
|
participantTrack.videoTrack,
|
||||||
isFixed,
|
avatarSize,
|
||||||
participantTrack.isScreenShare,
|
participantTrack.isScreenShare,
|
||||||
showStatsLayer,
|
showStatsLayer,
|
||||||
|
isList,
|
||||||
|
padding,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw UnimplementedError('Unknown participant type');
|
throw UnimplementedError('Unknown participant type');
|
||||||
@ -36,8 +47,10 @@ abstract class ParticipantWidget extends StatefulWidget {
|
|||||||
abstract final Participant participant;
|
abstract final Participant participant;
|
||||||
abstract final VideoTrack? videoTrack;
|
abstract final VideoTrack? videoTrack;
|
||||||
abstract final bool isScreenShare;
|
abstract final bool isScreenShare;
|
||||||
abstract final bool isFixed;
|
abstract final double? avatarSize;
|
||||||
abstract final bool showStatsLayer;
|
abstract final bool showStatsLayer;
|
||||||
|
abstract final bool isList;
|
||||||
|
abstract final EdgeInsets? padding;
|
||||||
final VideoQuality quality;
|
final VideoQuality quality;
|
||||||
|
|
||||||
const ParticipantWidget({
|
const ParticipantWidget({
|
||||||
@ -52,18 +65,24 @@ class LocalParticipantWidget extends ParticipantWidget {
|
|||||||
@override
|
@override
|
||||||
final VideoTrack? videoTrack;
|
final VideoTrack? videoTrack;
|
||||||
@override
|
@override
|
||||||
final bool isFixed;
|
final double? avatarSize;
|
||||||
@override
|
@override
|
||||||
final bool isScreenShare;
|
final bool isScreenShare;
|
||||||
@override
|
@override
|
||||||
final bool showStatsLayer;
|
final bool showStatsLayer;
|
||||||
|
@override
|
||||||
|
final bool isList;
|
||||||
|
@override
|
||||||
|
final EdgeInsets? padding;
|
||||||
|
|
||||||
const LocalParticipantWidget(
|
const LocalParticipantWidget(
|
||||||
this.participant,
|
this.participant,
|
||||||
this.videoTrack,
|
this.videoTrack,
|
||||||
this.isFixed,
|
this.avatarSize,
|
||||||
this.isScreenShare,
|
this.isScreenShare,
|
||||||
this.showStatsLayer, {
|
this.showStatsLayer,
|
||||||
|
this.isList,
|
||||||
|
this.padding, {
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,18 +96,24 @@ class RemoteParticipantWidget extends ParticipantWidget {
|
|||||||
@override
|
@override
|
||||||
final VideoTrack? videoTrack;
|
final VideoTrack? videoTrack;
|
||||||
@override
|
@override
|
||||||
final bool isFixed;
|
final double? avatarSize;
|
||||||
@override
|
@override
|
||||||
final bool isScreenShare;
|
final bool isScreenShare;
|
||||||
@override
|
@override
|
||||||
final bool showStatsLayer;
|
final bool showStatsLayer;
|
||||||
|
@override
|
||||||
|
final bool isList;
|
||||||
|
@override
|
||||||
|
final EdgeInsets? padding;
|
||||||
|
|
||||||
const RemoteParticipantWidget(
|
const RemoteParticipantWidget(
|
||||||
this.participant,
|
this.participant,
|
||||||
this.videoTrack,
|
this.videoTrack,
|
||||||
this.isFixed,
|
this.avatarSize,
|
||||||
this.isScreenShare,
|
this.isScreenShare,
|
||||||
this.showStatsLayer, {
|
this.showStatsLayer,
|
||||||
|
this.isList,
|
||||||
|
this.padding, {
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -136,19 +161,82 @@ abstract class _ParticipantWidgetState<T extends ParticipantWidget>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext ctx) {
|
Widget build(BuildContext context) {
|
||||||
|
if (widget.isList) {
|
||||||
|
return Padding(
|
||||||
|
padding: widget.padding ?? EdgeInsets.zero,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: (widget.avatarSize ?? 32) * 2,
|
||||||
|
height: (widget.avatarSize ?? 32) * 2,
|
||||||
|
child: Center(
|
||||||
|
child: NoContentWidget(
|
||||||
|
userinfo: _userinfoMetadata,
|
||||||
|
avatarSize: widget.avatarSize,
|
||||||
|
isSpeaking: widget.participant.isSpeaking,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Expanded(
|
||||||
|
child: SizedBox(
|
||||||
|
height: (widget.avatarSize ?? 32) * 2,
|
||||||
|
child: ParticipantInfoWidget(
|
||||||
|
isList: true,
|
||||||
|
title: widget.participant.name.isNotEmpty
|
||||||
|
? widget.participant.name
|
||||||
|
: widget.participant.identity,
|
||||||
|
audioAvailable: _firstAudioPublication?.muted == false &&
|
||||||
|
_firstAudioPublication?.subscribed == true,
|
||||||
|
connectionQuality: widget.participant.connectionQuality,
|
||||||
|
isScreenShare: widget.isScreenShare,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (_activeVideoTrack != null && !_activeVideoTrack!.muted)
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
child: Material(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.surfaceContainer
|
||||||
|
.withOpacity(0.75),
|
||||||
|
child: VideoTrackRenderer(
|
||||||
|
_activeVideoTrack!,
|
||||||
|
fit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).padding(top: 8),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
_activeVideoTrack != null && !_activeVideoTrack!.muted
|
if (_activeVideoTrack != null && !_activeVideoTrack!.muted)
|
||||||
? VideoTrackRenderer(
|
VideoTrackRenderer(
|
||||||
_activeVideoTrack!,
|
_activeVideoTrack!,
|
||||||
fit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
|
fit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
|
||||||
)
|
)
|
||||||
: NoContentWidget(
|
else
|
||||||
|
Center(
|
||||||
|
child: NoContentWidget(
|
||||||
userinfo: _userinfoMetadata,
|
userinfo: _userinfoMetadata,
|
||||||
isFixed: widget.isFixed,
|
avatarSize: widget.avatarSize,
|
||||||
isSpeaking: widget.participant.isSpeaking,
|
isSpeaking: widget.participant.isSpeaking,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
if (widget.showStatsLayer)
|
if (widget.showStatsLayer)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 30,
|
top: 30,
|
||||||
@ -199,33 +287,31 @@ class _RemoteParticipantWidgetState
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InteractiveParticipantWidget extends StatelessWidget {
|
class InteractiveParticipantWidget extends StatelessWidget {
|
||||||
final double? width;
|
final double? avatarSize;
|
||||||
final double? height;
|
final bool isList;
|
||||||
final Color? color;
|
|
||||||
final bool isFixedAvatar;
|
|
||||||
final ParticipantTrack participant;
|
final ParticipantTrack participant;
|
||||||
final Function() onTap;
|
final Function? onTap;
|
||||||
|
final EdgeInsets? padding;
|
||||||
|
|
||||||
const InteractiveParticipantWidget({
|
const InteractiveParticipantWidget({
|
||||||
super.key,
|
super.key,
|
||||||
this.width,
|
this.avatarSize,
|
||||||
this.height,
|
this.isList = false,
|
||||||
this.color,
|
this.padding,
|
||||||
this.isFixedAvatar = false,
|
|
||||||
required this.participant,
|
required this.participant,
|
||||||
required this.onTap,
|
this.onTap,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return Material(
|
||||||
child: Container(
|
color: Colors.transparent,
|
||||||
width: width,
|
child: InkWell(
|
||||||
height: height,
|
onTap: onTap != null
|
||||||
color: color,
|
? () {
|
||||||
child: ParticipantWidget.widgetFor(participant, isFixed: isFixedAvatar),
|
onTap?.call();
|
||||||
),
|
}
|
||||||
onTap: () => onTap(),
|
: null,
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
if (participant.participant is LocalParticipant) return;
|
if (participant.participant is LocalParticipant) return;
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
@ -237,6 +323,15 @@ class InteractiveParticipantWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
child: Container(
|
||||||
|
child: ParticipantWidget.widgetFor(
|
||||||
|
participant,
|
||||||
|
avatarSize: avatarSize,
|
||||||
|
isList: isList,
|
||||||
|
padding: padding,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ class ParticipantInfoWidget extends StatelessWidget {
|
|||||||
final bool audioAvailable;
|
final bool audioAvailable;
|
||||||
final ConnectionQuality connectionQuality;
|
final ConnectionQuality connectionQuality;
|
||||||
final bool isScreenShare;
|
final bool isScreenShare;
|
||||||
|
final bool isList;
|
||||||
|
|
||||||
const ParticipantInfoWidget({
|
const ParticipantInfoWidget({
|
||||||
super.key,
|
super.key,
|
||||||
@ -16,10 +17,69 @@ class ParticipantInfoWidget extends StatelessWidget {
|
|||||||
this.audioAvailable = true,
|
this.audioAvailable = true,
|
||||||
this.connectionQuality = ConnectionQuality.unknown,
|
this.connectionQuality = ConnectionQuality.unknown,
|
||||||
this.isScreenShare = false,
|
this.isScreenShare = false,
|
||||||
|
this.isList = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Container(
|
Widget build(BuildContext context) {
|
||||||
|
if (isList) {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (title != null)
|
||||||
|
Text(
|
||||||
|
title!,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
).padding(left: 2),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
isScreenShare
|
||||||
|
? const Icon(
|
||||||
|
Symbols.monitor,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
)
|
||||||
|
: Icon(
|
||||||
|
audioAvailable ? Symbols.mic : Symbols.mic_off,
|
||||||
|
color: audioAvailable ? Colors.white : Colors.red,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
const Gap(3),
|
||||||
|
if (connectionQuality != ConnectionQuality.unknown)
|
||||||
|
Icon(
|
||||||
|
{
|
||||||
|
ConnectionQuality.excellent: Symbols.signal_cellular_alt,
|
||||||
|
ConnectionQuality.good: Symbols.signal_cellular_alt_2_bar,
|
||||||
|
ConnectionQuality.poor: Symbols.signal_cellular_alt_1_bar,
|
||||||
|
}[connectionQuality],
|
||||||
|
color: {
|
||||||
|
ConnectionQuality.excellent: Colors.green,
|
||||||
|
ConnectionQuality.good: Colors.orange,
|
||||||
|
ConnectionQuality.poor: Colors.red,
|
||||||
|
}[connectionQuality],
|
||||||
|
size: 16,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
height: 12,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: Colors.white,
|
||||||
|
strokeWidth: 2,
|
||||||
|
),
|
||||||
|
).padding(all: 3),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
|
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 7,
|
vertical: 7,
|
||||||
@ -76,4 +136,5 @@ class ParticipantInfoWidget extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,13 @@ class _LinkPreviewWidgetState extends State<LinkPreviewWidget> {
|
|||||||
|
|
||||||
Future<void> _getLinkMeta() async {
|
Future<void> _getLinkMeta() async {
|
||||||
final linkRegex = RegExp(r'https?:\/\/[^\s/$.?#].[^\s]*');
|
final linkRegex = RegExp(r'https?:\/\/[^\s/$.?#].[^\s]*');
|
||||||
final links = linkRegex.allMatches(widget.text).map((e) => e.group(0)).toSet();
|
final links =
|
||||||
|
linkRegex.allMatches(widget.text).map((e) => e.group(0)).toSet();
|
||||||
|
|
||||||
final lp = context.read<SnLinkPreviewProvider>();
|
final lp = context.read<SnLinkPreviewProvider>();
|
||||||
|
|
||||||
final List<Future<SnLinkMeta?>> futures = links.where((e) => e != null).map((e) => lp.getLinkMeta(e!)).toList();
|
final List<Future<SnLinkMeta?>> futures =
|
||||||
|
links.where((e) => e != null).map((e) => lp.getLinkMeta(e!)).toList();
|
||||||
final results = await Future.wait(futures);
|
final results = await Future.wait(futures);
|
||||||
|
|
||||||
_links.addAll(results.where((e) => e != null).map((e) => e!).toList());
|
_links.addAll(results.where((e) => e != null).map((e) => e!).toList());
|
||||||
@ -66,7 +68,9 @@ class _LinkPreviewEntry extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE) ? double.infinity : 480,
|
maxWidth: ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE)
|
||||||
|
? double.infinity
|
||||||
|
: 480,
|
||||||
),
|
),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
child: Card(
|
child: Card(
|
||||||
@ -74,20 +78,29 @@ class _LinkPreviewEntry extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (meta.image != null)
|
if (meta.image != null)
|
||||||
Container(
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(8),
|
||||||
|
topRight: Radius.circular(8),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
margin: const EdgeInsets.only(bottom: 4),
|
margin: const EdgeInsets.only(bottom: 4),
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius:
|
||||||
|
const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
meta.image!.startsWith('//') ? 'https:${meta.image}' : meta.image!,
|
meta.image!.startsWith('//')
|
||||||
|
? 'https:${meta.image}'
|
||||||
|
: meta.image!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 48,
|
height: 48,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -98,7 +111,8 @@ class _LinkPreviewEntry extends StatelessWidget {
|
|||||||
width: 36,
|
width: 36,
|
||||||
height: 36,
|
height: 36,
|
||||||
child: meta.icon!.endsWith('.svg')
|
child: meta.icon!.endsWith('.svg')
|
||||||
? SvgPicture.network(meta.icon!, width: 36, height: 36)
|
? SvgPicture.network(meta.icon!,
|
||||||
|
width: 36, height: 36)
|
||||||
: UniversalImage(
|
: UniversalImage(
|
||||||
meta.icon!,
|
meta.icon!,
|
||||||
noErrorWidget: true,
|
noErrorWidget: true,
|
||||||
|
@ -87,6 +87,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
GoRouter.of(context).pushNamed(ele.screen);
|
GoRouter.of(context).pushNamed(ele.screen);
|
||||||
nav.setIndex(idx);
|
nav.setIndex(idx);
|
||||||
|
Scaffold.of(context).closeDrawer();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -282,7 +282,7 @@ class ResponsiveScaffoldLanding extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (ResponsiveScaffold.getIsExpand(context) || child == null) {
|
if (ResponsiveScaffold.getIsExpand(context) || child == null) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
noBackground: true,
|
noBackground: ResponsiveScaffold.getIsExpand(context),
|
||||||
appBar: AppBar(),
|
appBar: AppBar(),
|
||||||
body: const SizedBox.shrink(),
|
body: const SizedBox.shrink(),
|
||||||
);
|
);
|
||||||
|
@ -179,9 +179,7 @@ class _PostCommentListPopupState extends State<PostCommentListPopup> {
|
|||||||
final ua = context.watch<UserProvider>();
|
final ua = context.watch<UserProvider>();
|
||||||
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
||||||
|
|
||||||
return SizedBox(
|
return Column(
|
||||||
height: MediaQuery.of(context).size.height * 0.85,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
@ -229,7 +227,6 @@ class _PostCommentListPopupState extends State<PostCommentListPopup> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,8 +274,10 @@ class _PostItemState extends State<PostItem> {
|
|||||||
final isParentAuthor = ua.isAuthorized &&
|
final isParentAuthor = ua.isAuthorized &&
|
||||||
widget.data.replyTo?.publisher.accountId == ua.user?.id;
|
widget.data.replyTo?.publisher.accountId == ua.user?.id;
|
||||||
|
|
||||||
final displayableAttachments = widget.data.preload?.attachments
|
final displayableAttachments = widget.data.body['attachments']
|
||||||
?.where((ele) =>
|
?.map((e) => SnAttachment.fromJson(e))
|
||||||
|
.cast<SnAttachment>()
|
||||||
|
.where((ele) =>
|
||||||
ele?.mediaType != SnMediaType.image ||
|
ele?.mediaType != SnMediaType.image ||
|
||||||
widget.data.type != 'article')
|
widget.data.type != 'article')
|
||||||
.toList();
|
.toList();
|
||||||
@ -284,7 +286,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
|
|
||||||
var attachmentSize = math.min(
|
var attachmentSize = math.min(
|
||||||
MediaQuery.of(context).size.width, widget.maxWidth ?? double.infinity);
|
MediaQuery.of(context).size.width, widget.maxWidth ?? double.infinity);
|
||||||
if ((widget.data.preload?.attachments?.length ?? 0) > 1) {
|
if ((widget.data.body['attachments']?.length ?? 0) > 1) {
|
||||||
attachmentSize -= 80;
|
attachmentSize -= 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +343,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
if (widget.data.preload?.thumbnail != null)
|
if (widget.data.body['thumbnail'] != null)
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
margin: const EdgeInsets.only(bottom: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -361,14 +363,14 @@ class _PostItemState extends State<PostItem> {
|
|||||||
),
|
),
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(
|
sn.getAttachmentUrl(
|
||||||
widget.data.preload!.thumbnail!.rid,
|
widget.data.body['thumbnail']['rid'],
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.data.preload?.video != null)
|
if (widget.data.body['video'] != null)
|
||||||
_PostVideoPlayer(data: widget.data).padding(bottom: 8),
|
_PostVideoPlayer(data: widget.data).padding(bottom: 8),
|
||||||
if (widget.data.type == 'question')
|
if (widget.data.type == 'question')
|
||||||
_PostQuestionHint(data: widget.data).padding(bottom: 8),
|
_PostQuestionHint(data: widget.data).padding(bottom: 8),
|
||||||
@ -455,8 +457,8 @@ class _PostItemState extends State<PostItem> {
|
|||||||
if (widget.data.repostTo != null)
|
if (widget.data.repostTo != null)
|
||||||
_PostQuoteContent(child: widget.data.repostTo!).padding(
|
_PostQuoteContent(child: widget.data.repostTo!).padding(
|
||||||
top: 4,
|
top: 4,
|
||||||
bottom: widget.data.preload?.attachments?.isNotEmpty ??
|
bottom:
|
||||||
false
|
widget.data.body['attachments'].isNotEmpty ?? false
|
||||||
? 12
|
? 12
|
||||||
: 0,
|
: 0,
|
||||||
),
|
),
|
||||||
@ -479,11 +481,11 @@ class _PostItemState extends State<PostItem> {
|
|||||||
fit: widget.showFullPost ? BoxFit.cover : BoxFit.contain,
|
fit: widget.showFullPost ? BoxFit.cover : BoxFit.contain,
|
||||||
padding: EdgeInsets.only(left: 12, right: 12),
|
padding: EdgeInsets.only(left: 12, right: 12),
|
||||||
),
|
),
|
||||||
if (widget.data.preload?.poll != null)
|
if (widget.data.poll != null)
|
||||||
StyledWidget(Container(
|
StyledWidget(Container(
|
||||||
constraints:
|
constraints:
|
||||||
BoxConstraints(maxWidth: widget.maxWidth ?? double.infinity),
|
BoxConstraints(maxWidth: widget.maxWidth ?? double.infinity),
|
||||||
child: PostPoll(poll: widget.data.preload!.poll!),
|
child: PostPoll(poll: widget.data.poll!),
|
||||||
))
|
))
|
||||||
.padding(
|
.padding(
|
||||||
left: 12,
|
left: 12,
|
||||||
@ -585,7 +587,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
).padding(bottom: widget.showCompactAvatar ? 4 : 0),
|
).padding(bottom: widget.showCompactAvatar ? 4 : 0),
|
||||||
if (widget.data.preload?.thumbnail != null)
|
if (widget.data.body['thumbnail'] != null)
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
margin: const EdgeInsets.only(bottom: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -605,14 +607,14 @@ class _PostItemState extends State<PostItem> {
|
|||||||
),
|
),
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(
|
sn.getAttachmentUrl(
|
||||||
widget.data.preload!.thumbnail!.rid,
|
widget.data.body['thumbnail']['rid'],
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.data.preload?.video != null)
|
if (widget.data.body['video'] != null)
|
||||||
_PostVideoPlayer(data: widget.data)
|
_PostVideoPlayer(data: widget.data)
|
||||||
.padding(bottom: 8),
|
.padding(bottom: 8),
|
||||||
if (widget.data.type == 'question')
|
if (widget.data.type == 'question')
|
||||||
@ -712,7 +714,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
_isTranslated ||
|
_isTranslated ||
|
||||||
_isTranslating) &&
|
_isTranslating) &&
|
||||||
(widget.data.repostTo != null ||
|
(widget.data.repostTo != null ||
|
||||||
(widget.data.preload?.attachments
|
(widget.data.body['attachments']
|
||||||
?.isNotEmpty ??
|
?.isNotEmpty ??
|
||||||
false))
|
false))
|
||||||
? 8
|
? 8
|
||||||
@ -722,7 +724,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
_PostQuoteContent(child: widget.data.repostTo!)
|
_PostQuoteContent(child: widget.data.repostTo!)
|
||||||
.padding(
|
.padding(
|
||||||
bottom:
|
bottom:
|
||||||
(widget.data.preload?.attachments?.isNotEmpty ??
|
(widget.data.body['attachments']?.isNotEmpty ??
|
||||||
false)
|
false)
|
||||||
? 8
|
? 8
|
||||||
: 0,
|
: 0,
|
||||||
@ -746,8 +748,8 @@ class _PostItemState extends State<PostItem> {
|
|||||||
padding:
|
padding:
|
||||||
EdgeInsets.only(left: widget.showAvatar ? 60 : 12, right: 12),
|
EdgeInsets.only(left: widget.showAvatar ? 60 : 12, right: 12),
|
||||||
),
|
),
|
||||||
if (widget.data.preload?.poll != null)
|
if (widget.data.poll != null)
|
||||||
PostPoll(poll: widget.data.preload!.poll!).padding(
|
PostPoll(poll: widget.data.poll!).padding(
|
||||||
left: widget.showAvatar ? 60 : 12,
|
left: widget.showAvatar ? 60 : 12,
|
||||||
right: 12,
|
right: 12,
|
||||||
top: 12,
|
top: 12,
|
||||||
@ -808,7 +810,7 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (data.preload?.thumbnail != null)
|
if (data.body['thumbnail'] != null)
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
@ -817,7 +819,7 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
topRight: Radius.circular(8),
|
topRight: Radius.circular(8),
|
||||||
),
|
),
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(data.preload!.thumbnail!.rid),
|
sn.getAttachmentUrl(data.body['thumbnail']['rid']),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
),
|
),
|
||||||
@ -855,9 +857,13 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
isRelativeDate: false,
|
isRelativeDate: false,
|
||||||
).padding(horizontal: 16, bottom: 8),
|
).padding(horizontal: 16, bottom: 8),
|
||||||
if (data.type != 'article' &&
|
if (data.type != 'article' &&
|
||||||
(data.preload?.attachments?.isNotEmpty ?? false))
|
(data.body['attachments']?.isNotEmpty ?? false))
|
||||||
StyledWidget(AttachmentList(
|
StyledWidget(AttachmentList(
|
||||||
data: data.preload!.attachments!,
|
data: data.body['attachments']
|
||||||
|
?.map((e) => SnAttachment.fromJson(e))
|
||||||
|
.cast<SnAttachment>()
|
||||||
|
.toList() ??
|
||||||
|
[],
|
||||||
columned: true,
|
columned: true,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
@ -1146,31 +1152,9 @@ class _PostHeadline extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (isEnlarge) {
|
if (isEnlarge) {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (data.preload?.thumbnail != null)
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
|
||||||
border: Border.all(
|
|
||||||
color: Theme.of(context).dividerColor,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: AspectRatio(
|
|
||||||
aspectRatio: 16 / 9,
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
|
||||||
child: AutoResizeUniversalImage(
|
|
||||||
sn.getAttachmentUrl(data.preload!.thumbnail!.rid),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (data.body['title'] != null || (title?.isNotEmpty ?? false))
|
if (data.body['title'] != null || (title?.isNotEmpty ?? false))
|
||||||
Text(
|
Text(
|
||||||
title ?? data.body['title'],
|
title ?? data.body['title'],
|
||||||
@ -1255,7 +1239,7 @@ class _PostAvatar extends StatelessWidget {
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: data.preload?.realm == null
|
child: data.realm == null
|
||||||
? AccountImage(
|
? AccountImage(
|
||||||
filterQuality: filterQuality,
|
filterQuality: filterQuality,
|
||||||
content: data.publisher.avatar,
|
content: data.publisher.avatar,
|
||||||
@ -1271,7 +1255,7 @@ class _PostAvatar extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
: AccountImage(
|
: AccountImage(
|
||||||
filterQuality: filterQuality,
|
filterQuality: filterQuality,
|
||||||
content: data.preload!.realm!.avatar,
|
content: data.realm!.avatar,
|
||||||
radius: isCompact ? 12 : 20,
|
radius: isCompact ? 12 : 20,
|
||||||
borderRadius: isCompact ? 4 : 8,
|
borderRadius: isCompact ? 4 : 8,
|
||||||
badgeOffset: Offset(-6, -4),
|
badgeOffset: Offset(-6, -4),
|
||||||
@ -1568,6 +1552,7 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (isCompact) {
|
if (isCompact) {
|
||||||
return Row(
|
return Row(
|
||||||
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -1575,7 +1560,6 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
).bold(),
|
).bold(),
|
||||||
),
|
),
|
||||||
const Gap(4),
|
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
isRelativeDate
|
isRelativeDate
|
||||||
@ -1587,6 +1571,10 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
).fontSize(13).opacity(0.8),
|
).fontSize(13).opacity(0.8),
|
||||||
),
|
),
|
||||||
|
if (data.editedAt != null)
|
||||||
|
Flexible(
|
||||||
|
child: Text('postEditedHint').tr().fontSize(13).opacity(0.8),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -1596,20 +1584,20 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(data.publisher.nick).bold(),
|
Text(data.publisher.nick).bold(),
|
||||||
if (data.preload?.realm != null)
|
if (data.realm != null)
|
||||||
const Icon(Symbols.arrow_right, size: 16)
|
const Icon(Symbols.arrow_right, size: 16)
|
||||||
.padding(horizontal: 2)
|
.padding(horizontal: 2)
|
||||||
.opacity(0.5),
|
.opacity(0.5),
|
||||||
if (data.preload?.realm != null) Text(data.preload!.realm!.name),
|
if (data.realm != null) Text(data.realm!.name),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'@${data.publisher.name}',
|
'@${data.publisher.name}',
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
).fontSize(13),
|
).fontSize(13),
|
||||||
const Gap(4),
|
|
||||||
Text(
|
Text(
|
||||||
isRelativeDate
|
isRelativeDate
|
||||||
? RelativeTime(context)
|
? RelativeTime(context)
|
||||||
@ -1619,6 +1607,8 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
).fontSize(13),
|
).fontSize(13),
|
||||||
|
if (data.editedAt != null)
|
||||||
|
Text('postEditedHint').tr().fontSize(13),
|
||||||
],
|
],
|
||||||
).opacity(0.8),
|
).opacity(0.8),
|
||||||
],
|
],
|
||||||
@ -1648,7 +1638,11 @@ class _PostContentBody extends StatelessWidget {
|
|||||||
RegExp(r"^:([-\w]+):$").hasMatch(data.body['content'] ?? ''),
|
RegExp(r"^:([-\w]+):$").hasMatch(data.body['content'] ?? ''),
|
||||||
textScaler: isEnlarge ? TextScaler.linear(1.1) : null,
|
textScaler: isEnlarge ? TextScaler.linear(1.1) : null,
|
||||||
content: text,
|
content: text,
|
||||||
attachments: data.preload?.attachments,
|
attachments: data.body['attachments']
|
||||||
|
?.map((e) => SnAttachment.fromJson(e))
|
||||||
|
.cast<SnAttachment>()
|
||||||
|
.toList() ??
|
||||||
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isSelectable) {
|
if (isSelectable) {
|
||||||
@ -1706,14 +1700,14 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
).padding(horizontal: 16),
|
).padding(horizontal: 16),
|
||||||
if (child.type != 'article' &&
|
if (child.type != 'article' &&
|
||||||
(child.preload?.attachments?.isNotEmpty ?? false))
|
(child.body['attachments']?.isNotEmpty ?? false))
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(8),
|
bottomLeft: Radius.circular(8),
|
||||||
bottomRight: Radius.circular(8),
|
bottomRight: Radius.circular(8),
|
||||||
),
|
),
|
||||||
child: AttachmentList(
|
child: AttachmentList(
|
||||||
data: child.preload!.attachments!,
|
data: child.body['attachments']!,
|
||||||
maxHeight: 360,
|
maxHeight: 360,
|
||||||
minWidth: 640,
|
minWidth: 640,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
@ -2062,8 +2056,6 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: true,
|
|
||||||
isScrollControlled: true,
|
|
||||||
builder: (context) => PostCommentListPopup(
|
builder: (context) => PostCommentListPopup(
|
||||||
post: widget.data,
|
post: widget.data,
|
||||||
commentCount: widget.data.metric.replyCount,
|
commentCount: widget.data.metric.replyCount,
|
||||||
@ -2352,7 +2344,7 @@ class _PostVideoPlayer extends StatelessWidget {
|
|||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AttachmentItem(
|
child: AttachmentItem(
|
||||||
data: data.preload!.video!,
|
data: data.body['video'],
|
||||||
heroTag: 'post-video-${data.id}',
|
heroTag: 'post-video-${data.id}',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -24,6 +24,7 @@ import gal
|
|||||||
import hotkey_manager_macos
|
import hotkey_manager_macos
|
||||||
import in_app_review
|
import in_app_review
|
||||||
import livekit_client
|
import livekit_client
|
||||||
|
import livekit_noise_filter
|
||||||
import local_notifier
|
import local_notifier
|
||||||
import media_kit_libs_macos_video
|
import media_kit_libs_macos_video
|
||||||
import media_kit_video
|
import media_kit_video
|
||||||
@ -60,6 +61,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
HotkeyManagerMacosPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerMacosPlugin"))
|
HotkeyManagerMacosPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerMacosPlugin"))
|
||||||
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
||||||
LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin"))
|
LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin"))
|
||||||
|
LiveKitKrispNoiseFilterPlugin.register(with: registry.registrar(forPlugin: "LiveKitKrispNoiseFilterPlugin"))
|
||||||
LocalNotifierPlugin.register(with: registry.registrar(forPlugin: "LocalNotifierPlugin"))
|
LocalNotifierPlugin.register(with: registry.registrar(forPlugin: "LocalNotifierPlugin"))
|
||||||
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
|
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
|
||||||
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
|
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
|
||||||
|
@ -152,6 +152,11 @@ PODS:
|
|||||||
- flutter_webrtc
|
- flutter_webrtc
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- WebRTC-SDK (= 125.6422.06)
|
- WebRTC-SDK (= 125.6422.06)
|
||||||
|
- livekit_noise_filter (0.0.1):
|
||||||
|
- flutter_webrtc
|
||||||
|
- FlutterMacOS
|
||||||
|
- LiveKitKrispNoiseFilter (= 0.0.7)
|
||||||
|
- LiveKitKrispNoiseFilter (0.0.7)
|
||||||
- local_notifier (0.1.0):
|
- local_notifier (0.1.0):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- media_kit_libs_macos_video (1.0.4):
|
- media_kit_libs_macos_video (1.0.4):
|
||||||
@ -237,6 +242,7 @@ DEPENDENCIES:
|
|||||||
- hotkey_manager_macos (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos`)
|
- hotkey_manager_macos (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos`)
|
||||||
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
|
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
|
||||||
- livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`)
|
- livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`)
|
||||||
|
- livekit_noise_filter (from `Flutter/ephemeral/.symlinks/plugins/livekit_noise_filter/macos`)
|
||||||
- local_notifier (from `Flutter/ephemeral/.symlinks/plugins/local_notifier/macos`)
|
- local_notifier (from `Flutter/ephemeral/.symlinks/plugins/local_notifier/macos`)
|
||||||
- media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`)
|
- media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`)
|
||||||
- media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`)
|
- media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`)
|
||||||
@ -265,6 +271,7 @@ SPEC REPOS:
|
|||||||
- GoogleDataTransport
|
- GoogleDataTransport
|
||||||
- GoogleUtilities
|
- GoogleUtilities
|
||||||
- HotKey
|
- HotKey
|
||||||
|
- LiveKitKrispNoiseFilter
|
||||||
- nanopb
|
- nanopb
|
||||||
- OrderedSet
|
- OrderedSet
|
||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
@ -315,6 +322,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
|
||||||
livekit_client:
|
livekit_client:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos
|
||||||
|
livekit_noise_filter:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/livekit_noise_filter/macos
|
||||||
local_notifier:
|
local_notifier:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/local_notifier/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/local_notifier/macos
|
||||||
media_kit_libs_macos_video:
|
media_kit_libs_macos_video:
|
||||||
@ -378,6 +387,8 @@ SPEC CHECKSUMS:
|
|||||||
hotkey_manager_macos: a4317849af96d2430fa89944d3c58977ca089fbe
|
hotkey_manager_macos: a4317849af96d2430fa89944d3c58977ca089fbe
|
||||||
in_app_review: 0599bccaed5e02f6bed2b0d30d16f86b63ed8638
|
in_app_review: 0599bccaed5e02f6bed2b0d30d16f86b63ed8638
|
||||||
livekit_client: 35690bf9861be6325a6f7d11bb38d50c7c9fed80
|
livekit_client: 35690bf9861be6325a6f7d11bb38d50c7c9fed80
|
||||||
|
livekit_noise_filter: c5710c0871ef3621b48c0b44d3c3ff938ba414b2
|
||||||
|
LiveKitKrispNoiseFilter: efe418ceca28163ace0ff222bd2cc02384645d84
|
||||||
local_notifier: ebf072651e35ae5e47280ad52e2707375cb2ae4e
|
local_notifier: ebf072651e35ae5e47280ad52e2707375cb2ae4e
|
||||||
media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65
|
media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65
|
||||||
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
|
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
|
||||||
|
68
pubspec.lock
68
pubspec.lock
@ -13,10 +13,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _flutterfire_internals
|
name: _flutterfire_internals
|
||||||
sha256: "7fd72d77a7487c26faab1d274af23fb008763ddc10800261abbfb2c067f183d5"
|
sha256: de9ecbb3ddafd446095f7e833c853aff2fa1682b017921fe63a833f9d6f0e422
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.53"
|
version: "1.3.54"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -597,10 +597,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: "8d938fd5c11dc81bf1acd4f7f0486c683fe9e79a0b13419e27730f9ce4d8a25b"
|
sha256: "36a1652d99cb6bf8ccc8b9f43aded1fd60b234d23ce78af422c07f950a436ef7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.2.1"
|
version: "10.0.0"
|
||||||
file_saver:
|
file_saver:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -645,34 +645,34 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_analytics
|
name: firebase_analytics
|
||||||
sha256: "81a582e9348216fcf6b30878487369325bf78b8ddd752ed176949c8e4fd4aaac"
|
sha256: "2416b9d864412ab7b571dafded801bbcc7e29b5824623c055002d4d0819bea2b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.4.4"
|
version: "11.4.5"
|
||||||
firebase_analytics_platform_interface:
|
firebase_analytics_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_analytics_platform_interface
|
name: firebase_analytics_platform_interface
|
||||||
sha256: "5ae7bd4a551b67009cd0676f5407331b202eaf16e0a80dcf7b40cd0a34a18746"
|
sha256: "3ccf5c876a8bea186016de4bcf53fc1bc6fa01236d740fb501d7ef9be356c58e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.4"
|
version: "4.3.5"
|
||||||
firebase_analytics_web:
|
firebase_analytics_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_analytics_web
|
name: firebase_analytics_web
|
||||||
sha256: "15fd7459fea2a00958dbf9b86cd8ad14d3ce2db13950308af7c7717e89ccc5c2"
|
sha256: "5e4e3f001b67c2034b76cb2a42a0eed330fb3a8fb41ad13eceb04e8d9a74f662"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.10+10"
|
version: "0.5.10+11"
|
||||||
firebase_core:
|
firebase_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_core
|
name: firebase_core
|
||||||
sha256: f4d8f49574a4e396f34567f3eec4d38ab9c3910818dec22ca42b2a467c685d8b
|
sha256: "017d17d9915670e6117497e640b2859e0b868026ea36bf3a57feb28c3b97debe"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.12.1"
|
version: "3.13.0"
|
||||||
firebase_core_platform_interface:
|
firebase_core_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -685,34 +685,34 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_web
|
name: firebase_core_web
|
||||||
sha256: faa5a76f6380a9b90b53bc3bdcb85bc7926a382e0709b9b5edac9f7746651493
|
sha256: "129a34d1e0fb62e2b488d988a1fc26cc15636357e50944ffee2862efe8929b23"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.21.1"
|
version: "2.22.0"
|
||||||
firebase_messaging:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
sha256: "5fc345c6341f9dc69fd0ffcbf508c784fd6d1b9e9f249587f30434dd8b6aa281"
|
sha256: "5f8918848ee0c8eb172fc7698619b2bcd7dda9ade8b93522c6297dd8f9178356"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.2.4"
|
version: "15.2.5"
|
||||||
firebase_messaging_platform_interface:
|
firebase_messaging_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_platform_interface
|
name: firebase_messaging_platform_interface
|
||||||
sha256: a935924cf40925985c8049df4968b1dde5c704f570f3ce380b31d3de6990dd94
|
sha256: "0bbea00680249595fc896e7313a2bd90bd55be6e0abbe8b9a39d81b6b306acb6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.6.4"
|
version: "4.6.5"
|
||||||
firebase_messaging_web:
|
firebase_messaging_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_web
|
name: firebase_messaging_web
|
||||||
sha256: fafebf6a1921931334f3f10edb5037a5712288efdd022881e2d093e5654a2fd4
|
sha256: ffb392ce2a7e8439cd0a9a80e3c702194e73c927e5c7b4f0adf6faa00b245b17
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.10.4"
|
version: "3.10.5"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -794,10 +794,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_context_menu
|
name: flutter_context_menu
|
||||||
sha256: "4bc1dc30ae5aa705ed99ebbeb875898c6341a6d092397a566fecd5184b392380"
|
sha256: "9a80f3ab623086f6ec89483c24a1129e6b9f30914fdc1219f4af622164a2fb74"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.2"
|
||||||
flutter_expandable_fab:
|
flutter_expandable_fab:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1381,6 +1381,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.1"
|
||||||
|
livekit_noise_filter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: livekit_noise_filter
|
||||||
|
sha256: "398bfd1cc63ada9dee9fd7ea415e2fc1e51e091a6d217aad3649b882c35c7fcb"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
local_notifier:
|
local_notifier:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1801,10 +1809,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
sha256: "489024f942069c2920c844ee18bb3d467c69e48955a4f32d1677f71be103e310"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.4"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1937,10 +1945,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a"
|
sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.2"
|
version: "2.5.3"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -2454,18 +2462,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: volume_controller
|
name: volume_controller
|
||||||
sha256: "4c2a873c242da6ce69ae1d17c256c5626e0c481be1824d6c5fc95e68c31f3b36"
|
sha256: e82fd689bb8e1fe8e64be3fa5946ff8699058f8cf9f4c1679acdba20cda7f5bd
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.2"
|
version: "3.3.3"
|
||||||
wakelock_plus:
|
wakelock_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: wakelock_plus
|
name: wakelock_plus
|
||||||
sha256: "36c88af0b930121941345306d259ec4cc4ecca3b151c02e3a9e71aede83c615e"
|
sha256: b90fbcc8d7bdf3b883ea9706d9d76b9978cb1dfa4351fcc8014d6ec31a493354
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.10"
|
version: "1.2.11"
|
||||||
wakelock_plus_platform_interface:
|
wakelock_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -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.4.2+85
|
version: 2.4.2+88
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.5.4
|
sdk: ^3.5.4
|
||||||
@ -59,7 +59,7 @@ dependencies:
|
|||||||
relative_time: ^5.0.0
|
relative_time: ^5.0.0
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
cross_file: ^0.3.4+2
|
cross_file: ^0.3.4+2
|
||||||
file_picker: ^9.2.1
|
file_picker: ^10.0.0
|
||||||
croppy: ^1.3.1
|
croppy: ^1.3.1
|
||||||
flutter_expandable_fab: ^2.3.0
|
flutter_expandable_fab: ^2.3.0
|
||||||
dropdown_button2: ^2.3.9
|
dropdown_button2: ^2.3.9
|
||||||
@ -144,6 +144,7 @@ dependencies:
|
|||||||
latlong2: ^0.9.1
|
latlong2: ^0.9.1
|
||||||
crypto: ^3.0.6
|
crypto: ^3.0.6
|
||||||
audioplayers: ^6.4.0
|
audioplayers: ^6.4.0
|
||||||
|
livekit_noise_filter: ^0.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user