Compare commits
No commits in common. "v3" and "v2" have entirely different histories.
87
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us address issues you are facing
|
||||
title: "[Bug] "
|
||||
labels: [Bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make us better!
|
||||
|
||||
- type: checkboxes
|
||||
id: duplication
|
||||
attributes:
|
||||
label: ⠀
|
||||
options:
|
||||
- label: This issue is not duplicated with any other open or closed issues
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is
|
||||
placeholder: |
|
||||
Example:
|
||||
App crashes on startup every time after changing settings.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen
|
||||
placeholder: |
|
||||
Example:
|
||||
App started normally, everything worked fine.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Steps to reproduce the bug
|
||||
placeholder: |
|
||||
Example:
|
||||
1. Change "HyperNet Server" to "127.0.1" in "Network" settings
|
||||
2. Restart the app
|
||||
3. Crash
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Device information
|
||||
description: Provide details about your system environment
|
||||
placeholder: |
|
||||
Example:
|
||||
Device: Google Pixel 8 Pro
|
||||
System: Baklava (BP22.250124.009)
|
||||
Version*: 2.3.2
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem
|
||||
placeholder: |
|
||||
Example:
|
||||
setting_items.jpg
|
||||
crash_screen.jpg
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here
|
||||
placeholder: |
|
||||
Crash report or other useful informations
|
||||
validations:
|
||||
required: false
|
83
.github/ISSUE_TEMPLATE/bug_report_zh.yaml
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
name: 问题反馈
|
||||
description: 提交 Bug 或其它问题的反馈
|
||||
title: "[Bug] 标题"
|
||||
labels: [Bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
非常感谢,你将要提交的反馈会让我们变得更好!
|
||||
|
||||
- type: checkboxes
|
||||
id: duplication
|
||||
attributes:
|
||||
label: ⠀
|
||||
options:
|
||||
- label: 我已经搜索并确认此 issue 不与其它任何 issue 重复
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 问题描述
|
||||
description: 清楚且详细地描述你遇到的 Bug 或问题
|
||||
placeholder: |
|
||||
发生了什么?生动地描述你所看到的一切
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: 期望表现
|
||||
description: 清楚且详细地描述你期望发生的事
|
||||
placeholder: |
|
||||
什么功能应该正常运行,运行后会有什么结果
|
||||
什么界面应该正常显示,应该会显示什么内容
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: 复现步骤
|
||||
description: 能够复现问题的每一步
|
||||
placeholder: |
|
||||
1. 尽可能详细地描述每一步
|
||||
2. 更改的设置、添加的好友...
|
||||
3. 这里也可以描述你看到的界面
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: 环境/版本
|
||||
description: 提供运行时的环境信息
|
||||
placeholder: |
|
||||
示例:
|
||||
设备型号: Google Pixel 8 Pro
|
||||
系统板本: Baklava (BP22.250124.009)
|
||||
程序版本: 2.3.2
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: 屏幕截图/录制
|
||||
description: 提供截屏或录屏来更好地描述问题
|
||||
placeholder: |
|
||||
错误显示的界面/崩溃时的界面、先前改动的设置
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: 更多信息
|
||||
description: 任何与问题有关且有用的信息
|
||||
placeholder: |
|
||||
崩溃报告、日志,或是你的用户名
|
||||
validations:
|
||||
required: false
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Solsynth Releases
|
||||
url: https://files.solsynth.dev/production01/solian
|
||||
about: Another place to download released apps
|
59
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
name: Feature request
|
||||
description: Suggest features you want to add or suggest to modify existing features
|
||||
title: "[Feature] "
|
||||
labels: [Feature]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make us better!
|
||||
|
||||
- type: checkboxes
|
||||
id: duplication
|
||||
attributes:
|
||||
label: ⠀
|
||||
options:
|
||||
- label: This issue is not duplicated with any other open or closed issues
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the feature
|
||||
description: A clear and concise description of what the feature is
|
||||
placeholder: |
|
||||
Example:
|
||||
A Quick Settings tile to start the service, long press to launch the app.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reasons
|
||||
attributes:
|
||||
label: Reason for adding
|
||||
description: Explain why this feature would be useful to you
|
||||
placeholder: |
|
||||
Example:
|
||||
Start the service quickly from the Quick Settings tile and save lots of time.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: examples
|
||||
attributes:
|
||||
label: Example(s)
|
||||
description: Post screenshots/drawings/links/etc of the feature request, or proof-of-concept images about the feature
|
||||
placeholder: |
|
||||
Example:
|
||||
shazam_toggle.jpg
|
||||
nekobox_switch.jpg
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the feature here
|
||||
validations:
|
||||
required: false
|
49
.github/ISSUE_TEMPLATE/feature_request_zh.yaml
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
name: 功能建议
|
||||
description: 提出你想要添加或更改的功能
|
||||
title: "[Feature] 标题"
|
||||
labels: [Feature]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
非常感谢,你将要提交的请求会让我们变得更好!
|
||||
|
||||
- type: checkboxes
|
||||
id: duplication
|
||||
attributes:
|
||||
label: ⠀
|
||||
options:
|
||||
- label: 我已经搜索并确认此 issue 不与其它任何 issue 重复
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 功能描述
|
||||
description: 清楚且详细地描述要添加/更改后的功能
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reasons
|
||||
attributes:
|
||||
label: 添加/更改理由
|
||||
description: 解释为什么要这样做,对用户有什么好处
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: examples
|
||||
attributes:
|
||||
label: 功能示例
|
||||
description: 相似/已存在功能的截图,或画出大致的界面
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: 更多信息
|
||||
description: 任何与功能有关且有用的信息,或已存在功能的代码/仓库
|
||||
validations:
|
||||
required: false
|
81
.github/workflows/nightly.yml
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
name: release-nightly
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
build-web:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: stable
|
||||
cache: true
|
||||
- run: flutter pub get
|
||||
- run: flutter build web --release
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-output-web
|
||||
path: build/web
|
||||
build-exe:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: stable
|
||||
cache: true
|
||||
- run: flutter pub get
|
||||
- run: flutter build windows
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-output-windows
|
||||
path: build/windows/x64/runner/Release
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: stable
|
||||
- run: |
|
||||
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
|
||||
- run: flutter pub get
|
||||
- run: flutter build linux
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-output-linux
|
||||
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*'
|
3
.gitignore
vendored
@ -43,3 +43,6 @@ app.*.map.json
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
# FVM Version Cache
|
||||
.fvm/
|
30
.metadata
@ -4,7 +4,7 @@
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "ea121f8859e4b13e47a8f845e4586164519588bc"
|
||||
revision: "603104015dd692ea3403755b55d07813d5cf8965"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
@ -13,26 +13,26 @@ project_type: app
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
- platform: android
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
- platform: ios
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
- platform: linux
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
- platform: macos
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
- platform: web
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
- platform: windows
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||
|
||||
# User provided section
|
||||
|
||||
|
13
.roadsignrc
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"sync": {
|
||||
"region": "solian",
|
||||
"configPath": "roadsign.toml"
|
||||
},
|
||||
"deployments": [
|
||||
{
|
||||
"region": "solian",
|
||||
"site": "solian-web",
|
||||
"path": "build/web"
|
||||
}
|
||||
]
|
||||
}
|
1
.vscode/settings.json
vendored
@ -1 +0,0 @@
|
||||
{}
|
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!
|
||||
|
23
README.md
@ -1,20 +1,27 @@
|
||||
# Solar Network
|
||||
|
||||
> [!IMPORTANT]
|
||||
> You're visiting the Solar Network v3 branch, which is the next version and still under active development. **NOT READY FOR USE / PRODUCTION!**
|
||||
|
||||

|
||||
|
||||
Hello there! Welcome to the main repository of the DysonNetwork (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!
|
||||
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!
|
||||
|
||||
## Server
|
||||
## Sub Projects
|
||||
|
||||
The backend of the Solar Network project is located at [Solsynth/DysonNetwork](https://github.com/Solsynth/DysonNetwork)
|
||||
HyperNet, the Solar Network is a microservices project in which the backends are stored in separate repositories. Here is a simple index for it.
|
||||
|
||||
- The Core, Gateway: [Nexus](https://github.com/Solsynth/HyperNet.Nexus)
|
||||
- The Auth Service: [Passport](https://github.com/Solsynth/HyperNet.Passport)
|
||||
- The Posting Service: [Interactive](https://github.com/Solsynth/HyperNet.Interactive)
|
||||
- The Messaging Service: [Messaging](https://github.com/Solsynth/HyperNet.Messaging)
|
||||
- The Wallet Service: [Wallet](https://github.com/Solsynth/HyperNet.Wallet)
|
||||
- The Crawler: [Reader](https://github.com/Solsynth/HyperNet.Reader)
|
||||
- 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
|
||||
|
||||
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 .NET and PostgreSQL.
|
||||
|
||||
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).
|
||||
|
||||
@ -24,8 +31,6 @@ The content below will lead you to the world of Solar Network.
|
||||
|
||||
### For Normal Users
|
||||
|
||||
**The v3 Release is not ready, yet.**
|
||||
|
||||
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
|
||||
|
@ -9,6 +9,14 @@
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
analyzer:
|
||||
exclude:
|
||||
- "**/*.g.dart"
|
||||
- "**/*.freezed.dart"
|
||||
errors:
|
||||
invalid_annotation_target: ignore # Due to freezed + json_serializable issue, ref https://github.com/rrousselGit/freezed/issues/488#issuecomment-894358980
|
||||
deprecated_member_use: ignore
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
@ -24,9 +32,5 @@ linter:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
analyzer:
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
deprecated_member_use: ignore
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
3
android/.gitignore
vendored
@ -5,10 +5,11 @@ gradle-wrapper.jar
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
.cxx/
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/to/reference-keystore
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
|
||||
app/.cxx
|
91
android/app/build.gradle
Normal file
@ -0,0 +1,91 @@
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
// START: FlutterFire Configuration
|
||||
id 'com.google.gms.google-services'
|
||||
id 'com.google.firebase.crashlytics'
|
||||
// END: FlutterFire Configuration
|
||||
id "kotlin-android"
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// implementation('org.jitsi.react:jitsi-meet-sdk:11.1.1') { transitive = true }
|
||||
// implementation 'com.facebook.fresco:webpsupport:2.6.0'
|
||||
// implementation 'com.facebook.fresco:animated-webp:2.6.0'
|
||||
// implementation 'com.facebook.react:react-android:0.75.5'
|
||||
// implementation 'com.facebook.react:hermes-android:0.75.5'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'androidx.glance:glance:1.1.1'
|
||||
implementation 'androidx.glance:glance-appwidget:1.1.1'
|
||||
implementation 'androidx.compose.foundation:foundation-layout-android:1.7.8'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
implementation 'io.coil-kt.coil3:coil-compose:3.0.4'
|
||||
implementation 'io.coil-kt.coil3:coil-network-okhttp:3.0.4'
|
||||
}
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
buildFeatures {
|
||||
compose true
|
||||
}
|
||||
|
||||
namespace = "dev.solsynth.solian"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.4.8"
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.solsynth.solian"
|
||||
minSdk = 26
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias = keystoreProperties['keyAlias']
|
||||
keyPassword = keystoreProperties['keyPassword']
|
||||
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword = keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
debuggable true
|
||||
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
release {
|
||||
signingConfig = signingConfigs.release
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
// START: FlutterFire Configuration
|
||||
id("com.google.gms.google-services")
|
||||
// END: FlutterFire Configuration
|
||||
id("kotlin-android")
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "dev.solsynth.solian"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = "29.0.13113456"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_17.toString()
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.solsynth.solian"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||
minSdk = 26
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
96
android/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
-keepclassmembers class kotlin.Metadata { *; }
|
||||
-keep class dev.solsynth.solian.** { *; }
|
||||
-keep public class dev.solsynth.solian.data.** { public *; }
|
||||
-keepclassmembers class dev.solsynth.solian.data.** { *; }
|
||||
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Signature
|
||||
-keepattributes EnclosingMethod
|
||||
|
||||
-keep class com.google.gson.** { *; }
|
||||
|
||||
-keepclassmembers class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
-dontwarn com.facebook.imagepipeline.nativecode.WebpTranscoder
|
||||
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
|
||||
|
||||
# Do not strip any method/class that is annotated with @DoNotStrip
|
||||
-keep @com.facebook.proguard.annotations.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.proguard.annotations.DoNotStrip *;
|
||||
}
|
||||
|
||||
-keep @com.facebook.proguard.annotations.DoNotStripAny class * {
|
||||
*;
|
||||
}
|
||||
|
||||
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
|
||||
-keep class * implements com.facebook.react.bridge.JavaScriptModule { *; }
|
||||
-keep class * implements com.facebook.react.bridge.NativeModule { *; }
|
||||
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
|
||||
|
||||
-dontwarn com.facebook.react.**
|
||||
-keep,includedescriptorclasses class com.facebook.react.bridge.** { *; }
|
||||
-keep,includedescriptorclasses class com.facebook.react.turbomodule.core.** { *; }
|
||||
|
||||
# hermes
|
||||
-keep class com.facebook.jni.** { *; }
|
||||
|
||||
# okio
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-dontwarn okio.**
|
||||
|
||||
# yoga
|
||||
-keep,allowobfuscation @interface com.facebook.yoga.annotations.DoNotStrip
|
||||
-keep @com.facebook.yoga.annotations.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.yoga.annotations.DoNotStrip *;
|
||||
}
|
||||
|
||||
# WebRTC
|
||||
|
||||
-keep class org.webrtc.** { *; }
|
||||
-dontwarn org.chromium.build.BuildHooksAndroid
|
||||
|
||||
# Jisti Meet SDK
|
||||
|
||||
-keep class org.jitsi.meet.** { *; }
|
||||
-keep class org.jitsi.meet.sdk.** { *; }
|
||||
|
||||
# We added the following when we switched minifyEnabled on. Probably because we
|
||||
# ran the app and hit problems...
|
||||
|
||||
-keep class com.facebook.react.bridge.CatalystInstanceImpl { *; }
|
||||
-keep class com.facebook.react.bridge.ExecutorToken { *; }
|
||||
-keep class com.facebook.react.bridge.JavaScriptExecutor { *; }
|
||||
-keep class com.facebook.react.bridge.ModuleRegistryHolder { *; }
|
||||
-keep class com.facebook.react.bridge.ReadableType { *; }
|
||||
-keep class com.facebook.react.bridge.queue.NativeRunnable { *; }
|
||||
-keep class com.facebook.react.devsupport.** { *; }
|
||||
|
||||
-dontwarn com.facebook.react.devsupport.**
|
||||
-dontwarn com.google.appengine.**
|
||||
-dontwarn com.squareup.okhttp.**
|
||||
-dontwarn javax.servlet.**
|
||||
|
||||
# ^^^ We added the above when we switched minifyEnabled on.
|
||||
|
||||
# Rule to avoid build errors related to SVGs.
|
||||
-keep public class com.horcrux.svg.** {*;}
|
||||
|
||||
# https://github.com/facebook/fresco/issues/2638
|
||||
-keep public class com.facebook.imageutils.** {
|
||||
public *;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
@ -13,13 +13,17 @@
|
||||
android:maxSdkVersion="29" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
|
||||
|
||||
<application
|
||||
tools:replace="android:label"
|
||||
android:label="Solian"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/launcher_icon"
|
||||
android:usesCleartextTraffic="true">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
@ -29,6 +33,38 @@
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Widgets Indents -->
|
||||
<intent-filter>
|
||||
<action android:name="es.antonborri.home_widget.action.LAUNCH" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Sharing Intents -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="image/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="image/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
@ -42,21 +78,35 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="dev.solsynth.solian.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<!-- Widgets -->
|
||||
<receiver android:name=".widgets.CheckInWidgetReceiver"
|
||||
android:label="Check In"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/check_in_widget" />
|
||||
</receiver>
|
||||
<receiver android:name=".widgets.RandomPostWidgetReceiver"
|
||||
android:label="Random Post"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/random_post_widget" />
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
@ -68,4 +118,4 @@
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
BIN
android/app/src/main/ic_launcher-playstore.png
Normal file
After Width: | Height: | Size: 17 KiB |
@ -1,14 +0,0 @@
|
||||
package dev.solsynth.solian
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugins.sharedpreferences.LegacySharedPreferencesPlugin
|
||||
|
||||
class MainActivity : FlutterActivity()
|
||||
{
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
// https://github.com/flutter/flutter/issues/153075#issuecomment-2693189362
|
||||
flutterEngine.plugins.add(LegacySharedPreferencesPlugin())
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package dev.solsynth.solian
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity: FlutterActivity()
|
@ -0,0 +1,6 @@
|
||||
package dev.solsynth.solian.data
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
data class SolarPagination<T>(val count: Int, val data: List<T>)
|
@ -0,0 +1,35 @@
|
||||
package dev.solsynth.solian.data
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import java.time.Instant
|
||||
|
||||
@Keep
|
||||
data class SolarPost(
|
||||
val id: Int,
|
||||
val body: SolarPostBody,
|
||||
val publisher: SolarPublisher,
|
||||
val publisherId: Int,
|
||||
val createdAt: Instant,
|
||||
val updatedAt: Instant,
|
||||
val editedAt: Instant?,
|
||||
val publishedAt: Instant?
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class SolarPostBody(
|
||||
val content: String?,
|
||||
val title: String?,
|
||||
val description: String?,
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class SolarPublisher(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val nick: String,
|
||||
val description: String?,
|
||||
val avatar: String?,
|
||||
val banner: String?,
|
||||
val createdAt: Instant,
|
||||
val updatedAt: Instant
|
||||
)
|
@ -0,0 +1,38 @@
|
||||
package dev.solsynth.solian.data
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonParseException
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import java.lang.reflect.Type
|
||||
import java.time.Instant
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@Keep
|
||||
class InstantAdapter : JsonSerializer<Instant?>,
|
||||
JsonDeserializer<Instant?> {
|
||||
override fun serialize(
|
||||
src: Instant?,
|
||||
typeOfSrc: Type?,
|
||||
context: JsonSerializationContext?
|
||||
): JsonElement {
|
||||
return JsonPrimitive(formatter.format(src))
|
||||
}
|
||||
|
||||
@Throws(JsonParseException::class)
|
||||
override fun deserialize(
|
||||
json: JsonElement,
|
||||
typeOfT: Type?,
|
||||
context: JsonDeserializationContext?
|
||||
): Instant {
|
||||
return Instant.parse(json.asString)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_INSTANT
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package dev.solsynth.solian.data
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import java.time.Instant
|
||||
|
||||
@Keep
|
||||
data class SolarUser(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val nick: String
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class SolarCheckInRecord(
|
||||
val id: Int,
|
||||
val resultTier: Int,
|
||||
val resultExperience: Int,
|
||||
val createdAt: Instant
|
||||
)
|
@ -0,0 +1,128 @@
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.glance.GlanceId
|
||||
import androidx.glance.GlanceModifier
|
||||
import androidx.glance.GlanceTheme
|
||||
import androidx.glance.action.clickable
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.provideContent
|
||||
import androidx.glance.background
|
||||
import androidx.glance.currentState
|
||||
import androidx.glance.layout.Alignment
|
||||
import androidx.glance.layout.Column
|
||||
import androidx.glance.layout.Row
|
||||
import androidx.glance.layout.Spacer
|
||||
import androidx.glance.layout.fillMaxHeight
|
||||
import androidx.glance.layout.fillMaxWidth
|
||||
import androidx.glance.layout.height
|
||||
import androidx.glance.layout.padding
|
||||
import androidx.glance.state.GlanceStateDefinition
|
||||
import androidx.glance.text.FontFamily
|
||||
import androidx.glance.text.Text
|
||||
import androidx.glance.text.TextStyle
|
||||
import com.google.gson.FieldNamingPolicy
|
||||
import com.google.gson.GsonBuilder
|
||||
import dev.solsynth.solian.MainActivity
|
||||
import dev.solsynth.solian.data.InstantAdapter
|
||||
import dev.solsynth.solian.data.SolarCheckInRecord
|
||||
import es.antonborri.home_widget.actionStartActivity
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class CheckInWidget : GlanceAppWidget() {
|
||||
override val stateDefinition: GlanceStateDefinition<*>?
|
||||
get() = HomeWidgetGlanceStateDefinition()
|
||||
|
||||
override suspend fun provideGlance(context: Context, id: GlanceId) {
|
||||
provideContent {
|
||||
GlanceTheme {
|
||||
GlanceContent(context, currentState())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun GlanceContent(context: Context, currentState: HomeWidgetGlanceState) {
|
||||
val gson =
|
||||
GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.registerTypeAdapter(Instant::class.java, InstantAdapter())
|
||||
.create()
|
||||
val resultTierSymbols = listOf("Bad", "Poor", "Medium", "Good", "Great")
|
||||
|
||||
val prefs = currentState.preferences
|
||||
val checkInRaw: String? = prefs.getString("pas_check_in_record", null)
|
||||
|
||||
val checkIn: SolarCheckInRecord? =
|
||||
checkInRaw?.let { checkInRaw ->
|
||||
gson.fromJson(checkInRaw, SolarCheckInRecord::class.java)
|
||||
} ?: null;
|
||||
|
||||
Column(
|
||||
modifier = GlanceModifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight()
|
||||
.background(GlanceTheme.colors.widgetBackground)
|
||||
.padding(16.dp)
|
||||
.clickable(
|
||||
onClick = actionStartActivity<MainActivity>(
|
||||
context,
|
||||
Uri.parse("https://sn.solsynth.dev")
|
||||
)
|
||||
)
|
||||
) {
|
||||
if (checkIn != null) {
|
||||
val dateFormatter = DateTimeFormatter.ofPattern("EEE, MM/dd")
|
||||
|
||||
val checkDate = checkIn.createdAt.atZone(ZoneId.of("UTC")).toLocalDate()
|
||||
val currentDate = LocalDate.now()
|
||||
if (checkDate.isEqual(currentDate)) {
|
||||
Column {
|
||||
Text(
|
||||
text = resultTierSymbols[checkIn.resultTier],
|
||||
style = TextStyle(
|
||||
fontSize = 17.sp,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
Text(
|
||||
text = "+${checkIn.resultExperience} EXP",
|
||||
style = TextStyle(
|
||||
fontSize = 13.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = GlanceModifier.height(8.dp))
|
||||
Row(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
text = OffsetDateTime.ofInstant(
|
||||
checkIn.createdAt,
|
||||
ZoneId.systemDefault()
|
||||
)
|
||||
.format(dateFormatter),
|
||||
style = TextStyle(
|
||||
fontSize = 11.sp,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return@Column;
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "You haven't divined today",
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package dev.solsynth.solian.widgets
|
||||
|
||||
import CheckInWidget
|
||||
import HomeWidgetGlanceWidgetReceiver
|
||||
|
||||
class CheckInWidgetReceiver : HomeWidgetGlanceWidgetReceiver<CheckInWidget>() {
|
||||
override val glanceAppWidget = CheckInWidget()
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
import HomeWidgetGlanceState
|
||||
import HomeWidgetGlanceStateDefinition
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.glance.GlanceId
|
||||
import androidx.glance.GlanceModifier
|
||||
import androidx.glance.GlanceTheme
|
||||
import androidx.glance.action.clickable
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.provideContent
|
||||
import androidx.glance.background
|
||||
import androidx.glance.currentState
|
||||
import androidx.glance.layout.Alignment
|
||||
import androidx.glance.layout.Column
|
||||
import androidx.glance.layout.Row
|
||||
import androidx.glance.layout.Spacer
|
||||
import androidx.glance.layout.fillMaxHeight
|
||||
import androidx.glance.layout.fillMaxSize
|
||||
import androidx.glance.layout.fillMaxWidth
|
||||
import androidx.glance.layout.height
|
||||
import androidx.glance.layout.padding
|
||||
import androidx.glance.layout.width
|
||||
import androidx.glance.state.GlanceStateDefinition
|
||||
import androidx.glance.text.FontFamily
|
||||
import androidx.glance.text.FontWeight
|
||||
import androidx.glance.text.Text
|
||||
import androidx.glance.text.TextStyle
|
||||
import com.google.gson.FieldNamingPolicy
|
||||
import com.google.gson.GsonBuilder
|
||||
import dev.solsynth.solian.MainActivity
|
||||
import dev.solsynth.solian.data.InstantAdapter
|
||||
import dev.solsynth.solian.data.SolarPost
|
||||
import es.antonborri.home_widget.actionStartActivity
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class RandomPostWidget : GlanceAppWidget() {
|
||||
override val stateDefinition: GlanceStateDefinition<*>?
|
||||
get() = HomeWidgetGlanceStateDefinition()
|
||||
|
||||
override suspend fun provideGlance(context: Context, id: GlanceId) {
|
||||
provideContent {
|
||||
GlanceTheme {
|
||||
GlanceContent(context, currentState())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun GlanceContent(
|
||||
context: Context,
|
||||
currentState: HomeWidgetGlanceState,
|
||||
) {
|
||||
val prefs = currentState.preferences
|
||||
val postRaw = prefs.getString("int_random_post", null)
|
||||
|
||||
val gson =
|
||||
GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.registerTypeAdapter(Instant::class.java, InstantAdapter())
|
||||
.create()
|
||||
|
||||
val data: SolarPost? = postRaw?.let { postRaw ->
|
||||
gson.fromJson(postRaw, SolarPost::class.java)
|
||||
} ?: null;
|
||||
|
||||
Column(
|
||||
modifier = GlanceModifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight()
|
||||
.background(GlanceTheme.colors.widgetBackground)
|
||||
.padding(16.dp)
|
||||
.clickable(
|
||||
onClick = actionStartActivity<MainActivity>(
|
||||
context,
|
||||
Uri.parse("https://sn.solsynth.dev/posts/${data!!.id}")
|
||||
)
|
||||
)
|
||||
) {
|
||||
if (data != null) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = data.publisher.nick,
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
Spacer(modifier = GlanceModifier.width(8.dp))
|
||||
Text(
|
||||
text = "@${data.publisher.name}",
|
||||
style = TextStyle(
|
||||
fontSize = 13.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = GlanceModifier.height(8.dp))
|
||||
|
||||
if (data.body.title != null) {
|
||||
Text(
|
||||
text = data.body.title,
|
||||
style = TextStyle(fontSize = 19.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
if (data.body.description != null) {
|
||||
Text(
|
||||
text = data.body.description,
|
||||
style = TextStyle(fontSize = 17.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
|
||||
if (data.body.title != null || data.body.description != null) {
|
||||
Spacer(modifier = GlanceModifier.height(8.dp))
|
||||
}
|
||||
|
||||
Text(
|
||||
text = data.body.content ?: "No content",
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface),
|
||||
)
|
||||
|
||||
Spacer(modifier = GlanceModifier.height(8.dp))
|
||||
|
||||
|
||||
Text(
|
||||
LocalDateTime.ofInstant(data.createdAt, ZoneId.systemDefault())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
|
||||
style = TextStyle(fontSize = 13.sp, color = GlanceTheme.colors.onSurface),
|
||||
)
|
||||
|
||||
Text(
|
||||
"#${data.id}",
|
||||
style = TextStyle(
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
),
|
||||
)
|
||||
|
||||
return@Column;
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = GlanceModifier.fillMaxSize(),
|
||||
verticalAlignment = Alignment.Vertical.CenterVertically,
|
||||
horizontalAlignment = Alignment.Horizontal.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "No Recommendations",
|
||||
style = TextStyle(
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = GlanceTheme.colors.onSurface
|
||||
)
|
||||
)
|
||||
Text(
|
||||
text = "Open app to load some posts",
|
||||
style = TextStyle(fontSize = 15.sp, color = GlanceTheme.colors.onSurface)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package dev.solsynth.solian.widgets
|
||||
|
||||
import RandomPostWidget
|
||||
import HomeWidgetGlanceWidgetReceiver
|
||||
|
||||
class RandomPostWidgetReceiver : HomeWidgetGlanceWidgetReceiver<RandomPostWidget>() {
|
||||
override val glanceAppWidget = RandomPostWidget()
|
||||
}
|
BIN
android/app/src/main/res/drawable-hdpi/branding.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/app/src/main/res/drawable-hdpi/ic_notification.png
Normal file
After Width: | Height: | Size: 537 B |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 33 KiB |
BIN
android/app/src/main/res/drawable-mdpi/branding.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
android/app/src/main/res/drawable-mdpi/ic_notification.png
Normal file
After Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 18 KiB |
BIN
android/app/src/main/res/drawable-night-hdpi/branding.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 18 KiB |
BIN
android/app/src/main/res/drawable-night-mdpi/branding.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 69 B |
@ -6,4 +6,7 @@
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
<item android:bottom="24dp">
|
||||
<bitmap android:gravity="bottom" android:src="@drawable/branding"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
BIN
android/app/src/main/res/drawable-night-xhdpi/branding.png
Normal file
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 25 KiB |
BIN
android/app/src/main/res/drawable-night-xxhdpi/branding.png
Normal file
After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 39 KiB |
BIN
android/app/src/main/res/drawable-night-xxxhdpi/branding.png
Normal file
After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 69 B |
@ -6,4 +6,7 @@
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
<item android:bottom="24dp">
|
||||
<bitmap android:gravity="bottom" android:src="@drawable/branding"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 69 B |
@ -6,4 +6,7 @@
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
<item android:bottom="24dp">
|
||||
<bitmap android:gravity="bottom" android:src="@drawable/branding"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
BIN
android/app/src/main/res/drawable-xhdpi/branding.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
android/app/src/main/res/drawable-xhdpi/ic_notification.png
Normal file
After Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 49 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/branding.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/ic_notification.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 96 KiB |
BIN
android/app/src/main/res/drawable-xxxhdpi/branding.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
android/app/src/main/res/drawable-xxxhdpi/ic_notification.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 69 B |
@ -6,4 +6,7 @@
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
<item android:bottom="24dp">
|
||||
<bitmap android:gravity="bottom" android:src="@drawable/branding"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
Before Width: | Height: | Size: 544 B |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 952 B |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 872 B |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 442 B |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 644 B |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 594 B |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 721 B |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 1.0 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 12 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 1.4 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 17 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 9.2 KiB |
5
android/app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#FFFFFFFF</color>
|
||||
<color name="ic_notification_background">#00000000</color>
|
||||
</resources>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<style name="LaunchTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
@ -16,7 +16,7 @@
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
7
android/app/src/main/res/xml/check_in_widget.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:initialLayout="@layout/glance_default_loading_layout"
|
||||
android:minWidth="40dp"
|
||||
android:minHeight="40dp"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:updatePeriodMillis="10000">
|
||||
</appwidget-provider>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path
|
||||
name="external_files"
|
||||
path="." />
|
||||
</paths>
|
7
android/app/src/main/res/xml/random_post_widget.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:initialLayout="@layout/glance_default_loading_layout"
|
||||
android:minWidth="240dp"
|
||||
android:minHeight="40dp"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:updatePeriodMillis="10000">
|
||||
</appwidget-provider>
|
27
android/build.gradle
Normal file
@ -0,0 +1,27 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
eachDependency {
|
||||
if ((requested.group == "androidx.work") && (requested.name.startsWith("work-runtime"))) {
|
||||
useVersion("2.9.1")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = "../build"
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(":app")
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|