Compare commits
1 commit
main
...
krille/fcm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e83130a4df |
3
.github/CODEOWNERS
vendored
|
|
@ -1,3 +0,0 @@
|
|||
* @krille-chan
|
||||
pubspec.* @dependabot
|
||||
lib/l10n/*.arb @weblate
|
||||
13
.github/FUNDING.yml
vendored
|
|
@ -1,13 +0,0 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: krille
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: KrilleChritzelius
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
73
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -1,73 +0,0 @@
|
|||
name: 🐛 Bug report
|
||||
description: Create a report to help us improve
|
||||
labels: bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: bug-description
|
||||
attributes:
|
||||
label: "Bug Description"
|
||||
description: "A clear and concise description of what the bug is. Please add screenshots if you have as they usually help us a lot."
|
||||
placeholder: "Describe the bug here..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce-steps
|
||||
attributes:
|
||||
label: "Steps to Reproduce"
|
||||
description: "Steps to reproduce the behavior:"
|
||||
placeholder: "1. Go to '...'\n2. Click on '...'\n3. Scroll down to '...'\n4. See error"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: "Expected Behavior"
|
||||
description: "A clear and concise description of what you expected to happen."
|
||||
placeholder: "Describe what you expected to happen here..."
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: app-version
|
||||
attributes:
|
||||
label: "App Version"
|
||||
description: "Please provide the version of the app you are using."
|
||||
placeholder: "e.g. 1.12.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: "Platform"
|
||||
description: "Select the platform where the bug occurs."
|
||||
options:
|
||||
- Android (PlayStore)
|
||||
- Android (F-Droid)
|
||||
- Android (Other)
|
||||
- iOS (iPhone)
|
||||
- iOS (iPad)
|
||||
- Web (Chrome(ium))
|
||||
- Web (Firefox)
|
||||
- Web (Safari)
|
||||
- Linux (Snap)
|
||||
- Linux (Flatpak)
|
||||
- Linux (Other)
|
||||
- macOS (iOS/iPadOS version)
|
||||
- macOS (Self-compiled)
|
||||
- Windows (Self-compiled)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: platform-info
|
||||
attributes:
|
||||
label: "Additional Platform Information"
|
||||
description: "Please provide the following information:"
|
||||
placeholder: "Device: [e.g. iPhone6, PC, Pixel 3]\nOS: [e.g. iOS, Android, Windows, Linux, macOS]\nBrowser (if applicable): [e.g. Chrome, Safari]"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: "Additional Context"
|
||||
description: "Add any other context about the problem here."
|
||||
validations:
|
||||
required: false
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -1,5 +0,0 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 👬 FluffyChat Community
|
||||
url: https://matrix.to/#/#fluffy-space:matrix.org
|
||||
about: Please ask and answer questions here.
|
||||
34
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
|
|
@ -1,34 +0,0 @@
|
|||
name: 💡 Feature Request
|
||||
description: Suggest an idea for this project
|
||||
labels: enhancement
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: "Feature Description"
|
||||
description: "Provide a clear and concise description of the feature."
|
||||
placeholder: "Describe the feature here..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: "Rationale"
|
||||
description: "Explain why this feature should be added."
|
||||
placeholder: "Describe the rationale for the feature here..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: mockup
|
||||
attributes:
|
||||
label: "Mockup"
|
||||
description: "If applicable, add any visual mock-ups of the feature."
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: "Additional Context"
|
||||
description: "Add any other context or screenshots about the feature request here."
|
||||
validations:
|
||||
required: false
|
||||
27
.github/ISSUE_TEMPLATE/issue_pr_management.yml
vendored
|
|
@ -1,27 +0,0 @@
|
|||
name: Close Inactive Issues And PRs
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
days-before-issue-stale: 365
|
||||
days-before-issue-close: 14
|
||||
stale-issue-label: "stale"
|
||||
stale-issue-message: "This issue is stale because it has been open for 365 days with no activity."
|
||||
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
|
||||
stale-pr-message: "This pull request is stale because it has been open for 365 days with no activity."
|
||||
close-pr-message: "This pull request was closed because it has been inactive for 14 days since being marked as stale."
|
||||
days-before-pr-stale: 365
|
||||
days-before-pr-close: 14
|
||||
exempt-milestones: true
|
||||
exempt-assignees: krille-chan
|
||||
operations-per-run: 500
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
44
.github/ISSUE_TEMPLATE/test_report.md
vendored
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
name: 📝 Test
|
||||
about: A detailed protocol for testing all features
|
||||
title: 'Test Report'
|
||||
labels: test
|
||||
---
|
||||
|
||||
1. App receives push notifications over Firebase Cloud Messaging when it is in background/terminated:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
2. App receives push notifications over Unified Push when it is in background/terminated:
|
||||
- [ ] Android
|
||||
3. Notifications for rooms, which are not in foreground, are working:
|
||||
- [ ] Web
|
||||
- [ ] Linux
|
||||
4. QR Code scanner can still scan links to start a new chat:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
5. Recording and playing voice messages works:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
- [ ] Web (play only)
|
||||
6. Sending and downloading files/images works:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
- [ ] Web
|
||||
- [ ] Linux
|
||||
7. Sharing texts/files/images from other apps to FluffyChat works:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
8. Login with single sign on works:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
- [ ] Web
|
||||
- [ ] Linux
|
||||
9. Test if the app lock works as intended and appears on opening/resuming the app:
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
10. Drag&Drop to send a file into a chat still works:
|
||||
- [ ] Web
|
||||
- [ ] Linux
|
||||
11. Deeplinks are still working? https://matrix.to/#/@krille:janian.de
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
50
.github/actions/free_up_space/action.yaml
vendored
|
|
@ -1,50 +0,0 @@
|
|||
name: "Free up space"
|
||||
|
||||
inputs:
|
||||
target:
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Free up space
|
||||
shell: bash
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /usr/local/share/boost
|
||||
sudo rm -rf /usr/local/share/chromium
|
||||
sudo rm -rf /usr/local/share/powershell
|
||||
sudo rm -rf /usr/local/share/vcpkg
|
||||
sudo rm -rf /usr/local/share/miniconda
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf /opt/hostedtoolcache/CodeQL
|
||||
sudo rm -rf /opt/hostedtoolcache/go
|
||||
sudo rm -rf /opt/hostedtoolcache/Python
|
||||
sudo rm -rf /opt/hostedtoolcache/node
|
||||
sudo rm -rf /opt/hostedtoolcache/R
|
||||
sudo rm -rf /opt/hostedtoolcache/Java
|
||||
sudo rm -rf /opt/hostedtoolcache/LLVM
|
||||
sudo rm -rf /opt/hostedtoolcache/Swift
|
||||
sudo rm -rf /opt/hostedtoolcache/Php
|
||||
sudo rm -rf /opt/hostedtoolcache/Perl
|
||||
sudo rm -rf /opt/hostedtoolcache/Scala
|
||||
sudo rm -rf /opt/hostedtoolcache/Julia
|
||||
sudo rm -rf /opt/hostedtoolcache/Mono
|
||||
sudo rm -rf /opt/hostedtoolcache/PowerShell
|
||||
sudo rm -rf /opt/hostedtoolcache/Crystal
|
||||
sudo rm -rf /opt/hostedtoolcache/Elixir
|
||||
sudo rm -rf /opt/hostedtoolcache/Erlang
|
||||
sudo rm -rf /opt/hostedtoolcache/FSharp
|
||||
sudo rm -rf /opt/hostedtoolcache/Haskell
|
||||
sudo rm -rf /opt/hostedtoolcache/OCaml
|
||||
sudo rm -rf /opt/hostedtoolcache/Sbt
|
||||
sudo rm -rf /opt/hostedtoolcache/Solidity
|
||||
sudo rm -rf /opt/hostedtoolcache/VisualStudio
|
||||
sudo rm -rf /opt/hostedtoolcache/WinAppDriver
|
||||
sudo rm -rf /opt/hostedtoolcache/Xamarin
|
||||
sudo rm -rf /opt/hostedtoolcache/Yarn
|
||||
sudo rm -rf /opt/hostedtoolcache/Zephyr
|
||||
sudo rm -rf /opt/hostedtoolcache/zig
|
||||
sudo rm -rf /opt/hostedtoolcache/zulu
|
||||
sudo rm -rf /opt/hostedtoolcache/azcopy
|
||||
echo "export CARGO_BUILD_JOBS=1" >> $GITHUB_ENV
|
||||
23
.github/dependabot.yml
vendored
|
|
@ -1,23 +0,0 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pub"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "*"
|
||||
commit-message:
|
||||
prefix: "build: "
|
||||
include: "scope"
|
||||
assignees:
|
||||
- "krille-chan"
|
||||
open-pull-requests-limit: 5
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "*"
|
||||
commit-message:
|
||||
prefix: "build: "
|
||||
include: "scope"
|
||||
14
.github/pull_request_template.md
vendored
|
|
@ -1,14 +0,0 @@
|
|||
*Thank you so much for your contribution to FluffyChat ❤️❤️❤️*
|
||||
|
||||
- [ ] I have read and understood the [contributing guidelines](https://github.com/krille-chan/fluffychat/blob/main/CONTRIBUTING.md).
|
||||
|
||||
### Pull Request has been tested on:
|
||||
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
- [ ] Browser (Chromium based)
|
||||
- [ ] Browser (Firefox based)
|
||||
- [ ] Browser (WebKit based)
|
||||
- [ ] Desktop Linux
|
||||
- [ ] Desktop Windows
|
||||
- [ ] Desktop macOS
|
||||
249
.github/workflows/integrate.yaml
vendored
|
|
@ -1,249 +0,0 @@
|
|||
name: Pull Request Workflow
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
merge_group:
|
||||
|
||||
jobs:
|
||||
code_tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: webiny/action-conventional-commits@v1.3.1
|
||||
- run: ./scripts/generate-locale-config.sh
|
||||
- run: git diff --exit-code
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- name: Check for unused translations
|
||||
run: flutter pub run translations_cleaner list-unused-terms -a
|
||||
- run: flutter pub get
|
||||
- name: Check if pubspec.lock is up to date
|
||||
run: git diff --exit-code pubspec.lock
|
||||
- name: Check formatting
|
||||
run: dart format lib/ test/ --set-exit-if-changed
|
||||
- name: Check import formatting
|
||||
run: dart run import_sorter:main --no-comments --exit-if-changed
|
||||
- name: Check license compliance
|
||||
run: dart run license_checker check-licenses -c licenses.yaml --problematic
|
||||
- run: flutter analyze
|
||||
- name: Search unused dependencies
|
||||
run: |
|
||||
dart pub global activate dependency_validator
|
||||
dart pub global run dependency_validator
|
||||
- run: dart run dart_code_linter:metrics analyze lib --reporter=github
|
||||
- run: dart run dart_code_linter:metrics check-unused-code lib
|
||||
- run: dart run dart_code_linter:metrics check-unused-files lib
|
||||
- run: dart run dart_code_linter:metrics check-unused-l10n lib
|
||||
- name: Check for commented-out Dart code with semicolons
|
||||
run: |
|
||||
if grep -R --include="*.dart" -nE '^[[:space:]]*//[^/<].*;[[:space:]]*$' lib/; then
|
||||
echo ""
|
||||
echo "❌ Found commented-out Dart code ending with semicolon."
|
||||
exit 1
|
||||
fi
|
||||
- name: Add Firebase Messaging
|
||||
run: ./scripts/add-firebase-messaging.sh
|
||||
- run: flutter analyze
|
||||
- run: flutter test
|
||||
|
||||
build_debug_apk:
|
||||
needs: [ code_tests ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/free_up_space
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
with:
|
||||
cache: true
|
||||
- name: Cache Gradle
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: gradle-${{ runner.os }}-
|
||||
- run: ./scripts/add-firebase-messaging.sh
|
||||
- run: flutter build apk --debug --target-platform android-x64
|
||||
- name: Upload Debug APK
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: debug-apk-x64
|
||||
path: build/app/outputs/flutter-apk/app-debug.apk
|
||||
|
||||
build_debug_web:
|
||||
needs: [ code_tests ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- run: rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
- run: flutter pub get
|
||||
- name: Prepare web
|
||||
run: ./scripts/prepare-web.sh
|
||||
- run: flutter build web --dart-define=WITH_SEMANTICS=true
|
||||
- name: Upload Web Build
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Web Build
|
||||
path: build/web
|
||||
|
||||
build_debug_linux:
|
||||
needs: [ code_tests ]
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ x64, arm64 ]
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest'}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get install git wget curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libwebkit2gtk-4.1-dev -y
|
||||
- run: echo "FLUTTER_VERSION=$(yq '.environment.flutter' < .tool_versions.yaml)" >> $GITHUB_ENV
|
||||
- name: Install Flutter
|
||||
run: |
|
||||
git clone --branch ${{ env.FLUTTER_VERSION }} https://github.com/flutter/flutter.git
|
||||
./flutter/bin/flutter doctor
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- run: ./flutter/bin/flutter pub get
|
||||
- run: ./flutter/bin/flutter build linux --target-platform linux-${{ matrix.arch }}
|
||||
|
||||
build_debug_ios:
|
||||
needs: [ code_tests ]
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- name: Use Xcode 16.4
|
||||
run: sudo xcode-select --switch /Applications/Xcode_16.4.app
|
||||
- run: brew install sqlcipher
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- name: Add Firebase Messaging
|
||||
run: |
|
||||
flutter pub add fcm_shared_isolate:0.1.0
|
||||
sed -i '' 's,//<GOOGLE_SERVICES>,,g' lib/utils/background_push.dart
|
||||
- run: flutter pub get
|
||||
- run: flutter build ios --no-codesign
|
||||
|
||||
integration_test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
needs: [ build_debug_apk ]
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [34]
|
||||
env:
|
||||
ANDROID_USER_HOME: /home/runner/.android
|
||||
ANDROID_EMULATOR_HOME: /home/runner/.android
|
||||
ANDROID_AVD_HOME: /home/runner/.android/avd
|
||||
AVD_CONFIG_PATH: "~/.android/avd/test.avd/config.ini"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: debug-apk-x64
|
||||
path: .
|
||||
- uses: ./.github/actions/free_up_space
|
||||
# https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
|
||||
- name: Enable KVM group perms
|
||||
run: |
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger --name-match=kvm
|
||||
- name: AVD cache
|
||||
uses: actions/cache@v5
|
||||
id: avd-cache
|
||||
with:
|
||||
path: ~/.android/*
|
||||
key: avd-${{ matrix.api-level }}-integration_docker
|
||||
- name: create AVD and generate snapshot for caching
|
||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: google_apis
|
||||
arch: x86_64
|
||||
cores: 16
|
||||
ndk: 28.2.13676358
|
||||
force-avd-creation: false
|
||||
disk-size: 4096M
|
||||
ram-size: 4096M
|
||||
sdcard-path-or-size: 4096M
|
||||
emulator-options: -no-window -wipe-data -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
script: |
|
||||
cat ${{ env.AVD_CONFIG_PATH }}
|
||||
|
||||
sed -i.bak 's/hw.lcd.density = .*/hw.lcd.density=420/' ${{ env.AVD_CONFIG_PATH }}
|
||||
sed -i.bak 's/hw.lcd.height = .*/hw.lcd.height=1920/' ${{ env.AVD_CONFIG_PATH }}
|
||||
sed -i.bak 's/hw.lcd.width = .*/hw.lcd.width=1080/' ${{ env.AVD_CONFIG_PATH }}
|
||||
|
||||
if ! grep -q "hw.lcd.density" ${{ env.AVD_CONFIG_PATH }} && echo "hw.lcd.density = 420" >> ${{ env.AVD_CONFIG_PATH }}; then :; fi
|
||||
if ! grep -q "hw.lcd.height" ${{ env.AVD_CONFIG_PATH }} && echo "hw.lcd.height = 1920" >> ${{ env.AVD_CONFIG_PATH }}; then :; fi
|
||||
if ! grep -q "hw.lcd.width" ${{ env.AVD_CONFIG_PATH }} && echo "hw.lcd.width = 1080" >> ${{ env.AVD_CONFIG_PATH }}; then :; fi
|
||||
|
||||
echo "Emulator settings (${{ env.AVD_CONFIG_PATH }})"
|
||||
cat ${{ env.AVD_CONFIG_PATH }}
|
||||
echo "Generated AVD snapshot for caching."
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- uses: remarkablemark/setup-maestro-cli@v1
|
||||
- name: Load integration test env
|
||||
run: cat integration_test/data/integration_users.env >> $GITHUB_ENV
|
||||
- name: Prepare Homeserver
|
||||
run: |
|
||||
docker run -d --name synapse --tmpfs /data \
|
||||
--volume="$(pwd)/integration_test/synapse/data/homeserver.yaml":/data/homeserver.yaml:rw \
|
||||
--volume="$(pwd)/integration_test/synapse/data/localhost.log.config":/data/localhost.log.config:rw \
|
||||
-p 80:80 matrixdotorg/synapse:latest
|
||||
while ! curl -XGET "http://$HOMESERVER/_matrix/client/v3/login" >/dev/null 2>/dev/null; do
|
||||
echo "Waiting for homeserver to be available... (GET http://$HOMESERVER/_matrix/client/v3/login)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Homeserver is online!"
|
||||
|
||||
# create users
|
||||
curl -fS --retry 3 -XPOST -d "{\"username\":\"$USER1_NAME\", \"password\":\"$USER1_PW\", \"inhibit_login\":true, \"auth\": {\"type\":\"m.login.dummy\"}}" "http://$HOMESERVER/_matrix/client/r0/register"
|
||||
curl -fS --retry 3 -XPOST -d "{\"username\":\"$USER2_NAME\", \"password\":\"$USER2_PW\", \"inhibit_login\":true, \"auth\": {\"type\":\"m.login.dummy\"}}" "http://$HOMESERVER/_matrix/client/r0/register"
|
||||
|
||||
- name: Integration tests
|
||||
id: integration_tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: google_apis
|
||||
arch: x86_64
|
||||
cores: 16
|
||||
ndk: 28.2.13676358
|
||||
force-avd-creation: false
|
||||
disk-size: 4096M
|
||||
ram-size: 4096M
|
||||
sdcard-path-or-size: 4096M
|
||||
emulator-options: -no-snapshot-save -no-window -wipe-data -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
script: |
|
||||
flutter run --use-application-binary=$PWD/app-debug.apk > flutter_logs.txt 2>&1 &
|
||||
FLUTTER_PID=$!
|
||||
maestro test integration_test/login.yaml --env HOMESERVER=10.0.2.2 --env USER1_NAME=${USER1_NAME} --env USER1_PW=${USER1_PW}
|
||||
kill $FLUTTER_PID 2>/dev/null || true
|
||||
cp flutter_logs.txt ~/.maestro/tests/
|
||||
- name: Upload Flutter and Maestro logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: maestro-logs
|
||||
path: ~/.maestro/tests
|
||||
if-no-files-found: ignore
|
||||
78
.github/workflows/main_deploy.yaml
vendored
|
|
@ -1,78 +0,0 @@
|
|||
name: Main Deploy Workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: main_deploy
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy_web:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- run: rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
- name: Prepare web
|
||||
run: ./scripts/prepare-web.sh
|
||||
- run: rm ./assets/vodozemac/.gitignore
|
||||
- run: flutter pub get
|
||||
- name: Build Release Web
|
||||
run: flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps --base-href "/nightly/"
|
||||
- run: mv build/web/ public
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }}
|
||||
publish_dir: ./public
|
||||
publish_branch: gh-pages
|
||||
destination_dir: nightly
|
||||
|
||||
deploy_playstore_internal:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: '3.3'
|
||||
- uses: ./.github/actions/free_up_space
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- name: Install Fastlane
|
||||
run: gem install fastlane -NV
|
||||
- name: Add Firebase Messaging
|
||||
run: |
|
||||
echo '${{secrets.GOOGLE_SERVICES_JSON}}' | base64 -d > android/app/google-services.json
|
||||
./scripts/add-firebase-messaging.sh
|
||||
- run: flutter pub get
|
||||
- name: Prepare Android Release Build
|
||||
env:
|
||||
FDROID_KEY: ${{ secrets.FDROID_KEY }}
|
||||
FDROID_KEY_PASS: ${{ secrets.FDROID_KEY_PASS }}
|
||||
PLAYSTORE_DEPLOY_KEY: ${{ secrets.PLAYSTORE_DEPLOY_KEY }}
|
||||
run: ./scripts/prepare-android-release.sh
|
||||
- name: Build Android Release
|
||||
run: flutter build appbundle --target-platform android-arm,android-arm64
|
||||
- name: Set changelog
|
||||
working-directory: android/fastlane/metadata/android/en-US/changelogs
|
||||
run: git log --no-merges -1 --pretty=%B > default.txt
|
||||
- name: Deploy Android Release
|
||||
run: |
|
||||
mkdir -p build/android
|
||||
cp build/app/outputs/bundle/release/app-release.aab build/android/
|
||||
cd android
|
||||
bundle install
|
||||
bundle update fastlane
|
||||
bundle exec fastlane deploy_internal_test
|
||||
cd ..
|
||||
60
.github/workflows/matrix_notify.yaml
vendored
|
|
@ -1,60 +0,0 @@
|
|||
name: Matrix Notification
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
notify:
|
||||
if: ${{ (github.event_name == 'issues' && github.event.issue.user.login != 'krille-chan') || (github.event_name == 'pull_request_target' && github.event.pull_request.user.login != 'krille-chan') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send notification to Matrix room
|
||||
env:
|
||||
HOMESERVER: ${{ secrets.MATRIX_HOMESERVER }}
|
||||
ACCESS_TOKEN: ${{ secrets.MATRIX_ACCESS_TOKEN }}
|
||||
ROOM_ID: ${{ secrets.MATRIX_ROOM_ID }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||
ISSUE_URL: ${{ github.event.issue.html_url }}
|
||||
ISSUE_LABELS: ${{ join(github.event.issue.labels.*.name, ', ') }}
|
||||
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||
PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ', ') }}
|
||||
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
run: |
|
||||
if [ "${EVENT_NAME}" = "issues" ]; then
|
||||
EMOJI="📝"
|
||||
PREFIX="New Issue"
|
||||
TITLE="${ISSUE_TITLE}"
|
||||
URL="${ISSUE_URL}"
|
||||
LABELS="${ISSUE_LABELS}"
|
||||
AUTHOR="${ISSUE_AUTHOR}"
|
||||
else
|
||||
EMOJI="🔀"
|
||||
PREFIX="New Pull Request"
|
||||
TITLE="${PR_TITLE}"
|
||||
URL="${PR_URL}"
|
||||
LABELS="${PR_LABELS}"
|
||||
AUTHOR="${PR_AUTHOR}"
|
||||
fi
|
||||
|
||||
AUTHOR_URL="https://github.com/${AUTHOR}"
|
||||
PLAIN="${EMOJI} ${PREFIX} by ${AUTHOR}: ${TITLE} - ${URL}"
|
||||
HTML="<h3>${EMOJI} ${PREFIX}</h3>"
|
||||
HTML="${HTML}<b><a href='${URL}'>${TITLE}</a></b><br/>"
|
||||
HTML="${HTML}👤 <a href='${AUTHOR_URL}'>${AUTHOR}</a>"
|
||||
if [ -n "${LABELS}" ]; then
|
||||
HTML="${HTML}<br/>🏷️ ${LABELS}"
|
||||
fi
|
||||
TXN_ID=$(date +%s%N)
|
||||
|
||||
curl -s -o /dev/null -w "%{http_code}" -X PUT \
|
||||
"${HOMESERVER}/_matrix/client/v3/rooms/${ROOM_ID}/send/m.room.message/${TXN_ID}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(jq -n --arg body "$PLAIN" --arg html "$HTML" \
|
||||
'{"msgtype":"m.notice","body":$body,"format":"org.matrix.custom.html","formatted_body":$html}')"
|
||||
211
.github/workflows/release.yaml
vendored
|
|
@ -1,211 +0,0 @@
|
|||
name: Release Workflow
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
concurrency:
|
||||
group: release_workflow
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build_web:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- run: rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
- run: flutter pub get
|
||||
- name: Prepare web
|
||||
run: ./scripts/prepare-web.sh
|
||||
- run: rm ./assets/vodozemac/.gitignore
|
||||
- name: Build Release Web
|
||||
run: flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps
|
||||
- name: Create archive
|
||||
run: tar -czf fluffychat-web.tar.gz build/web/
|
||||
- name: Upload Web Build
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Web Build
|
||||
path: fluffychat-web.tar.gz
|
||||
- name: Upload to release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: fluffychat-web.tar.gz
|
||||
asset_name: fluffychat-web.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
- name: Clone fluffychat website
|
||||
run: |
|
||||
git clone https://github.com/krille-chan/fluffychat-website.git
|
||||
cp CHANGELOG.md fluffychat-website/
|
||||
cp PRIVACY.md fluffychat-website/
|
||||
- name: Build website
|
||||
working-directory: fluffychat-website
|
||||
run: |
|
||||
npm install tailwindcss @tailwindcss/cli
|
||||
npx tailwindcss -i ./src/styles.css -o ./src/assets/tailwind.css --minify
|
||||
npx @11ty/eleventy
|
||||
mv public ../
|
||||
- name: Copy FluffyChat web into it
|
||||
run: |
|
||||
mkdir public/web
|
||||
mkdir public/nightly
|
||||
cp -r build/web/* public/web/
|
||||
cp -r build/web/* public/nightly/
|
||||
echo "fluffychat.im" >> public/CNAME
|
||||
- name: Deploy to GitHub Pages
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }}
|
||||
publish_dir: ./public
|
||||
publish_branch: gh-pages
|
||||
cname: fluffychat.im
|
||||
|
||||
build_apk:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- name: Add Firebase Messaging
|
||||
run: |
|
||||
echo '${{secrets.GOOGLE_SERVICES_JSON}}' | base64 -d > android/app/google-services.json
|
||||
./scripts/add-firebase-messaging.sh
|
||||
- uses: ./.github/actions/free_up_space
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- run: flutter pub get
|
||||
- name: Prepare Android Release Build
|
||||
env:
|
||||
FDROID_KEY: ${{ secrets.FDROID_KEY }}
|
||||
FDROID_KEY_PASS: ${{ secrets.FDROID_KEY_PASS }}
|
||||
PLAYSTORE_DEPLOY_KEY: ${{ secrets.PLAYSTORE_DEPLOY_KEY }}
|
||||
run: ./scripts/prepare-android-release.sh
|
||||
- run: flutter build apk --release --target-platform android-arm,android-arm64
|
||||
- name: Upload to release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: build/app/outputs/apk/release/app-release.apk
|
||||
asset_name: fluffychat.apk
|
||||
asset_content_type: application/vnd.android.package-archive
|
||||
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ x64, arm64 ]
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest'}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libwebkit2gtk-4.1-dev -y
|
||||
- run: echo "FLUTTER_VERSION=$(yq '.environment.flutter' < .tool_versions.yaml)" >> $GITHUB_ENV
|
||||
- name: Install Flutter
|
||||
run: |
|
||||
git clone --branch ${{ env.FLUTTER_VERSION }} https://github.com/flutter/flutter.git
|
||||
./flutter/bin/flutter doctor
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- run: ./flutter/bin/flutter pub get
|
||||
- run: ./flutter/bin/flutter build linux --target-platform linux-${{ matrix.arch }}
|
||||
- name: Create archive
|
||||
run: tar -czf fluffychat-linux-${{ matrix.arch }}.tar.gz -C build/linux/${{ matrix.arch }}/release/bundle/ .
|
||||
- name: Upload to release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: fluffychat-linux-${{ matrix.arch }}.tar.gz
|
||||
asset_name: fluffychat-linux-${{ matrix.arch }}.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
|
||||
deploy_playstore:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version-file: .tool_versions.yaml
|
||||
cache: true
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: '3.3'
|
||||
- uses: ./.github/actions/free_up_space
|
||||
- uses: moonrepo/setup-rust@v1
|
||||
- name: Install Fastlane
|
||||
working-directory: android
|
||||
run: gem install fastlane -NV
|
||||
- name: Add Firebase Messaging
|
||||
run: |
|
||||
echo '${{secrets.GOOGLE_SERVICES_JSON}}' | base64 -d > android/app/google-services.json
|
||||
./scripts/add-firebase-messaging.sh
|
||||
- run: flutter pub get
|
||||
- name: Prepare Android Release Build
|
||||
env:
|
||||
FDROID_KEY: ${{ secrets.FDROID_KEY }}
|
||||
FDROID_KEY_PASS: ${{ secrets.FDROID_KEY_PASS }}
|
||||
PLAYSTORE_DEPLOY_KEY: ${{ secrets.PLAYSTORE_DEPLOY_KEY }}
|
||||
run: ./scripts/prepare-android-release.sh
|
||||
- name: Build Android Release
|
||||
run: flutter build appbundle --target-platform android-arm,android-arm64
|
||||
- name: Get Tag Name
|
||||
id: tag_name
|
||||
run: echo "::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/})"
|
||||
- name: Deploy Android Release
|
||||
run: |
|
||||
mkdir -p build/android
|
||||
cp build/app/outputs/bundle/release/app-release.aab build/android/
|
||||
cd android
|
||||
bundle install
|
||||
bundle update fastlane
|
||||
bundle exec fastlane deploy_internal_test
|
||||
if [[ $GITHUB_REF_NAME == rc* ]]; then
|
||||
bundle exec fastlane deploy_candidate
|
||||
else
|
||||
bundle exec fastlane deploy_release
|
||||
fi
|
||||
cd ..
|
||||
|
||||
deploy_docker:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v6
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
21
.github/workflows/stale.yaml
vendored
|
|
@ -1,21 +0,0 @@
|
|||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
stale-issue-message: 'This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 30 days.'
|
||||
stale-pr-message: 'This PR is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 30 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity.'
|
||||
days-before-issue-stale: 365
|
||||
days-before-pr-stale: 365
|
||||
days-before-issue-close: 30
|
||||
days-before-pr-close: 30
|
||||
exempt-all-assignees: true
|
||||
operations-per-run: 1000
|
||||
24
.gitignore
vendored
|
|
@ -10,11 +10,11 @@
|
|||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
lib/generated_plugin_registrant.dart
|
||||
prime
|
||||
|
||||
# libolm package
|
||||
web/Imaging.js
|
||||
web/Imaging.wasm
|
||||
/assets/js/package/*
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
|
|
@ -38,7 +38,10 @@ web/Imaging.wasm
|
|||
/build/
|
||||
|
||||
# Web related
|
||||
docs/tailwind.css
|
||||
lib/generated_plugin_registrant.dart
|
||||
docs/build/
|
||||
docs/.jekyll-cache/
|
||||
docs/_site/
|
||||
|
||||
# Exceptions to above rules.
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
|
|
@ -50,25 +53,12 @@ docs/tailwind.css
|
|||
android/key.jks
|
||||
android/keys.json
|
||||
android/Gemfile.lock
|
||||
lib/l10n/*.dart
|
||||
lib/l10n_old
|
||||
ios/Flutter/.last_build_id
|
||||
ios/Podfile.lock
|
||||
ios/Runner.ipa
|
||||
ios/Runner/GoogleServices-Info.plist
|
||||
|
||||
/windows/out
|
||||
/winuwp/out
|
||||
/linux/out
|
||||
/macos/out
|
||||
.vs
|
||||
olm
|
||||
docs/node_modules
|
||||
rust
|
||||
|
||||
libcrypto.3.dylib
|
||||
android/app/src/main/jniLibs/**
|
||||
android/app/google-services.json
|
||||
web/pkg/package.json
|
||||
web/pkg/vodozemac_bindings_dart_bg.wasm
|
||||
web/pkg/vodozemac_bindings_dart.js
|
||||
web/native_executor.js*
|
||||
|
|
|
|||
362
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
variables:
|
||||
FLUTTER_VERSION: 3.0.2
|
||||
|
||||
image: cirrusci/flutter:${FLUTTER_VERSION}
|
||||
|
||||
.shared_windows_runners:
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
- windows-1809
|
||||
|
||||
stages:
|
||||
- coverage
|
||||
- release
|
||||
- deploy
|
||||
|
||||
code_analyze:
|
||||
stage: coverage
|
||||
script: [./scripts/code_analyze.sh]
|
||||
artifacts:
|
||||
reports:
|
||||
codequality: code-quality-report.json
|
||||
|
||||
code_analyze_beta:
|
||||
extends: code_analyze
|
||||
image:
|
||||
name: cirrusci/flutter:beta
|
||||
allow_failure: true
|
||||
|
||||
test:
|
||||
stage: coverage
|
||||
script: [flutter test]
|
||||
|
||||
integration_test:
|
||||
image: registry.gitlab.com/famedly/company/frontend/flutter-dockerimages/integration/stable:${FLUTTER_VERSION}
|
||||
stage: coverage
|
||||
services:
|
||||
- name: docker:dind
|
||||
alias: docker
|
||||
variables:
|
||||
# activate container-to-container networking
|
||||
FF_NETWORK_PER_BUILD: "true"
|
||||
# Tell docker CLI how to talk to Docker daemon.
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
# Use the overlayfs driver for improved performance.
|
||||
DOCKER_DRIVER: overlay2
|
||||
# Disable TLS since we're running inside local network.
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
before_script:
|
||||
- chmod 777 -R /dev/kvm
|
||||
- adb start-server
|
||||
- emulator -avd test -no-audio -no-boot-anim -no-window -accel on -gpu swiftshader_indirect &
|
||||
- apk update && apk add docker drill grep
|
||||
- chown -R 991:991 integration_test/synapse
|
||||
- docker run -d --name synapse --user 991:991 --network=host --volume="$(pwd)/integration_test/synapse/data":/data:rw -p 8008:8008 matrixdotorg/synapse:latest
|
||||
- sleep 20
|
||||
# create three test user
|
||||
- docker exec -i synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml --user alice --password AliceInWonderland --admin
|
||||
- docker exec -i synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml --user bob --password JoWirSchaffenDas --admin
|
||||
- docker exec -i synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml --user trudy --password HaveIBeenPwned --admin
|
||||
script:
|
||||
# properly set the homeserver IP for the test
|
||||
- sed -i "s/10.0.2.2/$(drill docker | grep -m 1 -P "\d+\.\d+\.\d+.\d+" | awk -F ' ' '{print $NF}')/g" integration_test/users.dart
|
||||
- curl docker:8008/_matrix/static/ 2> /dev/null | grep "It works! Synapse is running"
|
||||
- flutter pub get
|
||||
- flutter test integration_test
|
||||
tags:
|
||||
- famedly
|
||||
- docker
|
||||
timeout: 20m
|
||||
|
||||
build_web:
|
||||
stage: coverage
|
||||
before_script:
|
||||
[sudo apt update && sudo apt install curl -y, ./scripts/prepare-web.sh]
|
||||
script: [./scripts/build-web.sh]
|
||||
artifacts:
|
||||
paths:
|
||||
- build/web/
|
||||
|
||||
build_web_beta:
|
||||
extends: build_web
|
||||
image:
|
||||
name: cirrusci/flutter:beta
|
||||
allow_failure: true
|
||||
|
||||
build_windows:
|
||||
extends:
|
||||
- .shared_windows_runners
|
||||
stage: coverage
|
||||
before_script: [./scripts/prepare-windows.ps1]
|
||||
script: [./scripts/build-windows.ps1]
|
||||
artifacts:
|
||||
paths:
|
||||
- build/windows/runner/Release
|
||||
allow_failure: true
|
||||
|
||||
build_android_debug:
|
||||
stage: coverage
|
||||
script: [./scripts/build-android-debug.sh]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/app/outputs/apk/debug/app-debug.apk
|
||||
except:
|
||||
- main
|
||||
- tags
|
||||
|
||||
build_android_apk:
|
||||
stage: coverage
|
||||
before_script: [./scripts/prepare-android-release.sh]
|
||||
script: [./scripts/build-android-apk.sh]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/android/app-release.apk
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
|
||||
build_android_appbundle:
|
||||
stage: coverage
|
||||
before_script: [./scripts/prepare-android-release.sh]
|
||||
script: [./scripts/release-playstore-beta.sh]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/android/app-release.aab
|
||||
resource_group: playstore_release
|
||||
only:
|
||||
- main
|
||||
|
||||
upload-fdroid:
|
||||
stage: release
|
||||
before_script:
|
||||
- "which ssh-agent || (sudo apt-get update -y && sudo apt-get install openssh-client -y )"
|
||||
- "which rsync || (sudo apt-get update -y && sudo apt-get install rsync -y )"
|
||||
- "which pcregrep || (sudo apt-get update -y && sudo apt-get install pcregrep -y )"
|
||||
- eval $(ssh-agent -s)
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- ssh-keyscan -t rsa ssh.fdroid.nordgedanken.dev >> ~/.ssh/known_hosts
|
||||
script:
|
||||
- cd build/android/
|
||||
- export UPDATE_VERSION=$(pcregrep -o1 'version:\s([0-9]*\.[0-9]*\.[0-9]*)\+[0-9]*' ../../pubspec.yaml) && mv app-release.apk "${UPDATE_VERSION}.apk"
|
||||
- rsync -rav -e ssh ./ fluffy@ssh.fdroid.nordgedanken.dev:/opt/fdroid/fluffychat/repo
|
||||
- ssh fluffy@ssh.fdroid.nordgedanken.dev -t '/bin/bash -i -l -c "cd /opt/fdroid/fluffychat && source ../fdroidserver-env/bin/activate && fdroid update --verbose && deactivate"'
|
||||
needs: ["build_android_apk"]
|
||||
resource_group: playstore_release
|
||||
allow_failure: true
|
||||
only:
|
||||
- tags
|
||||
|
||||
upload-fdroid-nightly:
|
||||
stage: release
|
||||
before_script:
|
||||
- "which ssh-agent || (sudo apt-get update -y && sudo apt-get install openssh-client -y )"
|
||||
- "which rsync || (sudo apt-get update -y && sudo apt-get install rsync -y )"
|
||||
- "which pcregrep || (sudo apt-get update -y && sudo apt-get install pcregrep -y )"
|
||||
- eval $(ssh-agent -s)
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- ssh-keyscan -t rsa ssh.fdroid.nordgedanken.dev >> ~/.ssh/known_hosts
|
||||
script:
|
||||
- cd build/android/
|
||||
- export UPDATE_VERSION=$(pcregrep -o1 'version:\s([0-9]*\.[0-9]*\.[0-9]*)\+[0-9]*' ../../pubspec.yaml) && mv app-release.apk "${UPDATE_VERSION}_$(date +%s).apk"
|
||||
- rsync -rav -e ssh ./ fluffy@ssh.fdroid.nordgedanken.dev:/opt/fdroid/fluffychat-nightly/repo
|
||||
- ssh fluffy@ssh.fdroid.nordgedanken.dev -t '/bin/bash -i -l -c "cd /opt/fdroid/fluffychat-nightly && source ../fdroidserver-env/bin/activate && fdroid update --verbose && deactivate"'
|
||||
needs: ["build_android_apk"]
|
||||
resource_group: playstore_release
|
||||
allow_failure: true
|
||||
only:
|
||||
- main
|
||||
|
||||
pages:
|
||||
needs: ["build_web"]
|
||||
stage: deploy
|
||||
image: node
|
||||
script:
|
||||
- cd docs
|
||||
- npx tailwindcss -o ./tailwind.css --minify
|
||||
- cd ..
|
||||
- mv docs public
|
||||
- mv build/web/ public/web/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- main
|
||||
|
||||
build_linux_x86:
|
||||
stage: coverage
|
||||
before_script:
|
||||
[
|
||||
sudo apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install keyboard-configuration -y && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 -y,
|
||||
]
|
||||
script: [./scripts/build-linux.sh]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/linux/x64/release/bundle/
|
||||
|
||||
build_linux_arm64:
|
||||
stage: coverage
|
||||
before_script: [flutter upgrade]
|
||||
script: [./scripts/build-linux.sh]
|
||||
tags: [docker_arm64]
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/linux/arm64/release/bundle/
|
||||
|
||||
build_linux_appimage_x86:
|
||||
stage: deploy
|
||||
image: appimagecrafters/appimage-builder
|
||||
needs: [build_linux_x86]
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
script:
|
||||
- cp -r build/linux/x64/release/bundle appimage/FluffyChat.AppDir
|
||||
- cd appimage
|
||||
- cp FluffyChat.desktop FluffyChat.AppDir/
|
||||
- cp AppRun FluffyChat.AppDir/
|
||||
- cp ../assets/logo.svg FluffyChat.AppDir/fluffychat.svg
|
||||
- appimagetool -u "zsync|https://gitlab.com/famedly/fluffychat/-/releases/permalink/latest/downloads/FluffyChat-x86_64.AppImage.zsync" FluffyChat.AppDir
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- appimage/FluffyChat-x86_64.AppImage
|
||||
- appimage/FluffyChat-x86_64.AppImage.zsync
|
||||
|
||||
build_linux_appimage_arm64:
|
||||
stage: deploy
|
||||
image: appimagecrafters/appimage-builder
|
||||
needs: [build_linux_arm64]
|
||||
tags: [docker_arm64]
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
script:
|
||||
- cp -r build/linux/arm64/release/bundle appimage/FluffyChat.AppDir
|
||||
- cd appimage
|
||||
- cp FluffyChat.desktop FluffyChat.AppDir/
|
||||
- cp AppRun FluffyChat.AppDir/
|
||||
- cp ../assets/logo.svg FluffyChat.AppDir/fluffychat.svg
|
||||
- appimagetool -u "zsync|https://gitlab.com/famedly/fluffychat/-/releases/permalink/latest/downloads/FluffyChat-arm64.AppImage.zsync" FluffyChat.AppDir
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- appimage/FluffyChat-arm64.AppImage
|
||||
- appimage/FluffyChat-arm64.AppImage.zsync
|
||||
|
||||
update-dependencies:
|
||||
stage: coverage
|
||||
needs: []
|
||||
tags:
|
||||
- docker
|
||||
only:
|
||||
- schedules
|
||||
variables:
|
||||
HOST: ${CI_PROJECT_URL}
|
||||
UPDATE_BRANCH: ci-bot/dependency-updates
|
||||
PRIVATE_TOKEN: ${GITLAB_API_TOKEN}
|
||||
before_script:
|
||||
- eval $(ssh-agent -s)
|
||||
- echo "$SSH_PRIVATE_BOT_KEY" | tr -d '\r' | ssh-add - > /dev/null
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
- git config --global user.email "bot@fluffy.chat"
|
||||
- git config --global user.name "Dependency Update Bot"
|
||||
- sudo apt-get update && sudo apt-get install -y curl
|
||||
script:
|
||||
- ./scripts/update-dependencies.sh
|
||||
- git remote set-url --push origin git@gitlab.com:$CI_PROJECT_PATH
|
||||
- 'git diff --exit-code || (git checkout -B ${UPDATE_BRANCH} && git add . && git commit -m "chore: Update dependencies" && git push -f origin ${UPDATE_BRANCH} && ./scripts/open-mr.sh)'
|
||||
|
||||
.release:
|
||||
stage: release
|
||||
image: curlimages/curl:latest
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
|
||||
- if: '$CI_COMMIT_TAG =~ /^rc\d+\.\d+\.\d+-\d+$/'
|
||||
before_script:
|
||||
- export RELEASE_TYPE=$(echo $CI_COMMIT_TAG | grep -oE "[a-z]+")
|
||||
- export RELEASE_VERSION=$(echo $CI_COMMIT_TAG | grep -oE "\d+\.\d+\.\d+")
|
||||
- export PACKAGE_REGISTRY_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/fluffychat/${RELEASE_VERSION}"
|
||||
|
||||
upload-android:
|
||||
extends: .release
|
||||
script:
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file build/android/app-release.apk ${PACKAGE_REGISTRY_URL}/fluffychat.apk
|
||||
|
||||
upload-web:
|
||||
extends: .release
|
||||
script:
|
||||
- tar czf package.tar.gz -C build/web/ .
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-web.tar.gz
|
||||
|
||||
upload-linux-x86:
|
||||
extends: .release
|
||||
script:
|
||||
- tar czf package.tar.gz -C build/linux/x64/release/bundle/ .
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-linux-x86.tar.gz
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file appimage/FluffyChat-x86_64.AppImage ${PACKAGE_REGISTRY_URL}/FluffyChat-x86_64.AppImage
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file appimage/FluffyChat-x86_64.AppImage.zsync ${PACKAGE_REGISTRY_URL}/FluffyChat-x86_64.AppImage.zsync
|
||||
|
||||
upload-linux-arm64:
|
||||
extends: .release
|
||||
script:
|
||||
- tar czf package.tar.gz -C build/linux/arm64/release/bundle/ .
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-linux-arm64.tar.gz
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file appimage/FluffyChat-arm64.AppImage ${PACKAGE_REGISTRY_URL}/FluffyChat-arm64.AppImage
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file appimage/FluffyChat-arm64.AppImage.zsync ${PACKAGE_REGISTRY_URL}/FluffyChat-arm64.AppImage.zsync
|
||||
|
||||
upload-windows:
|
||||
extends: .release
|
||||
image: alpine:latest
|
||||
script:
|
||||
- apk add --no-cache curl zip
|
||||
- cd build/windows/runner/Release; zip -r ../../../../package.zip . ; cd -
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.zip ${PACKAGE_REGISTRY_URL}/fluffychat-windows.zip
|
||||
|
||||
upload-playstore:
|
||||
stage: release
|
||||
before_script: [./scripts/prepare-android-release.sh]
|
||||
script: [./scripts/release-playstore.sh]
|
||||
resource_group: playstore_release
|
||||
only:
|
||||
- tags
|
||||
|
||||
release:
|
||||
extends: .release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
|
||||
script:
|
||||
- |
|
||||
release-cli create --name "Release ${CI_COMMIT_TAG}" --tag-name $CI_COMMIT_TAG \
|
||||
--assets-link "{\"name\":\"fluffychat.apk\",\"url\":\"${PACKAGE_REGISTRY_URL}/fluffychat.apk\"}" \
|
||||
--assets-link "{\"name\":\"fluffychat-linux-x86.tar.gz\",\"url\":\"${PACKAGE_REGISTRY_URL}/fluffychat-linux-x86.tar.gz\"}" \
|
||||
--assets-link "{\"name\":\"fluffychat-linux-arm64.tar.gz\",\"url\":\"${PACKAGE_REGISTRY_URL}/fluffychat-linux-arm64.tar.gz\"}" \
|
||||
--assets-link "{\"name\":\"fluffychat-windows.zip\",\"url\":\"${PACKAGE_REGISTRY_URL}/fluffychat-windows.zip\"}" \
|
||||
--assets-link "{\"name\":\"fluffychat-web.tar.gz\",\"url\":\"${PACKAGE_REGISTRY_URL}/fluffychat-web.tar.gz\"}"
|
||||
--assets-link "{\"name\":\"FluffyChat-x86_64.AppImage\",\"url\":\"${PACKAGE_REGISTRY_URL}/FluffyChat-x86_64.AppImage\",\"filepath\":\"/FluffyChat-x86_64.AppImage\"}"
|
||||
--assets-link "{\"name\":\"FluffyChat-x86_64.AppImage.zsync\",\"url\":\"${PACKAGE_REGISTRY_URL}/FluffyChat-x86_64.AppImage.zsync\",\"filepath\":\"/FluffyChat-x86_64.AppImage.zsync\"}"
|
||||
--assets-link "{\"name\":\"FluffyChat-arm64.AppImage\",\"url\":\"${PACKAGE_REGISTRY_URL}/FluffyChat-arm64.AppImage\",\"filepath\":\"/FluffyChat-arm64.AppImage\"}"
|
||||
--assets-link "{\"name\":\"FluffyChat-arm64.AppImage.zsync\",\"url\":\"${PACKAGE_REGISTRY_URL}/FluffyChat-arm64.AppImage.zsync\",\"filepath\":\"/FluffyChat-arm64.AppImage.zsync\"}"
|
||||
29
.metadata
|
|
@ -1,11 +1,11 @@
|
|||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
# This file should be version controlled.
|
||||
|
||||
version:
|
||||
revision: "fcf2c11572af6f390246c056bc905eca609533a0"
|
||||
channel: "stable"
|
||||
revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
|
||||
|
|
@ -13,11 +13,26 @@ project_type: app
|
|||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
|
||||
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
- platform: android
|
||||
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
|
||||
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
- platform: ios
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
- platform: linux
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
- platform: macos
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
- platform: web
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
- platform: windows
|
||||
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
|
||||
|
||||
# User provided section
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
environment:
|
||||
flutter: 3.41.4
|
||||
2358
CHANGELOG.md
19
Dockerfile
|
|
@ -1,21 +1,10 @@
|
|||
FROM ghcr.io/cirruslabs/flutter as builder
|
||||
RUN sudo apt update && sudo apt install curl wget jq build-essential -y
|
||||
|
||||
WORKDIR /tmp
|
||||
RUN wget https://github.com/mikefarah/yq/releases/download/v4.40.5/yq_linux_amd64.tar.gz
|
||||
RUN tar -xzvf ./yq_linux_amd64.tar.gz
|
||||
RUN mv yq_linux_amd64 /usr/bin/yq
|
||||
|
||||
FROM cirrusci/flutter as builder
|
||||
RUN sudo apt update && sudo apt install curl -y
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
RUN rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
RUN ./scripts/prepare-web.sh
|
||||
COPY config.* /app/
|
||||
RUN flutter pub get
|
||||
RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps
|
||||
RUN ./scripts/build-web.sh
|
||||
|
||||
FROM docker.io/nginx:alpine
|
||||
RUN rm -rf /usr/share/nginx/html
|
||||
COPY --from=builder /app/build/web /usr/share/nginx/html
|
||||
COPY --from=builder /app/build/web /usr/share/nginx/html
|
||||
62
PRIVACY.md
|
|
@ -1,34 +1,40 @@
|
|||
# Privacy
|
||||
|
||||
FluffyChat is available on Android, iOS, Linux and as a web version. Desktop versions for Windows and macOS may follow.
|
||||
FluffyChat is available on Android, iOS and as a web version. Desktop versions for Windows, Linux and macOS may follow.
|
||||
|
||||
* [Matrix](#matrix)
|
||||
* [Database](#database)
|
||||
* [Encryption](#encryption)
|
||||
* [App Permissions](#app-permissions)
|
||||
* [Push Notifications](#push-notifications)
|
||||
* [PlayStore Safety Standards](#playstore-safety)
|
||||
* [Matrix](#1)
|
||||
* [Sentry](#2)
|
||||
* [Database](#3)
|
||||
* [Encryption](#4)
|
||||
* [App Permissions](#5)
|
||||
* [Push Notifications](#6)
|
||||
* [Stories](#7)
|
||||
|
||||
## <a id="matrix" href="#matrix">#</a> Matrix
|
||||
## Matrix<a id="1"/>
|
||||
FluffyChat uses the Matrix protocol. This means that FluffyChat is just a client that can be connected to any compatible matrix server. The respective data protection agreement of the server selected by the user then applies.
|
||||
|
||||
For convenience, one or more servers are set as default that the FluffyChat developers consider trustworthy. The developers of FluffyChat do not guarantee their trustworthiness. Before the first communication, users are informed which server they are connecting to.
|
||||
|
||||
FluffyChat only communicates with the selected server and with [OpenStreetMap](https://openstreetmap.org) to display maps.
|
||||
FluffyChat only communicates with the selected server, with sentry.io if enabled and with [OpenStreetMap](https://openstreetmap.org) to display maps.
|
||||
|
||||
More information is available at: [https://matrix.org](https://matrix.org)
|
||||
|
||||
## <a id="database" href="#database">#</a> Database
|
||||
FluffyChat caches some data received from the server in a local sqflite database on the device of the user. On web indexedDB is used. FluffyChat always tries to encrypt the database by using SQLCipher and stores the encryption key in the [Secure Storage](https://pub.dev/packages/flutter_secure_storage) of the device.
|
||||
## Sentry<a id="2"/>
|
||||
FluffyChat uses Sentry for crash reports if the user allows it.
|
||||
|
||||
More information is available at: [https://pub.dev/packages/sqflite](https://pub.dev/packages/sqflite) and [https://pub.dev/packages/sqlcipher_flutter_libs](https://pub.dev/packages/sqlcipher_flutter_libs)
|
||||
More information is available at: [https://sentry.io](https://sentry.io)
|
||||
|
||||
## <a id="encryption" href="#encryption">#</a> Encryption
|
||||
## Database<a id="3"/>
|
||||
FluffyChat caches some data received from the server in a local database on the device of the user.
|
||||
|
||||
More information is available at: [https://pub.dev/packages/hive](https://pub.dev/packages/hive)
|
||||
|
||||
## Encryption<a id="4"/>
|
||||
All communication of substantive content between Fluffychat and any server is done in secure way, using transport encryption to protect it.
|
||||
|
||||
FluffyChat also uses End-To-End-Encryption by using [Vodozemac](https://github.com/matrix-org/vodozemac) and enables it by default for private chats.
|
||||
FluffyChat is able to use End-To-End-Encryption as a tech preview.
|
||||
|
||||
## <a id="app-permissions" href="#app-permissions">#</a> App Permissions
|
||||
## App Permissions<a id="5"/>
|
||||
|
||||
The permissions are the same on Android and iOS but may differ in the name. This are the Android Permissions:
|
||||
|
||||
|
|
@ -51,7 +57,7 @@ The user is able to send files from the device's file system.
|
|||
#### Location
|
||||
FluffyChat makes it possible to share the current location via the chat. When the user shares their location, FluffyChat uses the device location service and sends the geo-data via Matrix.
|
||||
|
||||
## <a id="push-notifications" href="#push-notifications">#</a> Push Notifications
|
||||
## Push Notifications<a id="6"/>
|
||||
FluffyChat uses the Firebase Cloud Messaging service for push notifications on Android and iOS. This takes place in the following steps:
|
||||
1. The matrix server sends the push notification to the FluffyChat Push Gateway
|
||||
2. The FluffyChat Push Gateway forwards the message in a different format to Firebase Cloud Messaging
|
||||
|
|
@ -59,7 +65,7 @@ FluffyChat uses the Firebase Cloud Messaging service for push notifications on A
|
|||
4. The device receives the push notification from Firebase Cloud Messaging and displays it as a notification
|
||||
|
||||
The source code of the push gateway can be viewed here:
|
||||
[https://github.com/krille-chan/fluffygate](https://github.com/krille-chan/fluffygate)
|
||||
[https://gitlab.com/famedly/services/famedly-push-gateway](https://gitlab.com/famedly/services/famedly-push-gateway)
|
||||
|
||||
`event_id_only` is used as the format for the push notification. A typical push notification therefore only contains:
|
||||
- Event ID
|
||||
|
|
@ -94,20 +100,22 @@ A typical push notification could look like this:
|
|||
|
||||
FluffyChat sets the `event_id_only` flag at the Matrix Server. This server is then responsible to send the correct data.
|
||||
|
||||
## Stories<a id="7"/>
|
||||
|
||||
# <a id="playstore-safety" href="#playstore-safety">#</a> Explanation of FluffyChat's Compliance with Google Play Store's Safety Standards
|
||||
FluffyChat supports stories which is a feature similar to WhatsApp status or Instagram stories. However it is just a different GUI for the same room-related communication. More information about the feature can be found here:
|
||||
|
||||
FluffyChat is committed to promoting a safe and respectful environment for all users. As a Matrix client, FluffyChat connects users to various Matrix servers. Please note that FluffyChat does not host or manage any servers directly, and as such, we do not have the capability to enforce content moderation or deletion within the app itself.
|
||||
https://github.com/krillefear/matrix-doc/blob/main/proposals/3588-stories-as-rooms.md
|
||||
|
||||
To enhance user safety and help protect against the sexual abuse and exploitation of children, FluffyChat enables users to report inappropriate content directly to server administrators.
|
||||
Stories are basically:
|
||||
|
||||
#### Reporting Content or Users:
|
||||
- End to end encrypted rooms
|
||||
- Read-only rooms with only one admin who can post stuff (while there is no technical limitation to have multiple admins)
|
||||
|
||||
1. Mark a message in the chat: Tap and hold the message you wish to report.
|
||||
2. Report the message: Select the "Report" option.
|
||||
3. Provide a reason and score: Enter the reason for reporting and assign a score from 1-100 to indicate how offensive the content is.
|
||||
4. Notification to admin: The server administrator will be notified of the reported content.
|
||||
By default:
|
||||
|
||||
In addition to reporting messages, users can also report other users following a similar process.
|
||||
- The user has to invite all contacts manually to a story room
|
||||
- The user can only invite contacts (matrix users the user shares a DM room with) to the story room
|
||||
- The story room is created when the first story is posted
|
||||
- User can mute and leave story rooms
|
||||
|
||||
We encourage server administrators to adhere to strict safety standards and provide mechanisms for addressing and moderating inappropriate content. For more information on the Matrix protocol and its safety standards, please refer to the following link: https://matrix.org/docs/older/moderation/
|
||||
The user is informed in the app that in theory all contacts can see each other in the story room. The user must give consent here. However the user is at any time able to create a group chat and invite all of their contacts to this chat in any matrix client which has the same result.
|
||||
|
|
|
|||
127
README.md
|
|
@ -1,115 +1,48 @@
|
|||

|
||||

|
||||
|
||||
[FluffyChat](https://fluffy.chat) is an open source, nonprofit and cute [[matrix](https://matrix.org)] client written in [Flutter](https://flutter.dev). The goal of the app is to create an easy to use instant messenger which is open source and accessible for everyone.
|
||||
<p align="center">
|
||||
<a href="https://matrix.to/#/#fluffychat:matrix.org" target="new">Join the community</a> - <a href="https://metalhead.club/@krille" target="new">Follow me on Mastodon</a> - <a href="https://hosted.weblate.org/projects/fluffychat/" target="new">Translate FluffyChat</a> - <a href="https://gitlab.com/ChristianPauly/fluffychat-website" target="new">Translate the website</a> - <a href="https://fluffychat.im" target="new">Website</a> - <a href="https://gitlab.com/famedly/famedlysdk" target="new">Famedly Matrix SDK</a> - <a href="https://famedly.com/kontakt">Server hosting and professional support</a>
|
||||
</p>
|
||||
|
||||
### Links:
|
||||
|
||||
- 🌐 [[Weblate] Translate FluffyChat into your language](https://hosted.weblate.org/projects/fluffychat/)
|
||||
- 🌍 [[m] Join the community](https://matrix.to/#/#fluffy-space:matrix.org)
|
||||
- 📰 [[Mastodon] Get updates on social media](https://troet.cafe/@krille)
|
||||
- 🖥️ [[Famedly] Server hosting and professional support](https://famedly.com/kontakt)
|
||||
- 💝 [[Liberapay] Support FluffyChat development](https://de.liberapay.com/KrilleChritzelius)
|
||||
FluffyChat is an open source, nonprofit and cute matrix messenger app. The app is easy to use but secure and decentralized.
|
||||
|
||||
<a href='https://ko-fi.com/C1C86VN53' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi5.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
||||
|
||||
### Screenshots:
|
||||
|
||||
<img src="https://github.com/krille-chan/fluffychat-website/blob/main/src/assets/screenshots/mobile.png?raw=true" height="300">
|
||||
<img src="https://github.com/krille-chan/fluffychat-website/blob/main/src/assets/screenshots/desktop.png?raw=true" height="300">
|
||||
|
||||
# Features
|
||||
|
||||
- 📩 Send all kinds of messages, images and files
|
||||
- 🎙️ Voice messages
|
||||
- 📍 Location sharing
|
||||
- 🔔 Push notifications
|
||||
- 💬 Unlimited private and public group chats
|
||||
- 📣 Public channels with thousands of participants
|
||||
- 🛠️ Feature rich group moderation including all matrix features
|
||||
- 🔍 Discover and join public groups
|
||||
- 🌙 Dark mode
|
||||
- 🎨 Material You design
|
||||
- 📟 Hides complexity of Matrix IDs behind simple QR codes
|
||||
- 😄 Custom emotes and stickers
|
||||
- 🌌 Spaces
|
||||
- 🔄 Compatible with Element, Nheko, NeoChat and all other Matrix apps
|
||||
- 🔐 End to end encryption
|
||||
- 🔒 Encrypted chat backup
|
||||
- 😀 Emoji verification & cross signing
|
||||
|
||||
... and much more.
|
||||
## Features
|
||||
|
||||
- Send all kinds of messages, images and files
|
||||
- Voice messages
|
||||
- Location sharing
|
||||
- Push notifications
|
||||
- Unlimited private and public group chats
|
||||
- Public channels with thousands of participants
|
||||
- Feature rich group moderation including all matrix features
|
||||
- Discover and join public groups
|
||||
- Dark mode
|
||||
- Custom themes
|
||||
- Hides complexity of Matrix IDs behind simple QR codes
|
||||
- Custom emotes and stickers
|
||||
- Spaces
|
||||
- Compatible with Element, Nheko, NeoChat and all other Matrix apps
|
||||
- End to end encryption
|
||||
- Emoji verification & cross signing
|
||||
- And much more...
|
||||
|
||||
# Installation
|
||||
|
||||
Please visit the website for installation instructions:
|
||||
Please visit our website for installation instructions:
|
||||
|
||||
- https://fluffy.chat
|
||||
https://fluffychat.im
|
||||
|
||||
# How to build
|
||||
|
||||
1. To build FluffyChat you need [Flutter](https://flutter.dev) and [Rust](https://www.rust-lang.org/tools/install)
|
||||
Please visit our Wiki for build instructions:
|
||||
|
||||
2. Clone the repo:
|
||||
```
|
||||
git clone https://github.com/krille-chan/fluffychat.git
|
||||
cd fluffychat
|
||||
```
|
||||
3. Choose your target platform below and enable support for it.
|
||||
3.1 If you want, enable Googles Firebase Cloud Messaging:
|
||||
|
||||
`./scripts/add-firebase-messaging.sh`
|
||||
|
||||
4. Debug with: `flutter run`
|
||||
|
||||
### Android
|
||||
|
||||
* Build with: `flutter build apk`
|
||||
|
||||
### iOS / iPadOS
|
||||
|
||||
* Have a Mac with Xcode installed, and set up for Xcode-managed app signing
|
||||
* If you want automatic app installation to connected devices, make sure you have Apple Configurator installed, with the Automation Tools (`cfgutil`) enabled
|
||||
* Set a few environment variables
|
||||
* FLUFFYCHAT_NEW_TEAM: the Apple Developer team that your certificates should live under
|
||||
* FLUFFYCHAT_NEW_GROUP: the group you want App IDs and such to live under (ie: com.example.fluffychat)
|
||||
* FLUFFYCHAT_INSTALL_IPA: set to `1` if you want the IPA to be deployed to connected devices after building, otherwise unset
|
||||
* Run `./scripts/build-ios.sh`
|
||||
|
||||
### Web
|
||||
|
||||
* Build with:
|
||||
```bash
|
||||
./scripts/prepare-web.sh # To install Vodozemac
|
||||
flutter build web --release
|
||||
```
|
||||
|
||||
* Optionally configure by serving a `config.json` at the same path as fluffychat.
|
||||
An example can be found at `config.sample.json`. All values there are optional.
|
||||
**Please only the values, you really need**. If you e.g. only want
|
||||
to change the default homeserver, then only modify the `defaultHomeserver` key.
|
||||
|
||||
### Desktop (Linux, Windows, macOS)
|
||||
|
||||
* Enable Desktop support in Flutter: https://flutter.dev/desktop
|
||||
|
||||
#### Install custom dependencies (Linux)
|
||||
|
||||
```bash
|
||||
sudo apt install libjsoncpp1 libsecret-1-dev libsecret-1-0 librhash0 libwebkit2gtk-4.0-dev lld
|
||||
```
|
||||
|
||||
* Build with one of these:
|
||||
```bash
|
||||
flutter build linux --release
|
||||
flutter build windows --release
|
||||
flutter build macos --release
|
||||
```
|
||||
https://gitlab.com/famedly/fluffychat/-/wikis/How-To-Build
|
||||
|
||||
|
||||
# Special thanks
|
||||
|
||||
* <a href="https://github.com/fabiyamada">Fabiyamada</a> is a graphics designer and has made the fluffychat logo and the banner. Big thanks for her great designs.
|
||||
* <a href="https://github.com/fabiyamada">Fabiyamada</a> is a graphics designer from Brasil and has made the fluffychat logo and the banner. Big thanks for her great designs.
|
||||
|
||||
* <a href="https://github.com/advocatux">Advocatux</a> has made the Spanish translation with great love and care. He always stands by my side and supports my work with great commitment.
|
||||
|
||||
|
|
@ -117,6 +50,8 @@ flutter build macos --release
|
|||
|
||||
* Also thanks to all translators and testers! With your help, fluffychat is now available in more than 12 languages.
|
||||
|
||||
* <a href="https://github.com/googlefonts/noto-emoji/">Noto Emoji Font</a> for the awesome emojis.
|
||||
|
||||
* <a href="https://github.com/madsrh/WoodenBeaver">WoodenBeaver</a> sound theme for the notification sound.
|
||||
|
||||
* The Matrix Foundation for making and maintaining the [emoji translations](https://github.com/matrix-org/matrix-spec/blob/main/data-definitions/sas-emoji.json) used for emoji verification, licensed Apache 2.0
|
||||
* The Matrix Foundation for making and maintaining the [emoji translations](https://github.com/matrix-org/matrix-doc/blob/main/data-definitions/sas-emoji.json) used for emoji verification, licensed Apache 2.0
|
||||
|
|
|
|||
15
SECURITY.md
|
|
@ -1,15 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
If you believe you have discovered a security vulnerability in this project, **do not open a public issue**.
|
||||
|
||||
To report a security issue responsibly, please go to the Security tab or visit:
|
||||
|
||||
https://github.com/krille-chan/fluffychat/security/advisories/new
|
||||
|
||||
The following information can help us address the issue:
|
||||
|
||||
- Clear steps to reproduce the vulnerability
|
||||
- The software version you are using
|
||||
- The affected platforms
|
||||
|
||||
We appreciate your report and will respond as quickly as possible. Please note that this project is maintained by volunteers and is provided without guarantees.
|
||||
35
TRANSLATORS_GUIDE.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Translators Guide
|
||||
|
||||
There are 3 main types of strings to be translated.
|
||||
|
||||
## Simple
|
||||
```
|
||||
Add new friend
|
||||
```
|
||||
They are just plain text and are to be translated in full.
|
||||
|
||||
## Placeholder
|
||||
```
|
||||
{username} changed their avatar
|
||||
```
|
||||
Contains one or more words surrounded by curly brackets "`{}`". Anything outside of the curly brackets is to be translated as normal, but the words in the curly brackets are **NOT** to be translated. In the above example "`{username}`" will be replaced by the users actual username by FluffyChat.
|
||||
|
||||
## Plural
|
||||
|
||||
- {count,plural, =1{**1 more event**} other{{count} **more events**}}
|
||||
|
||||
This is the most complicated string type, the parts in bold are the only parts that need translating in this string. You can identify plural strings by seeing the pattern `{word,plural,` at the start. `=1` and `other` are "selectors" so you can have multiple different translations for different quantities. `other` is the only required selector and will be chosen if the count does not match any other selectors.
|
||||
|
||||
Selector | Matches
|
||||
---|---
|
||||
=0 | a count of exactly 0
|
||||
=1 | a count of exactly 1
|
||||
=2 | a count of exactly 2
|
||||
other | any number unless it matches a more specific rule
|
||||
|
||||
There is also "few" and "many", but they seem to have language specific meaning.
|
||||
|
||||
Also the selectors do not need to match the English version such as your language may not even use different words for when there is more than one of something so:
|
||||
- {count,plural, other{{count} \<insert translation here\>}}
|
||||
|
||||
could be a perfectly resonable way to translate.
|
||||
|
|
@ -2,75 +2,51 @@ include: package:flutter_lints/flutter.yaml
|
|||
|
||||
linter:
|
||||
rules:
|
||||
- camel_case_types
|
||||
- avoid_print
|
||||
- constant_identifier_names
|
||||
- prefer_final_locals
|
||||
- prefer_final_in_for_each
|
||||
- sort_pub_dependencies
|
||||
- require_trailing_commas
|
||||
- omit_local_variable_types
|
||||
- cancel_subscriptions
|
||||
- always_declare_return_types
|
||||
- avoid_void_async
|
||||
- no_adjacent_strings_in_list
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- unnecessary_statements
|
||||
- avoid_bool_literals_in_conditional_expressions
|
||||
- prefer_single_quotes
|
||||
- prefer_const_declarations
|
||||
- unnecessary_lambdas
|
||||
- combinators_ordering
|
||||
- noop_primitive_operations
|
||||
- unnecessary_null_checks
|
||||
- unnecessary_null_in_if_null_operators
|
||||
- unnecessary_to_list_in_spreads
|
||||
- use_is_even_rather_than_modulo
|
||||
- use_super_parameters
|
||||
# Flutter specific:
|
||||
- use_colored_box
|
||||
|
||||
analyzer:
|
||||
plugins:
|
||||
- dart_code_linter
|
||||
errors:
|
||||
todo: ignore
|
||||
use_build_context_synchronously: ignore
|
||||
import_of_legacy_library_into_null_safe: ignore
|
||||
exclude:
|
||||
- lib/generated_plugin_registrant.dart
|
||||
- lib/l10n/*.dart
|
||||
|
||||
dart_code_linter:
|
||||
dart_code_metrics:
|
||||
metrics:
|
||||
cyclomatic-complexity: 20
|
||||
number-of-arguments: 4
|
||||
maximum-nesting-level: 5
|
||||
source-lines-of-code: 50
|
||||
maintainability-index: 40
|
||||
rules:
|
||||
# Dart specific:
|
||||
- avoid-dynamic
|
||||
- avoid-redundant-async
|
||||
- avoid-unnecessary-type-assertions
|
||||
- avoid-unnecessary-type-casts
|
||||
- avoid-unrelated-type-assertions
|
||||
- no-boolean-literal-compare
|
||||
- no-empty-block
|
||||
- prefer-conditional-expressions
|
||||
- no-equal-then-else
|
||||
- prefer-first
|
||||
- prefer-last
|
||||
- prefer-immediate-return
|
||||
- prefer-enums-by-name
|
||||
- avoid-unnecessary-conditionals
|
||||
# TODO:
|
||||
# - member-ordering
|
||||
# - avoid-global-state
|
||||
# - prefer-match-file-name
|
||||
# - avoid-banned-imports:
|
||||
# entries:
|
||||
# - paths: ['some/folder/.*\.dart', 'another/folder/.*\.dart']
|
||||
# deny: ['package:flutter/material.dart']
|
||||
# message: 'Do not import Flutter Material Design library, we should not depend on it!'
|
||||
# - no-magic-number:
|
||||
# allowed: [-1, 0, 1,2,4,6,8,12,16,32,40,56,64]
|
||||
# allow-only-once: true
|
||||
# Flutter specific:
|
||||
- prefer-media-query-direct-access
|
||||
- no-magic-number:
|
||||
severity: style
|
||||
- avoid-late-keyword:
|
||||
severity: style
|
||||
- avoid-non-null-assertion:
|
||||
severity: style
|
||||
- avoid-unused-parameters
|
||||
- binary-expression-operand-order
|
||||
- avoid-unnecessary-setstate
|
||||
- avoid-wrapping-in-padding
|
||||
- prefer-correct-edge-insets-constructor
|
||||
- avoid-returning-widgets
|
||||
# TODO:
|
||||
# - prefer-single-widget-per-file:
|
||||
# ignore-private-widgets: true
|
||||
# - prefer-extracting-callbacks
|
||||
- prefer-const-border-radius
|
||||
- prefer-single-widget-per-file:
|
||||
ignore-private-widgets: true
|
||||
- prefer-extracting-callbacks
|
||||
metrics-exclude:
|
||||
- test/**
|
||||
rules-exclude:
|
||||
- test/**
|
||||
anti-patterns:
|
||||
- long-method
|
||||
- long-parameter-list
|
||||
|
|
|
|||
6
android/.gitignore
vendored
|
|
@ -5,9 +5,3 @@ gradle-wrapper.jar
|
|||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
|
|
|
|||
86
android/app/build.gradle
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 32
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "chat.fluffy.fluffychat"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
implementation('com.github.UnifiedPush:android-foss_embedded_fcm_distributor:1.0.0-beta1')
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
import java.util.Properties
|
||||
import java.io.FileInputStream
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("kotlin-android")
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
}
|
||||
|
||||
if (file("google-services.json").exists()) {
|
||||
apply(plugin = "com.google.gms.google-services")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") // For flutter_local_notifications // Workaround for: https://github.com/MaikuB/flutter_local_notifications/issues/2286
|
||||
implementation("androidx.core:core-ktx:1.17.0") // For Android Auto
|
||||
}
|
||||
|
||||
|
||||
// Workaround for https://pub.dev/packages/unifiedpush#the-build-fails-because-of-duplicate-classes
|
||||
configurations.all {
|
||||
// Use the latest version published: https://central.sonatype.com/artifact/com.google.crypto.tink/tink-android
|
||||
val tink = "com.google.crypto.tink:tink-android:1.17.0"
|
||||
// You can also use the library declaration catalog
|
||||
// val tink = libs.google.tink
|
||||
resolutionStrategy {
|
||||
force(tink)
|
||||
dependencySubstitution {
|
||||
substitute(module("com.google.crypto.tink:tink")).using(module(tink))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
namespace = "chat.fluffy.fluffychat"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
keyAlias = "dummyAlias"
|
||||
keyPassword = "dummyPassword"
|
||||
storeFile = file("dummy.keystore")
|
||||
storePassword = "dummyStorePassword"
|
||||
}
|
||||
}
|
||||
|
||||
val keystoreProperties = Properties()
|
||||
val keystorePropertiesFile = rootProject.file("key.properties")
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
|
||||
signingConfigs.getByName("release").apply {
|
||||
keyAlias = keystoreProperties["keyAlias"] as String
|
||||
keyPassword = keystoreProperties["keyPassword"] as String
|
||||
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
|
||||
storePassword = keystoreProperties["storePassword"] as String
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "chat.fluffy.fluffychat"
|
||||
minSdk = flutter.minSdkVersion
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
ndk { // Workaround for https://github.com/flutter/flutter/issues/162153#issuecomment-2612443642
|
||||
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86_64", "x86")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
46
android/app/google-services.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"project_info": {
|
||||
"project_number": "865731724731",
|
||||
"project_id": "fluffychat-ef3e8",
|
||||
"storage_bucket": "fluffychat-ef3e8.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:865731724731:android:ec427b3b1dcd4a1e64309e",
|
||||
"android_client_info": {
|
||||
"package_name": "chat.fluffy.fluffychat"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "865731724731-od6969v178ul9970elgacpt936v5t7qg.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBLdZpGSPjcinikB4lAU6awW_h88NG17Sg"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "865731724731-od6969v178ul9970elgacpt936v5t7qg.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "865731724731-ofdr7e6m04murgb1bvchlj9oaos0q5i3.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "im.fluffychat.app"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
1
android/app/proguard-rules.pro
vendored
|
|
@ -1 +0,0 @@
|
|||
-keep class net.sqlcipher.** { *; }
|
||||
7
android/app/src/debug/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="chat.fluffy.fluffychat">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:installLocation="auto">
|
||||
package="chat.fluffy.fluffychat" android:installLocation="auto">
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
|
|
@ -14,23 +14,25 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<!-- To make app compatible with tablets -->
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="false" />
|
||||
<uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
|
||||
<uses-sdk
|
||||
tools:overrideLibrary="io.wazo.callkeep, net.touchcapture.qr.flutterqr, com.cloudwebrtc.webrtc, org.webrtc, com.it_nomads.fluttersecurestorage, com.pichillilorenzo.flutter_inappwebview, com.example.video_compress, com.otaliastudios.transcoder, com.otaliastudios.opengl, com.kineapps.flutter_file_dialog, com.llfbandit.record, com.pravera.flutter_foreground_task"/>
|
||||
tools:overrideLibrary="io.wazo.callkeep, net.touchcapture.qr.flutterqr, com.cloudwebrtc.webrtc, org.webrtc, com.it_nomads.fluttersecurestorage, com.pichillilorenzo.flutter_inappwebview, com.example.video_compress, com.otaliastudios.transcoder, com.otaliastudios.opengl, com.kineapps.flutter_file_dialog, com.llfbandit.record"/>
|
||||
|
||||
<application
|
||||
android:label="FluffyChat"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:allowBackup="false"
|
||||
android:fullBackupContent="false"
|
||||
android:localeConfig="@xml/locale_config"
|
||||
>
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
|
@ -38,22 +40,16 @@
|
|||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:showOnLockScreen="false"
|
||||
android:turnScreenOn="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
||||
<!-- App can open on notification action -->
|
||||
<intent-filter>
|
||||
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- App can open https://matrix.to urls -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
|
@ -62,51 +58,47 @@
|
|||
android:scheme="https"
|
||||
android:host="matrix.to"/>
|
||||
</intent-filter>
|
||||
|
||||
<!-- App can open matrix: uris -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="matrix" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- App can open im.fluffychat:// uris -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="im.fluffychat" android:host="chat" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- App can receive shared text -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/*" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- App can receive shared any type of files -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:mimeType="document/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="*/*" />
|
||||
<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>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
|
||||
android:exported="true">
|
||||
<activity android:name="com.linusu.flutter_web_auth.CallbackActivity"
|
||||
android:exported="true">
|
||||
<intent-filter android:label="flutter_web_auth">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="im.fluffychat" android:path="/login"/>
|
||||
<data android:scheme="im.fluffychat" android:host="login"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
|
@ -117,18 +109,26 @@
|
|||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
|
||||
android:foregroundServiceType="camera|microphone|mediaProjection">
|
||||
</service>
|
||||
|
||||
<!-- From flutter_local_notifications package for notification actions -->
|
||||
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" />
|
||||
|
||||
<!-- To make notifications available in Android Auto -->
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.car.application"
|
||||
android:resource="@xml/automotive_app_desc"/>
|
||||
<receiver android:name="org.unifiedpush.flutter.connector.UnifiedPushReceiver"
|
||||
tools:replace="android:enabled"
|
||||
android:enabled="false">
|
||||
</receiver>
|
||||
|
||||
<receiver android:exported="false" android:enabled="true" android:name=".UnifiedPushReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.flutter.connector.MESSAGE"/>
|
||||
<action android:name="org.unifiedpush.flutter.connector.UNREGISTERED"/>
|
||||
<action android:name="org.unifiedpush.flutter.connector.NEW_ENDPOINT"/>
|
||||
<action android:name="org.unifiedpush.flutter.connector.REGISTRATION_FAILED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:enabled="true" android:name=".EmbeddedDistributor" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.android.distributor.feature.BYTES_MESSAGE"/>
|
||||
<action android:name="org.unifiedpush.android.distributor.REGISTER"/>
|
||||
<action android:name="org.unifiedpush.android.distributor.UNREGISTER"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package chat.fluffy.fluffychat
|
||||
|
||||
import android.content.Context
|
||||
import org.unifiedpush.android.foss_embedded_fcm_distributor.EmbeddedDistributorReceiver
|
||||
|
||||
class EmbeddedDistributor: EmbeddedDistributorReceiver() {
|
||||
|
||||
override val googleProjectNumber = "865731724731" // This value comes from the google-services.json
|
||||
|
||||
override fun getEndpoint(context: Context, token: String, instance: String): String {
|
||||
// This returns the endpoint of your FCM Rewrite-Proxy
|
||||
return "https://push.fluffychat.im/_matrix/push/v1/notify?token=$token"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/*package chat.fluffy.fluffychat
|
||||
|
||||
import com.famedly.fcm_shared_isolate.FcmSharedIsolateService
|
||||
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint
|
||||
import android.content.Context
|
||||
|
||||
class FcmPushService : FcmSharedIsolateService() {
|
||||
override fun getEngine(): FlutterEngine {
|
||||
return provideEngine(getApplicationContext())
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun provideEngine(context: Context): FlutterEngine {
|
||||
var engine = MainActivity.engine
|
||||
if (engine == null) {
|
||||
engine = MainActivity.provideEngine(context)
|
||||
engine.getLocalizationPlugin().sendLocalesToFlutter(
|
||||
context.getResources().getConfiguration())
|
||||
engine.getDartExecutor().executeDartEntrypoint(
|
||||
DartEntrypoint.createDefault())
|
||||
}
|
||||
return engine
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -4,11 +4,13 @@ import io.flutter.embedding.android.FlutterActivity
|
|||
import io.flutter.embedding.engine.FlutterEngine
|
||||
|
||||
import android.content.Context
|
||||
import androidx.multidex.MultiDex
|
||||
|
||||
class MainActivity : FlutterActivity() {
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base)
|
||||
MultiDex.install(this)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package chat.fluffy.fluffychat
|
||||
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.embedding.engine.dart.DartExecutor
|
||||
import org.unifiedpush.flutter.connector.UnifiedPushReceiver
|
||||
|
||||
import android.content.Context
|
||||
|
||||
class UnifiedPushReceiver : UnifiedPushReceiver() {
|
||||
override fun getEngine(context: Context): FlutterEngine {
|
||||
var engine = MainActivity.engine
|
||||
if (engine == null) {
|
||||
engine = MainActivity.provideEngine(context)
|
||||
engine.localizationPlugin.sendLocalesToFlutter(
|
||||
context.resources.configuration
|
||||
)
|
||||
engine.dartExecutor.executeDartEntrypoint(
|
||||
DartExecutor.DartEntrypoint.createDefault()
|
||||
)
|
||||
}
|
||||
return engine
|
||||
}
|
||||
}
|
||||
|
|
@ -2,5 +2,5 @@
|
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_monochrome"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<automotiveApp>
|
||||
<uses name="notification" />
|
||||
</automotiveApp>
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<locale android:name="ar"/>
|
||||
<locale android:name="be"/>
|
||||
<locale android:name="bn"/>
|
||||
<locale android:name="bo"/>
|
||||
<locale android:name="ca"/>
|
||||
<locale android:name="cs"/>
|
||||
<locale android:name="da"/>
|
||||
<locale android:name="de"/>
|
||||
<locale android:name="el"/>
|
||||
<locale android:name="en"/>
|
||||
<locale android:name="eo"/>
|
||||
<locale android:name="es"/>
|
||||
<locale android:name="et"/>
|
||||
<locale android:name="eu"/>
|
||||
<locale android:name="fa"/>
|
||||
<locale android:name="fi"/>
|
||||
<locale android:name="fil"/>
|
||||
<locale android:name="fr"/>
|
||||
<locale android:name="ga"/>
|
||||
<locale android:name="gl"/>
|
||||
<locale android:name="he"/>
|
||||
<locale android:name="hi"/>
|
||||
<locale android:name="hr"/>
|
||||
<locale android:name="hu"/>
|
||||
<locale android:name="ia"/>
|
||||
<locale android:name="id"/>
|
||||
<locale android:name="ie"/>
|
||||
<locale android:name="it"/>
|
||||
<locale android:name="ja"/>
|
||||
<locale android:name="ka"/>
|
||||
<locale android:name="kab"/>
|
||||
<locale android:name="ko"/>
|
||||
<locale android:name="lt"/>
|
||||
<locale android:name="lv"/>
|
||||
<locale android:name="nb"/>
|
||||
<locale android:name="nl"/>
|
||||
<locale android:name="pl"/>
|
||||
<locale android:name="pt"/>
|
||||
<locale android:name="pt"/>
|
||||
<locale android:name="pt"/>
|
||||
<locale android:name="ro"/>
|
||||
<locale android:name="ru"/>
|
||||
<locale android:name="sk"/>
|
||||
<locale android:name="sl"/>
|
||||
<locale android:name="sq"/>
|
||||
<locale android:name="sr"/>
|
||||
<locale android:name="sv"/>
|
||||
<locale android:name="ta"/>
|
||||
<locale android:name="te"/>
|
||||
<locale android:name="th"/>
|
||||
<locale android:name="tr"/>
|
||||
<locale android:name="uk"/>
|
||||
<locale android:name="uz"/>
|
||||
<locale android:name="vi"/>
|
||||
<locale android:name="yue"/>
|
||||
<locale android:name="zh"/>
|
||||
<locale android:name="zh"/>
|
||||
</locale-config>
|
||||
7
android/app/src/profile/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="chat.fluffy.fluffychat">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
31
android/build.gradle
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.6.10'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
|
||||
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||
|
||||
subprojects {
|
||||
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
||||
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(":app")
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
|
|
@ -10,9 +10,6 @@
|
|||
# https://docs.fastlane.tools/plugins/available-plugins
|
||||
#
|
||||
|
||||
# Workaround for https://github.com/fastlane/fastlane/issues/21507#issuecomment-1723116829
|
||||
ENV['SUPPLY_UPLOAD_MAX_RETRIES']='5'
|
||||
|
||||
# Uncomment the line if you want fastlane to automatically update itself
|
||||
update_fastlane
|
||||
|
||||
|
|
@ -44,28 +41,14 @@ platform :android do
|
|||
json_key: "./keys.json"
|
||||
)
|
||||
last_version = versions[0].to_i
|
||||
upload_to_play_store(
|
||||
track: 'internal',
|
||||
aab: '../build/app/outputs/bundle/release/app-release.aab',
|
||||
version_code: "#{last_version+1}",
|
||||
)
|
||||
upload_to_play_store(track: 'internal', aab: '../build/app/outputs/bundle/release/app-release.aab', version_code: "#{last_version+1}")
|
||||
end
|
||||
|
||||
lane :deploy_candidate do
|
||||
upload_to_play_store(
|
||||
track: 'internal',
|
||||
track_promote_to: "beta",
|
||||
deactivate_on_promote: false,
|
||||
skip_upload_changelogs: true,
|
||||
)
|
||||
upload_to_play_store(track: 'internal', track_promote_to: "beta", deactivate_on_promote: false, skip_upload_changelogs: true)
|
||||
end
|
||||
|
||||
lane :deploy_release do
|
||||
upload_to_play_store(
|
||||
track: 'internal',
|
||||
track_promote_to: "production",
|
||||
deactivate_on_promote: false,
|
||||
skip_upload_changelogs: true,
|
||||
)
|
||||
upload_to_play_store(track: 'beta', track_promote_to: "production", deactivate_on_promote: false, skip_upload_changelogs: true)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,56 +1,39 @@
|
|||
fastlane documentation
|
||||
----
|
||||
|
||||
================
|
||||
# Installation
|
||||
|
||||
Make sure you have the latest version of the Xcode command line tools installed:
|
||||
|
||||
```sh
|
||||
```
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||
Install _fastlane_ using
|
||||
```
|
||||
[sudo] gem install fastlane -NV
|
||||
```
|
||||
or alternatively using `brew install fastlane`
|
||||
|
||||
# Available Actions
|
||||
|
||||
## Android
|
||||
|
||||
### android set_build_code_internal
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android set_build_code_internal
|
||||
```
|
||||
|
||||
|
||||
fastlane android set_build_code_internal
|
||||
```
|
||||
|
||||
### android deploy_internal_test
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deploy_internal_test
|
||||
```
|
||||
|
||||
|
||||
|
||||
### android deploy_candidate
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deploy_candidate
|
||||
fastlane android deploy_internal_test
|
||||
```
|
||||
|
||||
|
||||
|
||||
### android deploy_release
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deploy_release
|
||||
```
|
||||
|
||||
fastlane android deploy_release
|
||||
```
|
||||
|
||||
|
||||
----
|
||||
|
||||
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||
|
||||
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||
|
||||
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
||||
More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
|
||||
The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Check out https://gitlab.com/ChristianPauly/fluffychat-flutter/-/blob/main/CHANGELOG.md for the changelog.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
FluffyChat 2.5.0 introduces a new homeserver picker for onboarding,
|
||||
better image compression performance and several smaller new features,
|
||||
design adjustments and bug fixes.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
FluffyChat is an open, nonprofit and cute Matrix messenger app for Ubuntu Touch, Android and iOS.
|
||||
FluffyChat is an open, nonprofit and cute matrix messenger app for Ubuntu Touch, Android and iOS.
|
||||
|
||||
Open
|
||||
Opensource and open development where everyone can join.
|
||||
|
|
@ -9,7 +9,7 @@ FluffyChat is donation funded.
|
|||
Cute ♥
|
||||
Cute design and many theme settings including a dark mode.
|
||||
|
||||
One-to-one and group chats
|
||||
One-to-one and groupchats
|
||||
Unlimited groups and direct chats.
|
||||
|
||||
Easy
|
||||
|
|
@ -22,11 +22,11 @@ Decentralized
|
|||
There is no "FluffyChat server" you are forced to use. Use the server you find trustworthy or host your own.
|
||||
|
||||
Compatible
|
||||
Compatible with Element, Fractal, Nheko and all Matrix messengers.
|
||||
Compatible with Riot, Fractal, Nekho and all matrix messengers.
|
||||
|
||||
|
||||
FluffyChat comes with a dream
|
||||
|
||||
Imagine a world where everyone can choose the messenger they like and is still able to chat with all of their friends.
|
||||
A world where there are no companies spying on you when you send selfies to friends and your loved.
|
||||
And a world where apps are made for fluffyness and not for profit. ♥
|
||||
A world where there are no companies spying on you when you send selfies to friends and lovers.
|
||||
And a world where apps are made for fluffyness and not for profit. ♥
|
||||
|
|
@ -5,17 +5,17 @@
|
|||
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="0: update_fastlane" time="1.455419">
|
||||
<testcase classname="fastlane.lanes" name="0: update_fastlane" time="0.000489805">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="1: default_platform" time="0.000127">
|
||||
<testcase classname="fastlane.lanes" name="1: default_platform" time="0.000295551">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="2: google_play_track_version_codes" time="2.638619">
|
||||
<testcase classname="fastlane.lanes" name="2: google_play_track_version_codes" time="1.551277547">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
org.gradle.jvmargs=-Xmx4608m
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
kotlin.jvm.target.validation.mode=IGNORE
|
||||
android.enableR8.fullMode=true
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#Mon Mar 17 08:36:03 CET 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
|
||||
|
|
|
|||
15
android/settings.gradle
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
include ':app'
|
||||
|
||||
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
|
||||
|
||||
def plugins = new Properties()
|
||||
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
|
||||
if (pluginsFile.exists()) {
|
||||
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
|
||||
}
|
||||
|
||||
plugins.each { name, path ->
|
||||
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
|
||||
include ":$name"
|
||||
project(":$name").projectDir = pluginDirectory
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
pluginManagement {
|
||||
val flutterSdkPath = run {
|
||||
val properties = java.util.Properties()
|
||||
file("local.properties").inputStream().use { properties.load(it) }
|
||||
val flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
|
||||
flutterSdkPath
|
||||
}
|
||||
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "8.9.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
||||
if (file("app/google-services.json").exists()) {
|
||||
id("com.google.gms.google-services") version "4.3.8" apply false
|
||||
}
|
||||
}
|
||||
|
||||
include(":app")
|
||||
1
android/settings_aar.gradle
Normal file
|
|
@ -0,0 +1 @@
|
|||
include ':app'
|
||||
3
appimage/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
FluffyChat.AppDir
|
||||
*.AppImage
|
||||
*.AppImage.zsync
|
||||
4
appimage/AppRun
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
exec ./fluffychat
|
||||
9
appimage/FluffyChat.desktop
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=FluffyChat
|
||||
Comment=Matrix Client. Chat with your friends
|
||||
Exec=AppRun
|
||||
Icon=fluffychat
|
||||
Terminal=false
|
||||
Categories=Network;Chat;InstantMessaging;X-Matrix;
|
||||
24
appimage/README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# FluffyChat AppImage
|
||||
|
||||
FluffyChat is provided as AppImage too. To Download, visit fluffychat.im.
|
||||
|
||||
## Building
|
||||
|
||||
- Ensure you install `appimagetool`
|
||||
|
||||
```shell
|
||||
flutter build linux
|
||||
|
||||
# copy binaries to appimage dir
|
||||
cp -r build/linux/{x64,arm64}/release/bundle appimage/FluffyChat.AppDir
|
||||
cd appimage
|
||||
|
||||
# prepare AppImage files
|
||||
cp FluffyChat.desktop FluffyChat.AppDir/
|
||||
mkdir -p FluffyChat.AppDir/usr/share/icons
|
||||
cp ../assets/logo.svg FluffyChat.AppDir/fluffychat.svg
|
||||
cp AppRun FluffyChat.AppDir
|
||||
|
||||
# build the AppImage
|
||||
appimagetool FluffyChat.AppDir
|
||||
```
|
||||
BIN
assets/backup.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
assets/banner_dark.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 82 KiB |
185
assets/chat.svg
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="210mm" height="297mm" viewBox="0 0 210 297" version="1.1" id="svg8" inkscape:version="0.92.3 (d244b95, 2018-08-02)" sodipodi:docname="1.svg">
|
||||
<defs id="defs2"/>
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.5" inkscape:cx="675" inkscape:cy="548.18772" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="640" inkscape:window-height="748" inkscape:window-x="640" inkscape:window-y="24" inkscape:window-maximized="0"/>
|
||||
<metadata id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1">
|
||||
<g id="g3735" transform="matrix(1.3863783,0,0,1.3863783,53.572287,59.067903)">
|
||||
<path id="path3715" d="m 12.7,30.7 c 4,5.3 1.9,-0.3 7.3,-0.3 5.4,0 8,-5.1 7.9,-10.4 C 27.8,14.7 16.2,7.7 11.1,9.4 c -3.2,1.2 -1.6,17 1.6,21.3 z" class="st0" inkscape:connector-curvature="0" style="fill:#878787"/>
|
||||
|
||||
<path id="path3717" d="m 14.6,25.1 c 2.3,3 9.3,-1.9 9.3,-5 0,-3.1 -6.7,-7.1 -9.6,-6 -1.9,0.6 -1.6,8.5 0.3,11 z" class="st1" inkscape:connector-curvature="0" style="fill:#ffffff"/>
|
||||
|
||||
<path id="path3719" d="m 61,30.6 c -3.9,5.3 -1.9,-0.2 -7.3,-0.2 -5.4,0 -8,-5 -8,-10.4 0,-5.4 11.7,-12.4 16.7,-10.7 3.3,1.1 1.8,17 -1.4,21.3 z" class="st0" inkscape:connector-curvature="0" style="fill:#878787"/>
|
||||
|
||||
<path id="path3721" d="m 59.1,25 c -2.3,3.1 -9.3,-1.8 -9.3,-4.9 0,-3.1 6.7,-7.1 9.6,-6.1 1.8,0.6 1.5,8.5 -0.3,11 z" class="st1" inkscape:connector-curvature="0" style="fill:#ffffff"/>
|
||||
|
||||
<g id="g3725">
|
||||
<path id="path3723" d="m 30.7,60.8 c 0.2,2.1 2.6,3.6 4.9,2.1 0.5,-0.3 0.8,-0.9 0.9,-1.4 0.1,-0.3 0.4,-0.6 0.8,-0.6 0.4,0 0.7,0.2 0.8,0.6 0.1,0.5 0.3,0.9 0.7,1.2 2.3,1.8 4.9,0.3 5.1,-1.9 0,-0.3 0.2,-0.6 0.5,-0.7 0.3,-0.1 0.6,0 0.8,0.2 0.6,0.6 1.3,1 2.1,1 0,0 0,0 0,0 1,0 2,-0.5 2.6,-1.5 0.4,-0.6 0.5,-1.2 0.4,-2 0,-0.3 0.1,-0.6 0.3,-0.8 0.2,-0.2 0.6,-0.2 0.8,0 0.6,0.3 1.3,0.5 2,0.3 1.1,-0.2 2,-1.1 2.3,-2.1 0.2,-0.7 0.1,-1.4 -0.2,-2.1 -0.1,-0.3 -0.1,-0.6 0.1,-0.8 0.2,-0.2 0.5,-0.3 0.8,-0.3 0.7,0.1 1.3,0.1 1.9,-0.2 0.9,-0.4 1.5,-1.2 1.7,-2.2 0.2,-1 -0.1,-1.9 -0.8,-2.6 -0.2,-0.2 -0.3,-0.5 -0.2,-0.8 0.1,-0.3 0.4,-0.5 0.7,-0.5 0.7,0 1.5,-0.2 2,-0.8 1.7,-1.8 0.9,-4.2 -1,-5 -0.3,-0.1 -0.5,-0.4 -0.5,-0.8 0,-0.3 0.3,-0.6 0.6,-0.7 0.6,-0.1 1.1,-0.4 1.5,-0.8 1.6,-2.1 0.3,-4.7 -1.8,-5 -0.3,0 -0.6,-0.3 -0.6,-0.6 -0.1,-0.3 0,-0.6 0.3,-0.8 0.8,-0.6 1.2,-1.4 1.2,-2.3 0,-0.3 -0.1,-0.7 -0.3,-1 -1.3,-2 -2.1,-2.2 -3,-2.1 -0.3,0 -0.6,-0.1 -0.7,-0.4 -0.2,-0.3 -0.1,-0.6 0,-0.8 0.3,-0.5 0.5,-1 0.5,-1.6 0,-0.7 -0.2,-1.4 -0.6,-1.9 -0.6,-0.7 -1.4,-1.1 -2.3,-1.2 -0.4,0 -0.8,0.1 -1.2,0.2 -0.3,0.1 -0.6,0.1 -0.8,-0.2 -0.2,-0.2 -0.3,-0.5 -0.2,-0.8 0.2,-0.6 0.2,-1.2 0,-1.8 -0.4,-1.1 -1.3,-1.9 -2.5,-2.1 -0.8,-0.1 -1.6,0.1 -2.3,0.7 -0.2,0.2 -0.6,0.2 -0.8,0.1 -0.3,-0.1 -0.4,-0.4 -0.4,-0.7 0.1,-1.2 -0.5,-2.2 -1.4,-2.7 -1.8,-0.9 -3.5,0 -4.2,1.3 -0.2,0.3 -0.5,0.5 -0.8,0.4 -0.3,0 -0.6,-0.3 -0.6,-0.6 -0.2,-1 -0.8,-1.8 -1.7,-2.2 -1.9,-0.8 -3.9,0.3 -4.2,2.1 -0.1,0.3 -0.3,0.6 -0.6,0.6 C 33,14.3 32.7,14.1 32.5,13.8 32,13.1 31,12.5 30,12.5 c -1.6,0 -3,1.3 -3.1,2.9 0,0 0,0.1 0,0.1 v 0.1 c 0,0.3 -0.2,0.6 -0.4,0.7 -0.3,0.1 -0.6,0.1 -0.8,-0.1 -0.6,-0.5 -1.4,-0.7 -2.3,-0.6 -1.1,0.1 -2.1,1 -2.4,2.1 -0.2,0.6 -0.2,1.2 0,1.8 0.1,0.3 0,0.6 -0.2,0.8 -0.2,0.2 -0.5,0.3 -0.8,0.2 -0.6,-0.2 -1.2,-0.3 -1.8,-0.1 -1.1,0.3 -2,1.2 -2.2,2.3 -0.2,0.8 0,1.6 0.5,2.3 0.2,0.2 0.2,0.6 0,0.8 -0.2,0.3 -0.4,0.4 -0.7,0.4 h -0.1 c 0,0 -0.1,0 -0.1,0 -1.6,0 -3,1.3 -3.1,2.9 0,1 0.5,2 1.3,2.6 0.3,0.2 0.4,0.5 0.3,0.8 -0.1,0.3 -0.4,0.6 -0.7,0.6 -0.5,0 -1,0.2 -1.4,0.5 -2.1,2 -0.9,4.8 1.2,5.3 0.3,0.1 0.6,0.4 0.6,0.7 0,0.3 -0.2,0.7 -0.5,0.8 -0.4,0.2 -0.8,0.4 -1.1,0.8 -1.6,2.3 0,4.9 2.2,4.9 0.3,0 0.6,0.2 0.7,0.5 0.1,0.3 0.1,0.6 -0.2,0.8 -0.6,0.6 -0.9,1.4 -0.8,2.2 0.1,1.1 0.8,2.1 1.9,2.6 0.6,0.3 1.2,0.3 1.8,0.2 0.3,-0.1 0.6,0 0.8,0.3 0.2,0.2 0.2,0.6 0.1,0.8 -0.3,0.6 -0.4,1.3 -0.2,2 0.3,1.1 1.1,1.9 2.2,2.2 1,0.2 1.7,-0.1 2.2,-0.3 0.2,-0.1 -1.3,3.6 -2.4,6.1 -0.3,0.8 0.5,1.7 1.4,1.3 3.2,-1.7 8.8,-4.2 8.8,-4 z" class="st0" inkscape:connector-curvature="0" style="fill:#878787"/>
|
||||
|
||||
</g>
|
||||
|
||||
<g id="g3733">
|
||||
<circle id="circle3727" r="3.7" cy="38.299999" cx="24.9" class="st1" style="fill:#ffffff"/>
|
||||
|
||||
<path id="path3729" d="m 40.7,38.3 c 0,2.1 -1.7,3.7 -3.7,3.7 -2.1,0 -3.7,-1.7 -3.7,-3.7 0,-2 7.4,-2.1 7.4,0 z" class="st1" inkscape:connector-curvature="0" style="fill:#ffffff"/>
|
||||
|
||||
<circle id="circle3731" r="3.7" cy="38.299999" cx="49" class="st1" style="fill:#ffffff"/>
|
||||
|
||||
</g>
|
||||
|
||||
</g>
|
||||
<g transform="matrix(0.20394939,0,0,0.20394939,53.147489,17.386415)" id="layer1-3">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.14331597,0,0,0.14331597,115.93632,6.4245667)" id="layer1-7" inkscape:label="Layer 1">
|
||||
<g style="display:inline" id="g4845-5" transform="matrix(0,-1,-1,0,373.50506,516.50504)">
|
||||
<g inkscape:label="Layer 1" id="g4778-3" transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)" inkscape:export-filename="next01.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
|
||||
<g style="display:inline" id="g4780-5" transform="matrix(-1,0,0,1,575.99999,611)">
|
||||
<rect transform="scale(-1,1)" y="345.36221" x="-438.00244" height="96" width="96.037987" id="rect4782-6" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"/>
|
||||
<path inkscape:connector-curvature="0" id="path4170" d="m 429.99929,393.33773 c 0,0.004 -9.5e-4,0.007 -0.007,0.009 -0.001,0.007 -0.006,0.007 -0.009,0.009 -0.003,0.006 -0.008,0.008 -0.011,0.009 -0.003,0.006 -0.003,0.006 -0.007,0.009 -10.86428,5.06033 -21.9364,8.97057 -28.72087,11.19382 -0.006,7.31383 -0.28348,19.36 -1.77427,30.84126 -0.004,10e-4 -0.006,0.002 -0.009,-0.002 -0.007,10e-4 -0.01,-0.004 -0.0129,-0.007 -0.007,-10e-4 -0.009,-0.004 -0.011,-0.007 -0.007,-10e-4 -0.006,-0.002 -0.009,-0.004 -8.17196,-8.76466 -15.31373,-18.08322 -19.52571,-23.8462 -6.9601,2.25521 -18.50812,5.71446 -29.89293,7.84517 -0.002,-0.003 -0.003,-0.004 0,-0.009 -0.003,-0.006 10e-4,-0.01 0.002,-0.0129 -0.001,-0.007 10e-4,-0.011 0.002,-0.0129 -0.001,-0.007 -0.001,-0.008 0,-0.011 5.81401,-10.47791 12.47128,-20.14765 16.65275,-25.93264 -4.29657,-5.92015 -11.1555,-15.83137 -16.70025,-25.99521 0.002,-0.003 0.006,-0.003 0.0111,-0.002 0.004,-0.004 0.01,-0.002 0.0129,-0.002 0.006,-0.003 0.011,-0.002 0.0129,-0.002 0.006,-0.003 0.007,-0.004 0.0111,-0.004 11.76574,2.28943 23.02338,5.63169 29.81955,7.81927 4.30503,-5.9142 11.61263,-15.49511 19.56888,-23.90661 0.003,10e-4 0.006,0.003 0.007,0.009 0.006,0.003 0.006,0.008 0.007,0.011 0.004,0.004 0.006,0.0112 0.007,0.0129 0.004,0.004 0.007,0.004 0.009,0.009 1.4575,11.89244 1.75546,23.62651 1.77428,30.76358 6.95749,2.26527 18.3316,6.25356 28.7921,11.21756 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-0.05275813,-0.13325181,0.13325181,-0.05275813,6.9661783,108.94066)" id="layer1-7-2" inkscape:label="Layer 1">
|
||||
<g style="display:inline" id="g4845-5-9" transform="matrix(0,-1,-1,0,373.50506,516.50504)">
|
||||
<g inkscape:label="Layer 1" id="g4778-3-1" transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)" inkscape:export-filename="next01.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
|
||||
<g style="display:inline" id="g4780-5-2" transform="matrix(-1,0,0,1,575.99999,611)">
|
||||
<rect transform="scale(-1,1)" y="345.36221" x="-438.00244" height="96" width="96.037987" id="rect4782-6-7" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"/>
|
||||
<path inkscape:connector-curvature="0" id="path4170-0" d="m 429.99929,393.33773 c 0,0.004 -9.5e-4,0.007 -0.007,0.009 -0.001,0.007 -0.006,0.007 -0.009,0.009 -0.003,0.006 -0.008,0.008 -0.011,0.009 -0.003,0.006 -0.003,0.006 -0.007,0.009 -10.86428,5.06033 -21.9364,8.97057 -28.72087,11.19382 -0.006,7.31383 -0.28348,19.36 -1.77427,30.84126 -0.004,10e-4 -0.006,0.002 -0.009,-0.002 -0.007,10e-4 -0.01,-0.004 -0.0129,-0.007 -0.007,-10e-4 -0.009,-0.004 -0.011,-0.007 -0.007,-10e-4 -0.006,-0.002 -0.009,-0.004 -8.17196,-8.76466 -15.31373,-18.08322 -19.52571,-23.8462 -6.9601,2.25521 -18.50812,5.71446 -29.89293,7.84517 -0.002,-0.003 -0.003,-0.004 0,-0.009 -0.003,-0.006 10e-4,-0.01 0.002,-0.0129 -0.001,-0.007 10e-4,-0.011 0.002,-0.0129 -0.001,-0.007 -0.001,-0.008 0,-0.011 5.81401,-10.47791 12.47128,-20.14765 16.65275,-25.93264 -4.29657,-5.92015 -11.1555,-15.83137 -16.70025,-25.99521 0.002,-0.003 0.006,-0.003 0.0111,-0.002 0.004,-0.004 0.01,-0.002 0.0129,-0.002 0.006,-0.003 0.011,-0.002 0.0129,-0.002 0.006,-0.003 0.007,-0.004 0.0111,-0.004 11.76574,2.28943 23.02338,5.63169 29.81955,7.81927 4.30503,-5.9142 11.61263,-15.49511 19.56888,-23.90661 0.003,10e-4 0.006,0.003 0.007,0.009 0.006,0.003 0.006,0.008 0.007,0.011 0.004,0.004 0.006,0.0112 0.007,0.0129 0.004,0.004 0.007,0.004 0.009,0.009 1.4575,11.89244 1.75546,23.62651 1.77428,30.76358 6.95749,2.26527 18.3316,6.25356 28.7921,11.21756 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.11335991,-0.05676641,0.05676641,0.11335991,131.32884,182.57734)" id="layer1-3-9">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-3">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-6">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-0">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-62"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-6" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-0.08526503,-0.09382307,0.09382307,-0.08526503,162.91459,100.60822)" id="layer1-3-1">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-8">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-7">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-9">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-2"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-0" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.10698289,0.06802614,-0.06802614,0.10698289,41.950743,171.57375)" id="layer1-3-2">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-37">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-5">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-92">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-28"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-9" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.21497396,0,0,0.21497395,186.37278,111.09076)" id="layer1-7-7" inkscape:label="Layer 1">
|
||||
<g style="display:inline" id="g4845-5-3" transform="matrix(0,-1,-1,0,373.50506,516.50504)">
|
||||
<g inkscape:label="Layer 1" id="g4778-3-6" transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)" inkscape:export-filename="next01.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
|
||||
<g style="display:inline" id="g4780-5-1" transform="matrix(-1,0,0,1,575.99999,611)">
|
||||
<rect transform="scale(-1,1)" y="345.36221" x="-438.00244" height="96" width="96.037987" id="rect4782-6-2" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"/>
|
||||
<path inkscape:connector-curvature="0" id="path4170-9" d="m 429.99929,393.33773 c 0,0.004 -9.5e-4,0.007 -0.007,0.009 -0.001,0.007 -0.006,0.007 -0.009,0.009 -0.003,0.006 -0.008,0.008 -0.011,0.009 -0.003,0.006 -0.003,0.006 -0.007,0.009 -10.86428,5.06033 -21.9364,8.97057 -28.72087,11.19382 -0.006,7.31383 -0.28348,19.36 -1.77427,30.84126 -0.004,10e-4 -0.006,0.002 -0.009,-0.002 -0.007,10e-4 -0.01,-0.004 -0.0129,-0.007 -0.007,-10e-4 -0.009,-0.004 -0.011,-0.007 -0.007,-10e-4 -0.006,-0.002 -0.009,-0.004 -8.17196,-8.76466 -15.31373,-18.08322 -19.52571,-23.8462 -6.9601,2.25521 -18.50812,5.71446 -29.89293,7.84517 -0.002,-0.003 -0.003,-0.004 0,-0.009 -0.003,-0.006 10e-4,-0.01 0.002,-0.0129 -0.001,-0.007 10e-4,-0.011 0.002,-0.0129 -0.001,-0.007 -0.001,-0.008 0,-0.011 5.81401,-10.47791 12.47128,-20.14765 16.65275,-25.93264 -4.29657,-5.92015 -11.1555,-15.83137 -16.70025,-25.99521 0.002,-0.003 0.006,-0.003 0.0111,-0.002 0.004,-0.004 0.01,-0.002 0.0129,-0.002 0.006,-0.003 0.011,-0.002 0.0129,-0.002 0.006,-0.003 0.007,-0.004 0.0111,-0.004 11.76574,2.28943 23.02338,5.63169 29.81955,7.81927 4.30503,-5.9142 11.61263,-15.49511 19.56888,-23.90661 0.003,10e-4 0.006,0.003 0.007,0.009 0.006,0.003 0.006,0.008 0.007,0.011 0.004,0.004 0.006,0.0112 0.007,0.0129 0.004,0.004 0.007,0.004 0.009,0.009 1.4575,11.89244 1.75546,23.62651 1.77428,30.76358 6.95749,2.26527 18.3316,6.25356 28.7921,11.21756 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-0.08041856,0.09800893,-0.09800893,-0.08041856,139.91992,284.24876)" id="layer1-3-1-3">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-8-1">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-7-9">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-9-4">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-2-7"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-0-8" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.01456664,-0.07599603,0.07599603,0.01456664,80.480787,182.36304)" id="layer1-7-2-4" inkscape:label="Layer 1">
|
||||
<g style="display:inline" id="g4845-5-9-5" transform="matrix(0,-1,-1,0,373.50506,516.50504)">
|
||||
<g inkscape:label="Layer 1" id="g4778-3-1-0" transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)" inkscape:export-filename="next01.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
|
||||
<g style="display:inline" id="g4780-5-2-3" transform="matrix(-1,0,0,1,575.99999,611)">
|
||||
<rect transform="scale(-1,1)" y="345.36221" x="-438.00244" height="96" width="96.037987" id="rect4782-6-7-6" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"/>
|
||||
<path inkscape:connector-curvature="0" id="path4170-0-1" d="m 429.99929,393.33773 c 0,0.004 -9.5e-4,0.007 -0.007,0.009 -0.001,0.007 -0.006,0.007 -0.009,0.009 -0.003,0.006 -0.008,0.008 -0.011,0.009 -0.003,0.006 -0.003,0.006 -0.007,0.009 -10.86428,5.06033 -21.9364,8.97057 -28.72087,11.19382 -0.006,7.31383 -0.28348,19.36 -1.77427,30.84126 -0.004,10e-4 -0.006,0.002 -0.009,-0.002 -0.007,10e-4 -0.01,-0.004 -0.0129,-0.007 -0.007,-10e-4 -0.009,-0.004 -0.011,-0.007 -0.007,-10e-4 -0.006,-0.002 -0.009,-0.004 -8.17196,-8.76466 -15.31373,-18.08322 -19.52571,-23.8462 -6.9601,2.25521 -18.50812,5.71446 -29.89293,7.84517 -0.002,-0.003 -0.003,-0.004 0,-0.009 -0.003,-0.006 10e-4,-0.01 0.002,-0.0129 -0.001,-0.007 10e-4,-0.011 0.002,-0.0129 -0.001,-0.007 -0.001,-0.008 0,-0.011 5.81401,-10.47791 12.47128,-20.14765 16.65275,-25.93264 -4.29657,-5.92015 -11.1555,-15.83137 -16.70025,-25.99521 0.002,-0.003 0.006,-0.003 0.0111,-0.002 0.004,-0.004 0.01,-0.002 0.0129,-0.002 0.006,-0.003 0.011,-0.002 0.0129,-0.002 0.006,-0.003 0.007,-0.004 0.0111,-0.004 11.76574,2.28943 23.02338,5.63169 29.81955,7.81927 4.30503,-5.9142 11.61263,-15.49511 19.56888,-23.90661 0.003,10e-4 0.006,0.003 0.007,0.009 0.006,0.003 0.006,0.008 0.007,0.011 0.004,0.004 0.006,0.0112 0.007,0.0129 0.004,0.004 0.007,0.004 0.009,0.009 1.4575,11.89244 1.75546,23.62651 1.77428,30.76358 6.95749,2.26527 18.3316,6.25356 28.7921,11.21756 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-0.12765378,0.07360069,-0.07360069,-0.12765378,81.653111,258.78327)" id="layer1-7-2-0" inkscape:label="Layer 1">
|
||||
<g style="display:inline" id="g4845-5-9-6" transform="matrix(0,-1,-1,0,373.50506,516.50504)">
|
||||
<g inkscape:label="Layer 1" id="g4778-3-1-3" transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)" inkscape:export-filename="next01.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
|
||||
<g style="display:inline" id="g4780-5-2-2" transform="matrix(-1,0,0,1,575.99999,611)">
|
||||
<rect transform="scale(-1,1)" y="345.36221" x="-438.00244" height="96" width="96.037987" id="rect4782-6-7-0" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"/>
|
||||
<path inkscape:connector-curvature="0" id="path4170-0-6" d="m 429.99929,393.33773 c 0,0.004 -9.5e-4,0.007 -0.007,0.009 -0.001,0.007 -0.006,0.007 -0.009,0.009 -0.003,0.006 -0.008,0.008 -0.011,0.009 -0.003,0.006 -0.003,0.006 -0.007,0.009 -10.86428,5.06033 -21.9364,8.97057 -28.72087,11.19382 -0.006,7.31383 -0.28348,19.36 -1.77427,30.84126 -0.004,10e-4 -0.006,0.002 -0.009,-0.002 -0.007,10e-4 -0.01,-0.004 -0.0129,-0.007 -0.007,-10e-4 -0.009,-0.004 -0.011,-0.007 -0.007,-10e-4 -0.006,-0.002 -0.009,-0.004 -8.17196,-8.76466 -15.31373,-18.08322 -19.52571,-23.8462 -6.9601,2.25521 -18.50812,5.71446 -29.89293,7.84517 -0.002,-0.003 -0.003,-0.004 0,-0.009 -0.003,-0.006 10e-4,-0.01 0.002,-0.0129 -0.001,-0.007 10e-4,-0.011 0.002,-0.0129 -0.001,-0.007 -0.001,-0.008 0,-0.011 5.81401,-10.47791 12.47128,-20.14765 16.65275,-25.93264 -4.29657,-5.92015 -11.1555,-15.83137 -16.70025,-25.99521 0.002,-0.003 0.006,-0.003 0.0111,-0.002 0.004,-0.004 0.01,-0.002 0.0129,-0.002 0.006,-0.003 0.011,-0.002 0.0129,-0.002 0.006,-0.003 0.007,-0.004 0.0111,-0.004 11.76574,2.28943 23.02338,5.63169 29.81955,7.81927 4.30503,-5.9142 11.61263,-15.49511 19.56888,-23.90661 0.003,10e-4 0.006,0.003 0.007,0.009 0.006,0.003 0.006,0.008 0.007,0.011 0.004,0.004 0.006,0.0112 0.007,0.0129 0.004,0.004 0.007,0.004 0.009,0.009 1.4575,11.89244 1.75546,23.62651 1.77428,30.76358 6.95749,2.26527 18.3316,6.25356 28.7921,11.21756 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-0.12725507,-0.14002765,0.14002765,-0.12725507,1.4536,290.74091)" id="layer1-3-1-1">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-8-5">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-7-5">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-9-47">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-2-6"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-0-5" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-0.04494106,-0.11350812,0.11350812,-0.04494106,164.40006,247.77949)" id="layer1-7-2-6" inkscape:label="Layer 1">
|
||||
<g style="display:inline" id="g4845-5-9-9" transform="matrix(0,-1,-1,0,373.50506,516.50504)">
|
||||
<g inkscape:label="Layer 1" id="g4778-3-1-37" transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)" inkscape:export-filename="next01.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
|
||||
<g style="display:inline" id="g4780-5-2-4" transform="matrix(-1,0,0,1,575.99999,611)">
|
||||
<rect transform="scale(-1,1)" y="345.36221" x="-438.00244" height="96" width="96.037987" id="rect4782-6-7-5" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"/>
|
||||
<path inkscape:connector-curvature="0" id="path4170-0-2" d="m 429.99929,393.33773 c 0,0.004 -9.5e-4,0.007 -0.007,0.009 -0.001,0.007 -0.006,0.007 -0.009,0.009 -0.003,0.006 -0.008,0.008 -0.011,0.009 -0.003,0.006 -0.003,0.006 -0.007,0.009 -10.86428,5.06033 -21.9364,8.97057 -28.72087,11.19382 -0.006,7.31383 -0.28348,19.36 -1.77427,30.84126 -0.004,10e-4 -0.006,0.002 -0.009,-0.002 -0.007,10e-4 -0.01,-0.004 -0.0129,-0.007 -0.007,-10e-4 -0.009,-0.004 -0.011,-0.007 -0.007,-10e-4 -0.006,-0.002 -0.009,-0.004 -8.17196,-8.76466 -15.31373,-18.08322 -19.52571,-23.8462 -6.9601,2.25521 -18.50812,5.71446 -29.89293,7.84517 -0.002,-0.003 -0.003,-0.004 0,-0.009 -0.003,-0.006 10e-4,-0.01 0.002,-0.0129 -0.001,-0.007 10e-4,-0.011 0.002,-0.0129 -0.001,-0.007 -0.001,-0.008 0,-0.011 5.81401,-10.47791 12.47128,-20.14765 16.65275,-25.93264 -4.29657,-5.92015 -11.1555,-15.83137 -16.70025,-25.99521 0.002,-0.003 0.006,-0.003 0.0111,-0.002 0.004,-0.004 0.01,-0.002 0.0129,-0.002 0.006,-0.003 0.011,-0.002 0.0129,-0.002 0.006,-0.003 0.007,-0.004 0.0111,-0.004 11.76574,2.28943 23.02338,5.63169 29.81955,7.81927 4.30503,-5.9142 11.61263,-15.49511 19.56888,-23.90661 0.003,10e-4 0.006,0.003 0.007,0.009 0.006,0.003 0.006,0.008 0.007,0.011 0.004,0.004 0.006,0.0112 0.007,0.0129 0.004,0.004 0.007,0.004 0.009,0.009 1.4575,11.89244 1.75546,23.62651 1.77428,30.76358 6.95749,2.26527 18.3316,6.25356 28.7921,11.21756 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.11335991,-0.05676641,0.05676641,0.11335991,164.93091,31.23567)" id="layer1-3-9-5">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-3-4">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-6-7">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-0-4">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-62-4"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-6-3" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.07328708,0.04660033,-0.04660033,0.07328708,202.61287,11.89896)" id="layer1-3-2-0">
|
||||
<g transform="matrix(0,-1,-1,0,373.51,516.51)" id="g4845-37-7">
|
||||
<g transform="matrix(-0.9996,0,0,1,575.94,-611)" id="g4778-5-8">
|
||||
<g transform="matrix(-1,0,0,1,576,611)" id="g4780-92-6">
|
||||
<rect x="-438" y="345.35999" width="96.038002" height="96" transform="scale(-1,1)" style="color:#000000;fill:none" id="rect4782-28-8"/>
|
||||
<path d="m 430,411.93 c 0,11.675 -9.3424,21.174 -20.961,21.429 -5.3915,0 -9.5995,-1.413 -13.487,-2.8571 -16.066,-6.7837 -29.485,-20 -45.584,-37.143 16.098,-17.143 29.518,-30.359 45.584,-37.143 3.888,-1.4441 8.096,-2.8571 13.487,-2.8571 11.618,0.25447 20.961,9.7538 20.961,21.429 0,7.9422 -4.3266,14.87 -10.748,18.571 6.4217,3.7014 10.748,10.629 10.748,18.571 z" style="color:#000000;fill:#808080" id="path4849-9-8" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<style id="style3713" type="text/css">
|
||||
.st0{fill:#878787;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
</style>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 27 KiB |
BIN
assets/colors.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
assets/favicon.ico
Normal file
|
After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 36 KiB |
1
assets/js/package/olm.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
// Dummy file :-)
|
||||
2766
assets/l10n/intl_ar.arb
Normal file
30
assets/l10n/intl_bn.arb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"@@last_modified": "2021-08-14 12:41:10.154280",
|
||||
"about": "সম্পর্কে",
|
||||
"@about": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accept": "স্বীকার করি",
|
||||
"@accept": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"acceptedTheInvitation": "{username} আমন্ত্রণ গ্রহণ করেছে",
|
||||
"@acceptedTheInvitation": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"account": "অ্যাকাউন্ট",
|
||||
"@account": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accountInformation": "অ্যাকাউন্ট তথ্য",
|
||||
"@accountInformation": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
2529
assets/l10n/intl_ca.arb
Normal file
2864
assets/l10n/intl_cs.arb
Normal file
2864
assets/l10n/intl_de.arb
Normal file
2854
assets/l10n/intl_en.arb
Normal file
2561
assets/l10n/intl_eo.arb
Normal file
2677
assets/l10n/intl_es.arb
Normal file
2864
assets/l10n/intl_et.arb
Normal file
2850
assets/l10n/intl_eu.arb
Normal file
122
assets/l10n/intl_fa.arb
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
{
|
||||
"@@last_modified": "2021-08-14 12:41:10.061080",
|
||||
"pleaseChooseAtLeastChars": "لطفاً حداقل {min} تا نماد انتخاب بده.",
|
||||
"@pleaseChooseAtLeastChars": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"min": {}
|
||||
}
|
||||
},
|
||||
"repeatPassword": "رمز عبور را تکرار بده",
|
||||
"@repeatPassword": {},
|
||||
"about": "درباره",
|
||||
"@about": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"passwordsDoNotMatch": "این رمزهای عبور مطابقه ندارند!",
|
||||
"@passwordsDoNotMatch": {},
|
||||
"pleaseEnterValidEmail": "لطفاً یک آدرس ایمیل معتبر وارد کن.",
|
||||
"@pleaseEnterValidEmail": {},
|
||||
"accept": "بپذیر",
|
||||
"@accept": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"acceptedTheInvitation": "{username} دعوت را پذیرفت",
|
||||
"@acceptedTheInvitation": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"account": "حساب",
|
||||
"@account": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accountInformation": "اطلاعات حساب",
|
||||
"@accountInformation": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"addToSpace": "به اسپاش اضافه کن",
|
||||
"@addToSpace": {},
|
||||
"appLock": "قفل برنامه",
|
||||
"@appLock": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"all": "همه",
|
||||
"@all": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"allChats": "همه اتاقها",
|
||||
"@allChats": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"addEmail": "ایمیل اضافه کن",
|
||||
"@addEmail": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"addGroupDescription": "توضیحات گروه اضافه کن",
|
||||
"@addGroupDescription": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"addNewFriend": "دوست جدید اضافه کن",
|
||||
"@addNewFriend": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"alreadyHaveAnAccount": "قبلاً حساب دارید؟",
|
||||
"@alreadyHaveAnAccount": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"answeredTheCall": "{senderName} زنگ زدن را جواب کرد",
|
||||
"@answeredTheCall": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"anyoneCanJoin": "هرکسی میتواند بپیوندد",
|
||||
"@anyoneCanJoin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archive": "بایگانی",
|
||||
"@archive": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "اتاق بایگانی شده",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areYouSure": "مطمئن هستید؟",
|
||||
"@areYouSure": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areYouSureYouWantToLogout": "مطمئن هستید میخواهید خروج شوید؟",
|
||||
"@areYouSureYouWantToLogout": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"audioPlayerPause": "مکث",
|
||||
"@audioPlayerPause": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"audioPlayerPlay": "نمایش",
|
||||
"@audioPlayerPlay": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
2845
assets/l10n/intl_fi.arb
Normal file
2860
assets/l10n/intl_fr.arb
Normal file
2635
assets/l10n/intl_ga.arb
Normal file
2864
assets/l10n/intl_gl.arb
Normal file
1701
assets/l10n/intl_he.arb
Normal file
2764
assets/l10n/intl_hr.arb
Normal file
2257
assets/l10n/intl_hu.arb
Normal file
1551
assets/l10n/intl_hy.arb
Normal file
2886
assets/l10n/intl_id.arb
Normal file
2471
assets/l10n/intl_it.arb
Normal file
2381
assets/l10n/intl_ja.arb
Normal file
2765
assets/l10n/intl_ko.arb
Normal file
2843
assets/l10n/intl_lt.arb
Normal file
2211
assets/l10n/intl_nb.arb
Normal file
2863
assets/l10n/intl_nl.arb
Normal file
2432
assets/l10n/intl_pl.arb
Normal file
3
assets/l10n/intl_pt.arb
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"@@last_modified": "2021-08-14 12:41:09.940318"
|
||||
}
|
||||
2861
assets/l10n/intl_pt_BR.arb
Normal file
2003
assets/l10n/intl_pt_PT.arb
Normal file
182
assets/l10n/intl_ro.arb
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
{
|
||||
"@@last_modified": "2021-08-14 12:41:09.918296",
|
||||
"about": "Despre",
|
||||
"@about": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accept": "Accept",
|
||||
"@accept": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"acceptedTheInvitation": "{username} a aceptat invitați",
|
||||
"@acceptedTheInvitation": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"account": "Cont",
|
||||
"@account": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accountInformation": "Informații despre cont",
|
||||
"@accountInformation": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"activatedEndToEndEncryption": "{username} a activat criptarea end-to-end",
|
||||
"@activatedEndToEndEncryption": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"addGroupDescription": "Adaugă o descriere de",
|
||||
"@addGroupDescription": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"admin": "Administrator",
|
||||
"@admin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"alias": "poreclă",
|
||||
"@alias": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"alreadyHaveAnAccount": "Ai deja un cont?",
|
||||
"@alreadyHaveAnAccount": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"answeredTheCall": "{sendername} a acceptat apelul",
|
||||
"@answeredTheCall": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"anyoneCanJoin": "Oricine se poate alătura",
|
||||
"@anyoneCanJoin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archive": "Arhivă",
|
||||
"@archive": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Grup arhivat",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Vizitatorii \"guest\" se pot alătura",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areYouSure": "Ești sigur?",
|
||||
"@areYouSure": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"askSSSSCache": "Te rog introdu parola ta sau cheile de recuparare pentru a depozita cheile.",
|
||||
"@askSSSSCache": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"askSSSSSign": "Pentru a putea conecta cealaltă persoană, te rog introdu parola sau cheia ta de recuperare.",
|
||||
"@askSSSSSign": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"askSSSSVerify": "Te rog introdu parola sau cheia ta de recuperare pentru a-ți verifica sesiunea.",
|
||||
"@askSSSSVerify": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"askVerificationRequest": "Accepți cererea de verificare de la {username}?",
|
||||
"@askVerificationRequest": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"authentication": "Autentificare",
|
||||
"@authentication": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"avatarHasBeenChanged": "Image de profil schimbată",
|
||||
"@avatarHasBeenChanged": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"banFromChat": "Interzis din conversație",
|
||||
"@banFromChat": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"banned": "Interzis",
|
||||
"@banned": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"bannedUser": "{username} a interzis pe {targetName}",
|
||||
"@bannedUser": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"targetName": {}
|
||||
}
|
||||
},
|
||||
"blockDevice": "Blochează dispozitiv",
|
||||
"@blockDevice": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"cachedKeys": "Chei salvate",
|
||||
"@cachedKeys": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"cancel": "Anulează",
|
||||
"@cancel": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"changeDeviceName": "Schimbă numele dispozitiv",
|
||||
"@changeDeviceName": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"changedTheChatAvatar": "{username} a schimbat poza conversați",
|
||||
"@changedTheChatAvatar": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"changedTheChatDescriptionTo": "{username} a schimbat descrierea grupului în '{description}'",
|
||||
"@changedTheChatDescriptionTo": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"description": {}
|
||||
}
|
||||
},
|
||||
"changedTheChatNameTo": "{username} a schimbat porecla în '{chatname}'",
|
||||
"@changedTheChatNameTo": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"chatname": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
2892
assets/l10n/intl_ru.arb
Normal file
374
assets/l10n/intl_si.arb
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
{
|
||||
"@@last_modified": "2021-08-14 12:41:09.895217",
|
||||
"about": "පිළිබඳව",
|
||||
"@about": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accept": "පිළිගන්න",
|
||||
"@accept": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"account": "ගිණුම",
|
||||
"@account": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"accountInformation": "ගිණුමේ තොරතුරු",
|
||||
"@accountInformation": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"addEmail": "වි-තැපෑල එකතු කරන්න",
|
||||
"@addEmail": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"admin": "පරිපාලක",
|
||||
"@admin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"allChats": "සියලුම සංවාද",
|
||||
"@allChats": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"alreadyHaveAnAccount": "දැනටමත් ගිණුමක් තිබේද?",
|
||||
"@alreadyHaveAnAccount": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"anyoneCanJoin": "ඕනෑම කෙනෙකුට එක්විය හැකිය",
|
||||
"@anyoneCanJoin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archive": "සංරක්ෂිතය",
|
||||
"@archive": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "සංරක්ෂිත කාමරය",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "ආගන්තුක පරිශීලකයින්ට එක්වීමට අවසර තිබේද",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areYouSure": "ඔබට විශ්වාසද?",
|
||||
"@areYouSure": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areYouSureYouWantToLogout": "ඔබට නික්මීමට අවශ්ය බව විශ්වාසද?",
|
||||
"@areYouSureYouWantToLogout": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"audioPlayerPlay": "ධාවනය",
|
||||
"@audioPlayerPlay": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"blockDevice": "උපාංගය අවහිර කරන්න",
|
||||
"@blockDevice": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"cachedKeys": "යතුරු නිහිතගතයි",
|
||||
"@cachedKeys": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"cancel": "අවලංගු කරන්න",
|
||||
"@cancel": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"changeDeviceName": "උපාංගයේ නම වෙනස් කරන්න",
|
||||
"@changeDeviceName": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"changePassword": "මුරපදය වෙනස් කරන්න",
|
||||
"@changePassword": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"chat": "සංවාදය",
|
||||
"@chat": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"chatBackup": "සංවාද උපස්ථය",
|
||||
"@chatBackup": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"chatDetails": "සංවාදයේ විස්තර",
|
||||
"@chatDetails": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"chats": "සංවාද",
|
||||
"@chats": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"chooseAStrongPassword": "ශක්තිමත් මුරපදයක් තෝරන්න",
|
||||
"@chooseAStrongPassword": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"chooseAUsername": "පරිශීලක නාමයක් තෝරන්න",
|
||||
"@chooseAUsername": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"clearArchive": "සංරක්ෂිතය හිස් කරන්න",
|
||||
"@clearArchive": {},
|
||||
"close": "වසන්න",
|
||||
"@close": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"commandHint_join": "දී ඇති කාමරයට එක්වන්න",
|
||||
"@commandHint_join": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /join"
|
||||
},
|
||||
"commandHint_leave": "මෙම කාමරය හැරයන්න",
|
||||
"@commandHint_leave": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /leave"
|
||||
},
|
||||
"commandInvalid": "විධානය වලංගු නොවේ",
|
||||
"@commandInvalid": {
|
||||
"type": "text"
|
||||
},
|
||||
"commandMissing": "{{command} විධානයක් නොවේ.",
|
||||
"@commandMissing": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"command": {}
|
||||
},
|
||||
"description": "State that {command} is not a valid /command."
|
||||
},
|
||||
"compareEmojiMatch": "සසඳා බලා පහත දැක්වෙන ඉමොජි අනෙක් උපාංගයට නිසැකවම ගැලපෙන බවට වග බලා ගන්න:",
|
||||
"@compareEmojiMatch": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"compareNumbersMatch": "සංසන්දනය කර පහත දැක්වෙන අංක අනෙක් උපාංගට නිසැකව ගැලපෙන බවට වග බලා ගන්න:",
|
||||
"@compareNumbersMatch": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"confirm": "තහවුරු කරන්න",
|
||||
"@confirm": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"connect": "සබඳින්න",
|
||||
"@connect": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"connectionAttemptFailed": "සබැඳීමේ උත්සාහය අසාර්ථකයි",
|
||||
"@connectionAttemptFailed": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"contactHasBeenInvitedToTheGroup": "සමූහය වෙත සබඳතාවයකට ආරාධනා කර ඇත",
|
||||
"@contactHasBeenInvitedToTheGroup": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"copy": "පිටපත්",
|
||||
"@copy": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"create": "සාදන්න",
|
||||
"@create": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"createAccountNow": "දැන් ගිණුමක් සාදන්න",
|
||||
"@createAccountNow": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"createNewGroup": "නව සමූහයක් සාදන්න",
|
||||
"@createNewGroup": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"donate": "පරිත්යාග",
|
||||
"@donate": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"encryption": "සංකේතාංකනය",
|
||||
"@encryption": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"everythingReady": "සියල්ල සූදානම්!",
|
||||
"@everythingReady": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fontSize": "මුද්රණඅකුරේ ප්රමාණය",
|
||||
"@fontSize": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"goToTheNewRoom": "නව කාමරයට යන්න",
|
||||
"@goToTheNewRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinRoom": "කාමරයට එක්වන්න",
|
||||
"@joinRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "යතුරු නිහිතගත යි",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"next": "ඊලඟ",
|
||||
"@next": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noPublicRoomsFound": "ප්රසිද්ධ කාමර හමු නොවිණි…",
|
||||
"@noPublicRoomsFound": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"people": "මිනිසුන්",
|
||||
"@people": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"publicGroups": "ප්රසිද්ධ සමූහ",
|
||||
"@publicGroups": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"removeDevice": "උපාංගය ඉවත්කරන්න",
|
||||
"@removeDevice": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"roomVersion": "කාමරයේ අනුවාදය",
|
||||
"@roomVersion": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"savedFileAs": "ලෙස ගොනුව සුරකින්න {filename}",
|
||||
"@savedFileAs": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"filename": {}
|
||||
}
|
||||
},
|
||||
"saveFile": "ගොනුව සුරකින්න",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFileToFolder": "ගොනුව මෙම බහාලුමට සුරකින්න",
|
||||
"@saveFileToFolder": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"securityKey": "ආරක්ෂක යතුර",
|
||||
"@securityKey": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"securityKeyLost": "ආරක්ෂක යතුර නැතිවුනාද?",
|
||||
"@securityKeyLost": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"send": "යවන්න",
|
||||
"@send": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"showPassword": "මුරපදය පෙන්වන්න",
|
||||
"@showPassword": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "ඉරිදා",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"username": "පරිශීලක නාමය",
|
||||
"@username": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"videoCall": "දෘශ්ය ඇමතුම",
|
||||
"@videoCall": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wallpaper": "බිතුපත",
|
||||
"@wallpaper": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"warning": "අවවාදයයි!",
|
||||
"@warning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "බදාදා",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"writeAMessage": "පණිවිඩයක් ලියන්න…",
|
||||
"@writeAMessage": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yes": "ඔව්",
|
||||
"@yes": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"you": "ඔබ",
|
||||
"@you": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourOwnUsername": "ඔබට හිමි පරිශීලකනාමය",
|
||||
"@yourOwnUsername": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"zoomIn": "විශාලනය",
|
||||
"@zoomIn": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"zoomOut": "කුඩාලනය",
|
||||
"@zoomOut": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||