v1-t
harvey186 2025-06-30 10:56:29 +02:00
parent 1ca61b3bef
commit c47bd82b0c
217 changed files with 18308 additions and 2048 deletions

View File

@ -1,30 +0,0 @@
# Definitions for jobs that run periodically. For details on the format, see
# `taskcluster/taskgraph/cron/schema.py`. For documentation, see
# `taskcluster/docs/cron.rst`.
---
jobs:
- name: fennec-production
job:
type: decision-task
treeherder-symbol: fennec-production
target-tasks-method: fennec-production
when: [] # Force hook only
- name: bump-android-components
job:
type: decision-task
treeherder-symbol: bump-ac
target-tasks-method: bump_android_components
when: [{hour: 15, minute: 30}]
- name: screenshots
job:
type: decision-task
treeherder-symbol: screenshots-D
target-tasks-method: screenshots
when: [{weekday: 'Monday', hour: 10, minute: 0}]
- name: legacy-api-ui-tests
job:
type: decision-task
treeherder-symbol: legacy-api-ui
target-tasks-method: legacy_api_ui_tests
when: [{hour: 10, minute: 30}]

9
.gitignore vendored
View File

@ -14,6 +14,9 @@
# Java class files
*.class
# Kotlin
.kotlin
# Generated files
bin/
gen/
@ -83,13 +86,17 @@ gen-external-apklibs
.mls_token
.wallpaper_url
# Google Play Publisher credentials
play-service-account.json
*.p12
# Python Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
venv/
# UI test artifacts
# UI test artifacts
.firebase_token*
results/
test_artifacts/

View File

@ -1,100 +0,0 @@
queue_rules:
- name: default
conditions:
- or:
- status-success=complete-pr
- and:
# For more context, see "Auto Merge" rules down below
- base~=^releases[_/].*
- status-success=complete-push
- or:
- head~=^automation/sync-strings-\d+
- head~=^relbot/fenix-\d+
pull_request_rules:
- name: Resolve conflict
conditions:
- conflict
actions:
comment:
message: This pull request has conflicts when rebasing. Could you fix it @{{author}}? 🙏
- name: Android-Components bump - Auto Merge
conditions:
- and:
- files=buildSrc/src/main/java/AndroidComponents.kt
- -files~=^(?!buildSrc/src/main/java/AndroidComponents.kt).+$
- or:
- and:
- author=MickeyMoz
- base=main
- head=ac-update
- status-success=complete-pr
- and:
- author=github-actions[bot]
- base~=^releases[_/].*
- head~=^relbot/fenix-\d+
- status-success=complete-push
actions:
review:
type: APPROVE
message: 🚢
queue:
method: rebase
name: default
rebase_fallback: none
- name: L10N - Auto Merge
conditions:
- and:
- files~=^(l10n.toml|app/src/main/res/values[A-Za-z-]*/strings\.xml)$
# /!\ The line above doesn't prevent random files to be changed alongside
# l10n ones. That's why the additional condition exists below. For more
# information: https://docs.mergify.com/conditions/#how-to-match-lists
- -files~=^(?!(l10n.toml|app/src/main/res/values[A-Za-z-]*/strings\.xml)).+$
- or:
- and:
- author=mozilla-l10n-automation-bot
- base=main
- head=import-l10n
- status-success=complete-pr
- and:
- author=github-actions[bot]
- base~=^releases[_/].*
- head~=^automation/sync-strings-\d+
- status-success=complete-push
# Taskcluster only runs on git-push events because github-actions[bot] is not considered
# a collaborator, so pull request events are triggered. That said, github-actions[bot]
# doesn't create the PR on a separate fork (unlike mozilla-l10n-automation-bot). That's
# why git-push events are taken into account
actions:
review:
type: APPROVE
message: LGTM 😎
queue:
method: rebase
name: default
rebase_fallback: none
- name: Needs landing - Rebase
conditions:
- check-success=complete-pr
- label=pr:needs-landing
- "#approved-reviews-by>=1"
- -draft
- label!=pr:work-in-progress
- label!=pr:do-not-land
actions:
queue:
method: rebase
name: default
rebase_fallback: none
- name: Needs landing - Squash
conditions:
- check-success=complete-pr
- label=pr:needs-landing-squashed
- "#approved-reviews-by>=1"
- -draft
- label!=pr:work-in-progress
- label!=pr:do-not-land
actions:
queue:
method: squash
name: default
rebase_fallback: none

View File

@ -1,15 +0,0 @@
# Community Participation Guidelines
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
For more details, please read the
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
## How to Report
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
<!--
## Project Specific Etiquette
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
Please update for your project.
-->

View File

@ -1,3 +0,0 @@
source "https://rubygems.org"
gem "fastlane"

53
Jenkinsfile vendored
View File

@ -1,53 +0,0 @@
pipeline {
agent any
triggers {
cron(env.BRANCH_NAME == 'main' ? 'H 0 * * *' : '')
}
options {
timestamps()
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('test') {
when { branch 'main' }
steps {
dir('app/src/androidTest/java/net/waterfox/android/syncIntegration') {
sh 'pipenv install'
sh 'pipenv check'
sh 'pipenv run pytest'
}
}
}
}
post {
always {
script {
if (env.BRANCH_NAME == 'main') {
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'app/src/androidTest/java/net/waterfox/android/syncintegration/results',
reportFiles: 'index.html',
reportName: 'HTML Report'])
}
}
}
failure {
script {
if (env.BRANCH_NAME == 'main') {
slackSend(
color: 'danger',
message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL}HTML_20Report/)")
}
}
}
fixed {
slackSend(
color: 'good',
message: "FIXED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL}HTML_20Report/)")
}
}
}

123
README.md
View File

@ -4,7 +4,128 @@ The all-new Waterfox for Android browser is based on [GeckoView](https://mozilla
## License
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/
## Building with Local Android Components
To build Waterfox for Android with local Android components - as opposed to via Android Studio and Mozilla's Maven respository - you'll first need to build GeckoView from source and then build Waterfox for Android itself, pointing it to your local GeckoView build.
These instructions are based on if you were to start from a clean Linux distribution installation.
### 1. Clone and Prepare GeckoView
First, clone the Firefox repository (which contains GeckoView). These instructions assume you will clone it into a directory named `firefox`. We do not care about the commit history, so we are shallow cloning.
```shell
git clone --depth 1 --branch release https://github.com/mozilla-firefox/firefox/
cd firefox
```
### 2. Install Python Dependencies
Ensure you have `python3-pip` installed, which is required by Mozilla's build scripts.
```shell
sudo apt-get install python3-pip
```
### 3. Bootstrap GeckoView
Run the `mach` bootstrap command to set up the build environment for GeckoView specifically for Android.
```shell
./mach --no-interactive bootstrap --application-choice="GeckoView/Firefox for Android"
```
### 4. Configure the GeckoView Build
Create a `.mozconfig` file in the `firefox` directory with the necessary build options. This configuration enables the Android mobile project, optimizes the build, disables debug symbols, and enables GeckoView Lite.
```shell
rm -f mozconfig
cat > .mozconfig << 'EOF'
ac_add_options --enable-project=mobile/android
ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --enable-geckoview-lite
EOF
```
### 5. Build GeckoView
Compile GeckoView and its binaries. This can take a significant amount of time.
```shell
./mach build && ./mach build binaries
```
### 6. Publish GeckoView to Maven Local
Publish the GeckoView and Exoplayer2 artifacts to your local Maven repository. This makes them accessible to the Waterfox for Android build system.
```shell
./mach gradle geckoview:publishDebugPublicationToMavenLocal
./mach gradle exoplayer2:publishDebugPublicationToMavenLocal
```
### 7. Clone Waterfox-Android
Navigate out of the `firefox` directory (or whatever you named your GeckoView clone) and clone the Waterfox-Android repository.
```shell
cd ../
git clone git@github.com:BrowserWorks/Waterfox-Android.git
cd Waterfox-Android
```
### 8. Configure Local Properties for Waterfox-Android
Create a `local.properties` file in the root of the `Waterfox-Android` project. This file tells the Waterfox build system where to find your locally built GeckoView.
Execute the following command in the `Waterfox-Android` directory:
```shell
cat > local.properties << 'EOF'
dependencySubstitutions.geckoviewTopsrcdir=/home/$USER/firefox
dependencySubstitutions.geckoviewTopobjdir=/home/$USER/firefox/obj-$TRIPLET
EOF
```
The `dependencySubstitutions.geckoviewTopsrcdir` path should point to the root of your GeckoView source code (e.g., the `firefox` directory you cloned in Step 1). The `dependencySubstitutions.geckoviewTopobjdir` path should point to the object directory within your GeckoView build, which is typically `obj-` followed by your architecture triplet (e.g., `obj-x86_64-unknown-linux-android`).
For example, if you cloned GeckoView to `/workspace/firefox` and your object directory is `/workspace/firefox/obj-x86_64-unknown-linux-android`, your `local.properties` would look like:
```Waterfox-Android/local.properties#L1-2
dependencySubstitutions.geckoviewTopsrcdir=/workspace/firefox
dependencySubstitutions.geckoviewTopobjdir=/workspace/firefox/obj-x86_64-unknown-linux-android
```
### 9. Set Environment Variables
Set the `JAVA_HOME` and `ANDROID_HOME` environment variables. The paths shown below are typical for a `.mozbuild` setup (created during GeckoView bootstrap) but might differ on your system. Ensure these point to a JDK 17 and a valid Android SDK.
```shell
# These paths might differ based on your .mozbuild setup
export JAVA_HOME=$HOME/.mozbuild/jdk/jdk-17.0.13+11/ # Or your JDK 17 path
export ANDROID_HOME=$HOME/.mozbuild/android-sdk-linux/ # Or your Android SDK path
```
### 10. Build Waterfox-Android
Finally, clean and build the Waterfox for Android application.
To build a **debug** version:
```shell
./gradlew clean app:assembleDebug
```
To build a **release** version:
```shell
./gradlew clean app:assembleRelease
```
Note: For release builds, you will need to have set up signing configurations as per standard Android development practices.

View File

@ -1,5 +0,0 @@
# Security Policy
## Reporting a Vulnerability
Report all security vunerablites to [Bugzilla Fenix::Security](https://bugzilla.mozilla.org/enter_bug.cgi?product=Fenix&component=Security). If they are not a security bug you will be asked to move your report to [Fenix GitHub](https://github.com/mozilla-mobile/fenix/issues). See the [Mozilla Security Bug Bounty Program](https://www.mozilla.org/en-US/security/bug-bounty/) and the [client security reporting](https://www.mozilla.org/en-US/security/client-bug-bounty/) pages for details. In any case where this document and the Mozilla.org pages differ the Mozilla.org pages are the official documentation.

View File

@ -2,16 +2,31 @@ import com.android.build.OutputFile
import groovy.json.JsonOutput
import net.waterfox.android.gradle.tasks.ApkSizeTask
plugins {
alias libs.plugins.android.application
alias libs.plugins.kotlin.android
alias libs.plugins.androidx.safeargs
alias libs.plugins.kotlin.parcelize
alias libs.plugins.compose.compiler
alias libs.plugins.play.publisher
id "com.jetbrains.python.envs" version "0.0.26"
id 'jacoco'
id 'com.google.android.gms.oss-licenses-plugin'
id("app.accrescent.tools.bundletool") version "0.2.4"
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'jacoco'
apply plugin: 'androidx.navigation.safeargs.kotlin'
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
bundletool {
// Only configure signing if the KEYSTORE environment variable is set
if (System.getenv("KEYSTORE") != null) {
signingConfig {
storeFile = file(System.getenv("KEYSTORE"))
storePassword = System.getenv("KEYSTORE_PWD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEY_ALIAS_PWD")
}
}
}
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
@ -20,6 +35,16 @@ import static org.gradle.api.tasks.testing.TestResult.ResultType
apply from: 'benchmark.gradle'
play {
// The plugin will read the service account credentials from the
// ANDROID_PUBLISHER_CREDENTIALS environment variable if it's set
enabled.set(gradle.hasProperty("enablePlayPublisher") || System.getenv("ANDROID_PUBLISHER_CREDENTIALS") != null)
// Only publish release builds
defaultToAppBundles.set(true)
track.set("internal") // Start with internal track for safety
}
android {
project.maybeConfigForJetpackBenchmark(it)
if (project.hasProperty("testBuildType")) {
@ -43,7 +68,7 @@ android {
buildConfigField "String", "GIT_HASH", "\"\"" // see override in release builds for why it's blank.
// This should be the "public" base URL of AMO.
buildConfigField "String", "AMO_BASE_URL", "\"https://addons.mozilla.org\""
buildConfigField "String", "AMO_COLLECTION_NAME", "\"Waterfox-Android\""
buildConfigField "String", "AMO_COLLECTION_NAME", "\"LeOSium-Android\""
buildConfigField "String", "AMO_COLLECTION_USER", "\"17224042\""
// This should be the base URL used to call the AMO API.
buildConfigField "String", "AMO_SERVER_URL", "\"https://services.addons.mozilla.org\""
@ -84,6 +109,7 @@ android {
applicationIdSuffix ".debug"
resValue "bool", "IS_DEBUG", "true"
pseudoLocalesEnabled true
testCoverageEnabled true
}
release releaseTemplate >> {
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
@ -119,7 +145,13 @@ android {
animationsDisabled = true
}
flavorDimensions "engine"
flavorDimensions.add("product")
productFlavors {
waterfox {
dimension "product"
}
}
sourceSets {
androidTest {
@ -140,6 +172,7 @@ android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
coreLibraryDesugaringEnabled true
}
lint {
@ -229,7 +262,7 @@ android.applicationVariants.all { variant ->
buildConfigField 'String', 'SENTRY_TOKEN', 'null'
if (!isDebug) {
buildConfigField 'boolean', 'CRASH_REPORTING', 'true'
buildConfigField 'boolean', 'CRASH_REPORTING', 'false'
// Reading sentry token from local file (if it exists). In a release task on Fastlane it will be available.
try {
def token = new File("${rootDir}/.sentry_token").text.trim()
@ -304,145 +337,146 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
}
dependencies {
implementation Deps.mozilla_browser_engine_gecko
implementation libs.mozilla.browser.engine.gecko
implementation Deps.kotlin_stdlib
implementation Deps.kotlin_coroutines
implementation Deps.kotlin_coroutines_android
testImplementation Deps.kotlin_coroutines_test
implementation Deps.androidx_appcompat
implementation Deps.androidx_activity_compose
implementation Deps.androidx_constraintlayout
implementation Deps.androidx_coordinatorlayout
implementation Deps.google_accompanist_drawablepainter
implementation Deps.google_accompanist_insets
implementation Deps.google_accompanist_swiperefresh
implementation Deps.coil
implementation libs.kotlin.stdlib
implementation libs.kotlin.coroutines
implementation libs.kotlin.coroutines.android
testImplementation libs.kotlin.coroutines.test
implementation libs.androidx.appcompat
implementation libs.androidx.activity.compose
implementation libs.androidx.constraintlayout
implementation libs.androidx.coordinatorlayout
implementation libs.google.accompanist.drawablepainter
implementation libs.google.accompanist.insets
implementation libs.google.accompanist.swiperefresh
implementation libs.coil
// implementation Deps.sentry
// implementation libs.sentry
implementation Deps.mozilla_compose_awesomebar
implementation libs.mozilla.compose.awesomebar
implementation Deps.mozilla_concept_awesomebar
implementation Deps.mozilla_concept_base
implementation Deps.mozilla_concept_engine
implementation Deps.mozilla_concept_menu
implementation Deps.mozilla_concept_push
implementation Deps.mozilla_concept_storage
implementation Deps.mozilla_concept_sync
implementation Deps.mozilla_concept_toolbar
implementation Deps.mozilla_concept_tabstray
implementation libs.mozilla.concept.awesomebar
implementation libs.mozilla.concept.base
implementation libs.mozilla.concept.engine
implementation libs.mozilla.concept.menu
implementation libs.mozilla.concept.push
implementation libs.mozilla.concept.storage
implementation libs.mozilla.concept.sync
implementation libs.mozilla.concept.toolbar
implementation libs.mozilla.concept.tabstray
implementation Deps.mozilla_browser_domains
implementation Deps.mozilla_browser_icons
implementation Deps.mozilla_browser_menu
implementation Deps.mozilla_browser_menu2
implementation Deps.mozilla_browser_session_storage
implementation Deps.mozilla_browser_state
implementation Deps.mozilla_browser_storage_sync
implementation Deps.mozilla_browser_tabstray
implementation Deps.mozilla_browser_thumbnails
implementation Deps.mozilla_browser_toolbar
implementation libs.mozilla.browser.domains
implementation libs.mozilla.browser.icons
implementation libs.mozilla.browser.menu
implementation libs.mozilla.browser.menu2
implementation libs.mozilla.browser.session.storage
implementation libs.mozilla.browser.state
implementation libs.mozilla.browser.storage.sync
implementation libs.mozilla.browser.tabstray
implementation libs.mozilla.browser.thumbnails
implementation libs.mozilla.browser.toolbar
implementation Deps.mozilla_feature_addons
implementation Deps.mozilla_feature_accounts
implementation Deps.mozilla_feature_app_links
implementation Deps.mozilla_feature_autofill
implementation Deps.mozilla_feature_awesomebar
implementation Deps.mozilla_feature_contextmenu
implementation Deps.mozilla_feature_customtabs
implementation Deps.mozilla_feature_downloads
implementation Deps.mozilla_feature_intent
implementation Deps.mozilla_feature_media
implementation Deps.mozilla_feature_prompts
implementation Deps.mozilla_feature_push
implementation Deps.mozilla_feature_privatemode
implementation Deps.mozilla_feature_pwa
implementation Deps.mozilla_feature_qr
implementation Deps.mozilla_feature_search
implementation Deps.mozilla_feature_session
implementation Deps.mozilla_feature_syncedtabs
implementation Deps.mozilla_feature_toolbar
implementation Deps.mozilla_feature_tabs
implementation Deps.mozilla_feature_findinpage
implementation Deps.mozilla_feature_logins
implementation Deps.mozilla_feature_site_permissions
implementation Deps.mozilla_feature_readerview
implementation Deps.mozilla_feature_tab_collections
implementation Deps.mozilla_feature_recentlyclosed
implementation Deps.mozilla_feature_top_sites
implementation Deps.mozilla_feature_share
implementation Deps.mozilla_feature_accounts_push
implementation Deps.mozilla_feature_webauthn
implementation Deps.mozilla_feature_webcompat
implementation Deps.mozilla_feature_webnotifications
implementation Deps.mozilla_feature_webcompat_reporter
implementation libs.mozilla.feature.addons
implementation libs.mozilla.feature.accounts
implementation libs.mozilla.feature.app.links
implementation libs.mozilla.feature.autofill
implementation libs.mozilla.feature.awesomebar
implementation libs.mozilla.feature.contextmenu
implementation libs.mozilla.feature.customtabs
implementation libs.mozilla.feature.downloads
implementation libs.mozilla.feature.intent
implementation libs.mozilla.feature.media
implementation libs.mozilla.feature.prompts
implementation libs.mozilla.feature.push
implementation libs.mozilla.feature.privatemode
implementation libs.mozilla.feature.pwa
implementation libs.mozilla.feature.qr
implementation libs.mozilla.feature.search
implementation libs.mozilla.feature.session
implementation libs.mozilla.feature.syncedtabs
implementation libs.mozilla.feature.toolbar
implementation libs.mozilla.feature.tabs
implementation libs.mozilla.feature.findinpage
implementation libs.mozilla.feature.logins
implementation libs.mozilla.feature.site.permissions
implementation libs.mozilla.feature.readerview
implementation libs.mozilla.feature.tab.collections
implementation libs.mozilla.feature.recentlyclosed
implementation libs.mozilla.feature.top.sites
implementation libs.mozilla.feature.share
implementation libs.mozilla.feature.accounts.push
implementation libs.mozilla.feature.webauthn
implementation libs.mozilla.feature.webcompat
implementation libs.mozilla.feature.webnotifications
implementation libs.mozilla.feature.webcompat.reporter
implementation Deps.mozilla_service_mars
implementation Deps.mozilla_service_digitalassetlinks
implementation Deps.mozilla_service_sync_autofill
implementation Deps.mozilla_service_sync_logins
implementation Deps.mozilla_service_firefox_accounts
implementation Deps.mozilla_service_location
implementation libs.mozilla.service.mars
implementation libs.mozilla.service.digitalassetlinks
implementation libs.mozilla.service.sync.autofill
implementation libs.mozilla.service.sync.logins
implementation libs.mozilla.service.firefox.accounts
implementation libs.mozilla.service.location
implementation Deps.mozilla_support_extensions
implementation Deps.mozilla_support_base
implementation Deps.mozilla_support_rusterrors
implementation Deps.mozilla_support_images
implementation Deps.mozilla_support_ktx
implementation Deps.mozilla_support_rustlog
implementation Deps.mozilla_support_utils
implementation Deps.mozilla_support_locale
implementation libs.mozilla.support.extensions
implementation libs.mozilla.support.base
implementation libs.mozilla.support.rusterrors
implementation libs.mozilla.support.images
implementation libs.mozilla.support.ktx
implementation libs.mozilla.support.rustlog
implementation libs.mozilla.support.utils
implementation libs.mozilla.support.locale
implementation Deps.mozilla_ui_colors
implementation Deps.mozilla_ui_icons
implementation Deps.mozilla_lib_publicsuffixlist
implementation Deps.mozilla_ui_widgets
implementation Deps.mozilla_ui_tabcounter
implementation libs.mozilla.ui.colors
implementation libs.mozilla.ui.icons
implementation libs.mozilla.lib.publicsuffixlist
implementation libs.mozilla.ui.widgets
implementation libs.mozilla.ui.tabcounter
implementation Deps.mozilla_lib_crash
implementation Deps.lib_crash_sentry
implementation Deps.mozilla_lib_state
implementation Deps.mozilla_lib_dataprotect
debugImplementation Deps.leakcanary
implementation libs.mozilla.lib.crash
// implementation libs.lib.crash.sentry
implementation libs.mozilla.lib.push.firebase
implementation libs.mozilla.lib.state
implementation libs.mozilla.lib.dataprotect
debugImplementation libs.leakcanary
implementation Deps.androidx_compose_ui
implementation Deps.androidx_compose_ui_tooling
implementation Deps.androidx_compose_foundation
implementation Deps.androidx_compose_material
implementation Deps.androidx_compose_paging
implementation Deps.androidx_legacy
implementation Deps.androidx_biometric
implementation Deps.androidx_paging
implementation Deps.androidx_preference
implementation Deps.androidx_fragment
implementation Deps.androidx_navigation_fragment
implementation Deps.androidx_navigation_ui
implementation Deps.androidx_recyclerview
implementation Deps.androidx_lifecycle_common
implementation Deps.androidx_lifecycle_livedata
implementation Deps.androidx_lifecycle_process
implementation Deps.androidx_lifecycle_runtime
implementation Deps.androidx_lifecycle_viewmodel
implementation Deps.androidx_core
implementation Deps.androidx_core_ktx
implementation Deps.androidx_transition
implementation Deps.androidx_work_ktx
implementation Deps.androidx_datastore
implementation Deps.google_material
implementation libs.androidx.compose.ui
implementation libs.androidx.compose.ui.tooling
implementation libs.androidx.compose.foundation
implementation libs.androidx.compose.material
implementation libs.androidx.compose.paging
implementation libs.androidx.legacy
implementation libs.androidx.biometric
implementation libs.androidx.paging
implementation libs.androidx.preference
implementation libs.androidx.fragment
implementation libs.androidx.navigation.fragment
implementation libs.androidx.navigation.ui
implementation libs.androidx.recyclerview
implementation libs.androidx.lifecycle.common
implementation libs.androidx.lifecycle.livedata
implementation libs.androidx.lifecycle.process
implementation libs.androidx.lifecycle.runtime
implementation libs.androidx.lifecycle.viewmodel
implementation libs.androidx.core
implementation libs.androidx.core.ktx
implementation libs.androidx.transition
implementation libs.androidx.work.ktx
implementation libs.androidx.datastore
implementation libs.google.material
androidTestImplementation Deps.uiautomator
androidTestImplementation libs.uiautomator
androidTestImplementation "tools.fastlane:screengrab:2.0.0"
// This Falcon version is added to maven central now required for Screengrab
implementation 'com.jraska:falcon:2.2.0'
androidTestImplementation Deps.androidx_compose_ui_test
androidTestImplementation libs.androidx.compose.ui.test.manifest
androidTestImplementation Deps.espresso_core, {
androidTestImplementation libs.espresso.core, {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestImplementation(Deps.espresso_contrib) {
androidTestImplementation libs.espresso.contrib, {
exclude module: 'appcompat-v7'
exclude module: 'support-v4'
exclude module: 'support-annotations'
@ -452,37 +486,40 @@ dependencies {
exclude module: 'protobuf-lite'
}
androidTestImplementation Deps.androidx_test_core
androidTestImplementation Deps.espresso_idling_resources
androidTestImplementation Deps.espresso_intents
androidTestImplementation libs.androidx.test.core
androidTestImplementation libs.espresso.idling.resources
androidTestImplementation libs.espresso.intents
androidTestImplementation Deps.tools_test_runner
androidTestImplementation Deps.tools_test_rules
androidTestUtil Deps.orchestrator
androidTestImplementation Deps.espresso_core, {
androidTestImplementation libs.tools.test.runner
androidTestImplementation libs.tools.test.rules
androidTestUtil libs.orchestrator
androidTestImplementation libs.espresso.core, {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestImplementation Deps.androidx_junit
androidTestImplementation Deps.androidx_test_extensions
androidTestImplementation Deps.androidx_work_testing
androidTestImplementation Deps.androidx_benchmark_junit4
androidTestImplementation Deps.mockwebserver
testImplementation Deps.mozilla_support_test
testImplementation Deps.mozilla_support_test_libstate
testImplementation Deps.androidx_junit
testImplementation Deps.androidx_test_extensions
testImplementation Deps.androidx_work_testing
testImplementation (Deps.robolectric) {
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.androidx.test.extensions
androidTestImplementation libs.androidx.work.testing
androidTestImplementation libs.androidx.benchmark.junit4
androidTestImplementation libs.mockwebserver
androidTestImplementation libs.androidx.compose.ui.test
testImplementation libs.mozilla.support.test
testImplementation libs.mozilla.support.test.libstate
testImplementation libs.androidx.junit
testImplementation libs.androidx.test.extensions
testImplementation libs.androidx.work.testing
testImplementation (libs.robolectric) {
exclude group: 'org.apache.maven'
}
testImplementation 'org.apache.maven:maven-ant-tasks:2.1.3'
implementation Deps.mozilla_support_rusthttp
implementation libs.mozilla.support.rusthttp
testImplementation Deps.mockk
testImplementation libs.mockk
lintChecks project(":mozilla-lint-rules")
coreLibraryDesugaring libs.desugar
}
if (project.hasProperty("coverage")) {
@ -519,14 +556,6 @@ if (project.hasProperty("coverage")) {
]))
}
}
android {
buildTypes {
debug {
testCoverageEnabled true
}
}
}
}
// -------------------------------------------------------------------------------------------------

View File

@ -200,7 +200,7 @@ fun editBookmarkFolder() = onView(withText(R.string.bookmark_menu_edit_button)).
fun deleteBookmarkFolder() = onView(withText(R.string.bookmark_menu_delete_button)).click()
fun tapOnTabCounter() = onView(withId(R.id.counter_text)).click()
fun tapOnTabCounter() = onView(withId(mozilla.components.ui.tabcounter.R.id.counter_text)).click()
fun settingsAccountPreferences() = onView(withText(R.string.preferences_sync_2)).click()

View File

@ -21,11 +21,11 @@ import net.waterfox.android.ui.robots.navigationToolbar
* Tests that verify errors encountered while browsing websites: unsafe pages, connection errors, etc
*/
class BrowsingErrorPagesTest {
private val malwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_malware_uri_title)
private val phishingWarning = getStringResource(R.string.mozac_browser_errorpages_safe_phishing_uri_title)
private val malwareWarning = getStringResource(mozilla.components.browser.errorpages.R.string.mozac_browser_errorpages_safe_browsing_malware_uri_title)
private val phishingWarning = getStringResource(mozilla.components.browser.errorpages.R.string.mozac_browser_errorpages_safe_phishing_uri_title)
private val unwantedSoftwareWarning =
getStringResource(R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title)
private val harmfulSiteWarning = getStringResource(R.string.mozac_browser_errorpages_safe_harmful_uri_title)
getStringResource(mozilla.components.browser.errorpages.R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title)
private val harmfulSiteWarning = getStringResource(mozilla.components.browser.errorpages.R.string.mozac_browser_errorpages_safe_harmful_uri_title)
private val featureSettingsHelper = FeatureSettingsHelper()
@get: Rule

View File

@ -113,7 +113,7 @@ class NoNetworkAccessStartupTests {
verifyUrl(
"waterfox.net",
"$packageName:id/mozac_browser_toolbar_url_view",
R.id.mozac_browser_toolbar_url_view
mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_url_view
)
}
}

View File

@ -76,7 +76,7 @@ class ReaderViewTest {
}
readerViewNotification = ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
activityIntentTestRule.activity.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE
)
@ -119,7 +119,7 @@ class ReaderViewTest {
}
readerViewNotification = ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
activityIntentTestRule.activity.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE
)
@ -157,7 +157,7 @@ class ReaderViewTest {
}
readerViewNotification = ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
activityIntentTestRule.activity.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE
)
@ -197,7 +197,7 @@ class ReaderViewTest {
}
readerViewNotification = ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
activityIntentTestRule.activity.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE
)
@ -243,7 +243,7 @@ class ReaderViewTest {
}
readerViewNotification = ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
activityIntentTestRule.activity.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE
)

View File

@ -762,7 +762,7 @@ class SmokeTest {
}
readerViewNotification = ViewVisibilityIdlingResource(
activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
activityTestRule.activity.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE
)

View File

@ -971,7 +971,7 @@ fun browserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
fun navURLBar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
fun searchBar() = onView(withId(R.id.mozac_browser_toolbar_url_view))
fun searchBar() = onView(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_url_view))
fun homeScreenButton() = onView(withContentDescription(R.string.browser_toolbar_home))
@ -985,7 +985,7 @@ private fun assertNavURLBar() = assertTrue(navURLBar().waitForExists(waitingTime
private fun assertNavURLBarHidden() = assertTrue(navURLBar().waitUntilGone(waitingTime))
private fun assertSecureConnectionLockIcon() {
onView(withId(R.id.mozac_browser_toolbar_security_indicator))
onView(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_site_info_indicator))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}

View File

@ -67,11 +67,11 @@ class FindInPageRobot {
}
}
private fun findInPageQuery() = onView(withId(R.id.find_in_page_query_text))
private fun findInPageResult() = onView(withId(R.id.find_in_page_result_text))
private fun findInPageNextButton() = onView(withId(R.id.find_in_page_next_btn))
private fun findInPagePrevButton() = onView(withId(R.id.find_in_page_prev_btn))
private fun findInPageCloseButton() = onView(withId(R.id.find_in_page_close_btn))
private fun findInPageQuery() = onView(withId(mozilla.components.feature.findinpage.R.id.find_in_page_query_text))
private fun findInPageResult() = onView(withId(mozilla.components.feature.findinpage.R.id.find_in_page_result_text))
private fun findInPageNextButton() = onView(withId(mozilla.components.feature.findinpage.R.id.find_in_page_next_btn))
private fun findInPagePrevButton() = onView(withId(mozilla.components.feature.findinpage.R.id.find_in_page_prev_btn))
private fun findInPageCloseButton() = onView(withId(mozilla.components.feature.findinpage.R.id.find_in_page_close_btn))
private fun assertFindInPageQuery() = findInPageQuery()
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))

View File

@ -523,7 +523,7 @@ private fun assertHomeComponent() =
onView(ViewMatchers.withResourceName("sessionControlRecyclerView"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertNoTabsOpened() = onView(withId(R.id.counter_text)).check(matches(withText("0")))
private fun assertNoTabsOpened() = onView(withId(mozilla.components.ui.tabcounter.R.id.counter_text)).check(matches(withText("0")))
private fun threeDotButton() = onView(allOf(withId(R.id.menuButton)))
@ -778,7 +778,7 @@ private fun startBrowsingButton(): UiObject {
val deleteFromHistory =
onView(
allOf(
withId(R.id.simple_text),
withId(mozilla.components.browser.menu2.R.id.simple_text),
withText(R.string.delete_from_history)
)
).inRoot(RootMatchers.isPlatformPopup())

View File

@ -185,7 +185,7 @@ class NavigationToolbarRobot {
fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition {
mDevice.waitForIdle(waitingTime)
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.perform(
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(
@ -202,7 +202,7 @@ class NavigationToolbarRobot {
fun openTabFromShortcutsMenu(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
mDevice.waitForIdle(waitingTime)
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.perform(
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(
@ -219,7 +219,7 @@ class NavigationToolbarRobot {
fun openNewPrivateTabFromShortcutsMenu(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
mDevice.waitForIdle(waitingTime)
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.perform(
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(
@ -271,7 +271,7 @@ private fun assertNoHistoryBookmarks() {
}
private fun assertTabButtonShortcutMenuItems() {
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.check(matches(hasDescendant(withText("Close tab"))))
.check(matches(hasDescendant(withText("New private tab"))))
.check(matches(hasDescendant(withText("New tab"))))
@ -280,14 +280,14 @@ private fun assertTabButtonShortcutMenuItems() {
private fun urlBar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
private fun awesomeBar() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"))
private fun threeDotButton() = onView(withId(R.id.mozac_browser_toolbar_menu))
private fun threeDotButton() = onView(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_menu))
private fun tabTrayButton() = onView(withId(R.id.tab_button))
private fun fillLinkButton() = onView(withId(R.id.fill_link_from_clipboard))
private fun clearAddressBar() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_clear_view"))
private fun goBackButton() = mDevice.pressBack()
private fun readerViewToggle() =
onView(withParent(withId(R.id.mozac_browser_toolbar_page_actions)))
onView(withParent(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions)))
private fun assertReaderViewDetected(visible: Boolean) {
mDevice.findObject(
@ -298,7 +298,7 @@ private fun assertReaderViewDetected(visible: Boolean) {
onView(
allOf(
withParent(withId(R.id.mozac_browser_toolbar_page_actions)),
withParent(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions)),
withContentDescription("Reader view")
)
).check(
@ -316,7 +316,7 @@ private fun assertCloseReaderViewDetected(visible: Boolean) {
onView(
allOf(
withParent(withId(R.id.mozac_browser_toolbar_page_actions)),
withParent(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_page_actions)),
withContentDescription("Close reader view")
)
).check(

View File

@ -92,7 +92,7 @@ class ReaderViewRobot {
fun toggleSansSerif(interact: ReaderViewRobot.() -> Unit): Transition {
fun sansSerifButton() =
onView(
withId(R.id.mozac_feature_readerview_font_sans_serif)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_sans_serif)
)
sansSerifButton().click()
@ -104,7 +104,7 @@ class ReaderViewRobot {
fun toggleSerif(interact: ReaderViewRobot.() -> Unit): Transition {
fun serifButton() =
onView(
withId(R.id.mozac_feature_readerview_font_serif)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_serif)
)
serifButton().click()
@ -116,7 +116,7 @@ class ReaderViewRobot {
fun toggleFontSizeDecrease(interact: ReaderViewRobot.() -> Unit): Transition {
fun fontSizeDecrease() =
onView(
withId(R.id.mozac_feature_readerview_font_size_decrease)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_size_decrease)
)
fontSizeDecrease().click()
@ -128,7 +128,7 @@ class ReaderViewRobot {
fun toggleFontSizeIncrease(interact: ReaderViewRobot.() -> Unit): Transition {
fun fontSizeIncrease() =
onView(
withId(R.id.mozac_feature_readerview_font_size_increase)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_size_increase)
)
fontSizeIncrease().click()
@ -140,7 +140,7 @@ class ReaderViewRobot {
fun toggleColorSchemeChangeLight(interact: ReaderViewRobot.() -> Unit): Transition {
fun toggleLightColorSchemeButton() =
onView(
withId(R.id.mozac_feature_readerview_color_light)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_light)
)
toggleLightColorSchemeButton().click()
@ -152,7 +152,7 @@ class ReaderViewRobot {
fun toggleColorSchemeChangeDark(interact: ReaderViewRobot.() -> Unit): Transition {
fun toggleDarkColorSchemeButton() =
onView(
withId(R.id.mozac_feature_readerview_color_dark)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_dark)
)
toggleDarkColorSchemeButton().click()
@ -164,7 +164,7 @@ class ReaderViewRobot {
fun toggleColorSchemeChangeSepia(interact: ReaderViewRobot.() -> Unit): Transition {
fun toggleSepiaColorSchemeButton() =
onView(
withId(R.id.mozac_feature_readerview_color_sepia)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_sepia)
)
toggleSepiaColorSchemeButton().click()
@ -182,63 +182,63 @@ fun readerViewRobot(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Trans
private fun assertAppearanceFontGroup(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_font_group)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_group)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceFontSansSerif(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_font_sans_serif)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_sans_serif)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceFontSerif(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_font_serif)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_serif)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceFontDecrease(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_font_size_decrease)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_size_decrease)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceFontIncrease(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_font_size_increase)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_size_increase)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceColorDark(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_color_dark)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_dark)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceColorLight(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_color_light)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_light)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceColorSepia(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_color_sepia)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_sepia)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)
private fun assertAppearanceColorGroup(visible: Boolean) =
onView(
withId(R.id.mozac_feature_readerview_color_scheme_group)
withId(mozilla.components.feature.readerview.R.id.mozac_feature_readerview_color_scheme_group)
).check(
matches(withEffectiveVisibility(visibleOrGone(visible)))
)

View File

@ -392,7 +392,7 @@ private fun assertKeyboardVisibility(isExpectedToBeVisible: Boolean): () -> Unit
}
private fun ComposeTestRule.assertSearchEngineList() {
onView(withId(R.id.mozac_browser_toolbar_edit_icon)).click()
onView(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_edit_icon)).click()
onNodeWithText("Google")
.assertExists()
@ -445,7 +445,7 @@ private fun assertEngineListShortcutContains(rule: ComposeTestRule, searchEngine
}
private fun ComposeTestRule.selectDefaultSearchEngine(searchEngine: String) {
onView(withId(R.id.mozac_browser_toolbar_edit_icon)).click()
onView(withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_edit_icon)).click()
onNodeWithText(searchEngine)
.assertExists()
@ -470,7 +470,7 @@ private fun assertPastedToolbarText(expectedText: String) {
onView(
allOf(
withSubstring(expectedText),
withId(R.id.mozac_browser_toolbar_edit_url_view)
withId(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_edit_url_view)
)
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}

View File

@ -131,7 +131,7 @@ private fun assertSupport(rule: ComposeTestRule) {
TestHelper.verifyUrl(
"waterfox.net/docs/support",
"$packageName:id/mozac_browser_toolbar_url_view",
R.id.mozac_browser_toolbar_url_view
mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_url_view
)
}
@ -165,7 +165,7 @@ private fun assertPrivacyNotice(rule: ComposeTestRule) {
TestHelper.verifyUrl(
"waterfox.net/docs/policies/privacy",
"$packageName:id/mozac_browser_toolbar_url_view",
R.id.mozac_browser_toolbar_url_view
mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_url_view
)
}
@ -180,7 +180,7 @@ private fun assertKnowYourRights(rule: ComposeTestRule) {
TestHelper.verifyUrl(
SupportUtils.SumoTopic.YOUR_RIGHTS.topicStr,
"$packageName:id/mozac_browser_toolbar_url_view",
R.id.mozac_browser_toolbar_url_view
mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_url_view
)
}
@ -195,7 +195,7 @@ private fun assertLicensingInformation(rule: ComposeTestRule) {
TestHelper.verifyUrl(
"about:license",
"$packageName:id/mozac_browser_toolbar_url_view",
R.id.mozac_browser_toolbar_url_view
mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_url_view
)
}

View File

@ -107,15 +107,15 @@ private fun assertSliderBar() {
// onView(withId(net.waterfox.android.R.id.sampleText))
// .check(matches(withText("This is sample text. It is here to show how text will appear when you increase or decrease the size with this setting.")))
onView(withId(net.waterfox.android.R.id.seekbar_value))
onView(withId(androidx.preference.R.id.seekbar_value))
.check(matches(withText("100%")))
onView(withId(net.waterfox.android.R.id.seekbar))
onView(withId(androidx.preference.R.id.seekbar))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun adjustTextSizeSlider(seekBarPercentage: Int) {
onView(withId(net.waterfox.android.R.id.seekbar))
onView(withId(androidx.preference.R.id.seekbar))
.perform(SeekBarChangeProgressViewAction(seekBarPercentage))
}
@ -134,9 +134,9 @@ private fun assertMenuItemsAreDisabled() {
// onView(withId(net.waterfox.android.R.id.sampleText)).assertIsEnabled(false)
onView(withId(net.waterfox.android.R.id.seekbar_value)).assertIsEnabled(false)
onView(withId(androidx.preference.R.id.seekbar_value)).assertIsEnabled(false)
onView(withId(net.waterfox.android.R.id.seekbar)).assertIsEnabled(false)
onView(withId(androidx.preference.R.id.seekbar)).assertIsEnabled(false)
}
private fun goBackButton() =

View File

@ -124,7 +124,7 @@ class SettingsSubMenuAddonsManagerRobot {
mDevice.findObject(UiSelector().text("Allow in private browsing"))
.waitForExists(waitingTimeLong)
)
onView(withId(R.id.allow_in_private_browsing)).click()
onView(withId(mozilla.components.feature.addons.R.id.allow_in_private_browsing)).click()
}
fun installAddon(addonName: String) {
@ -154,10 +154,10 @@ class SettingsSubMenuAddonsManagerRobot {
onView(
allOf(
withId(R.id.add_on_item),
withId(mozilla.components.feature.addons.R.id.add_on_item),
hasDescendant(
allOf(
withId(R.id.add_on_name),
withId(mozilla.components.feature.addons.R.id.add_on_name),
withText(addonName)
)
)
@ -173,8 +173,8 @@ class SettingsSubMenuAddonsManagerRobot {
private fun installButtonForAddon(addonName: String) =
onView(
allOf(
withContentDescription(R.string.mozac_feature_addons_install_addon_content_description_2),
isDescendantOfA(withId(R.id.add_on_item)),
withContentDescription(mozilla.components.feature.addons.R.string.mozac_feature_addons_install_addon_content_description_2),
isDescendantOfA(withId(mozilla.components.feature.addons.R.id.add_on_item)),
hasSibling(hasDescendant(withText(addonName)))
)
)
@ -196,10 +196,10 @@ class SettingsSubMenuAddonsManagerRobot {
)
.check(matches(isCompletelyDisplayed()))
onView(allOf(withId(R.id.allow_button), withText("Add")))
onView(allOf(withId(mozilla.components.feature.sitepermissions.R.id.allow_button), withText("Add")))
.check(matches(isCompletelyDisplayed()))
onView(allOf(withId(R.id.deny_button), withText("Cancel")))
onView(allOf(withId(mozilla.components.feature.downloads.R.id.deny_button), withText("Cancel")))
.check(matches(isCompletelyDisplayed()))
}
@ -207,20 +207,20 @@ class SettingsSubMenuAddonsManagerRobot {
onView(
allOf(
withId(R.id.add_button),
isDescendantOfA(withId(R.id.add_on_item)),
isDescendantOfA(withId(mozilla.components.feature.addons.R.id.add_on_item)),
hasSibling(hasDescendant(withText(addonName)))
)
).check(matches(withEffectiveVisibility(Visibility.GONE)))
}
private fun cancelInstall() {
onView(allOf(withId(R.id.deny_button), withText("Cancel")))
onView(allOf(withId(mozilla.components.feature.downloads.R.id.deny_button), withText("Cancel")))
.check(matches(isCompletelyDisplayed()))
.perform(click())
}
private fun allowPermissionToInstall() {
onView(allOf(withId(R.id.allow_button), withText("Add")))
onView(allOf(withId(mozilla.components.feature.sitepermissions.R.id.allow_button), withText("Add")))
.check(matches(isCompletelyDisplayed()))
.perform(click())
}
@ -243,11 +243,11 @@ class SettingsSubMenuAddonsManagerRobot {
onView(
allOf(
isAssignableFrom(RelativeLayout::class.java),
withId(R.id.add_on_item),
hasDescendant(allOf(withId(R.id.add_on_icon), isCompletelyDisplayed())),
withId(mozilla.components.feature.addons.R.id.add_on_item),
hasDescendant(allOf(withId(mozilla.components.feature.addons.R.id.add_on_icon), isCompletelyDisplayed())),
hasDescendant(
allOf(
withId(R.id.details_container),
withId(mozilla.components.feature.addons.R.id.details_container),
hasDescendant(withText("uBlock Origin")),
hasDescendant(withText("Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.")),
hasDescendant(withId(R.id.rating)),
@ -269,7 +269,7 @@ class SettingsSubMenuAddonsManagerRobot {
hasSibling(
hasDescendant(
allOf(
withId(R.id.add_on_name),
withId(mozilla.components.feature.addons.R.id.add_on_name),
withText(addonName)
)
)

View File

@ -83,7 +83,7 @@ class SitePermissionsRobot {
}
fun selectRememberPermissionDecision() {
onView(withId(R.id.do_not_ask_again))
onView(withId(mozilla.components.feature.sitepermissions.R.id.do_not_ask_again))
.check(matches(isDisplayed()))
.click()
}

View File

@ -613,12 +613,12 @@ private fun tabItem(title: String) =
private fun tabsCounter() = onView(withId(R.id.tab_button))
private fun tabsTrayCounterBox() = onView(withId(R.id.counter_box))
private fun tabsTrayCounterBox() = onView(withId(mozilla.components.ui.tabcounter.R.id.counter_box))
private fun tabsSettingsButton() =
onView(
allOf(
withId(R.id.simple_text),
withId(mozilla.components.browser.menu2.R.id.simple_text),
withText(R.string.tab_tray_menu_tab_settings)
)
)
@ -626,7 +626,7 @@ private fun tabsSettingsButton() =
private fun recentlyClosedTabsButton() =
onView(
allOf(
withId(R.id.simple_text),
withId(mozilla.components.browser.menu2.R.id.simple_text),
withText(R.string.tab_tray_menu_recently_closed)
)
)

View File

@ -61,7 +61,7 @@ class ThreeDotMenuMainRobot {
fun verifyReaderViewAppearance(visible: Boolean) = assertReaderViewAppearanceButton(visible)
fun expandMenu() {
onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeUp())
onView(withId(mozilla.components.browser.menu.R.id.mozac_browser_menu_menuView)).perform(swipeUp())
}
fun verifyShareTabButton() = assertShareTabButton()
@ -399,7 +399,7 @@ class ThreeDotMenuMainRobot {
}
}
private fun threeDotMenuRecyclerView() =
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
private fun threeDotMenuRecyclerViewExists() {
threeDotMenuRecyclerView().check(matches(isDisplayed()))
@ -421,7 +421,7 @@ private fun assertCustomizeHomeButton() =
private fun addOnsButton() = onView(allOf(withText("Add-ons")))
private fun assertAddOnsButton() {
onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown())
onView(withId(mozilla.components.browser.menu.R.id.mozac_browser_menu_menuView)).perform(swipeDown())
addOnsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
@ -447,7 +447,7 @@ private fun backButton() = mDevice.findObject(UiSelector().description("Back"))
private fun addBookmarkButton() = onView(allOf(withId(R.id.checkbox), withText("Add")))
private fun assertAddBookmarkButton() {
onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeUp())
onView(withId(mozilla.components.browser.menu.R.id.mozac_browser_menu_menuView)).perform(swipeUp())
addBookmarkButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
@ -525,7 +525,7 @@ private fun removeFromShortcutsButton() =
onView(allOf(withText(R.string.browser_menu_remove_from_shortcuts)))
private fun assertAddToTopSitesButton() {
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(R.string.browser_menu_add_to_shortcuts))
@ -535,7 +535,7 @@ private fun assertAddToTopSitesButton() {
private fun assertRemoveFromShortcutsButton() {
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(R.string.browser_menu_settings))
@ -547,7 +547,7 @@ private fun addToMobileHomeButton() =
onView(allOf(withText(R.string.browser_menu_add_to_homescreen)))
private fun assertAddToMobileHome() {
onView(withId(R.id.mozac_browser_menu_recyclerView))
onView(withId(mozilla.components.browser.menu2.R.id.mozac_browser_menu_recyclerView))
.perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(R.string.browser_menu_add_to_homescreen))
@ -573,12 +573,12 @@ private fun openInAppButton() =
private fun downloadsButton() = onView(withText(R.string.library_downloads))
private fun assertDownloadsButton() {
onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown())
onView(withId(mozilla.components.browser.menu.R.id.mozac_browser_menu_menuView)).perform(swipeDown())
downloadsButton().check(matches(isDisplayed()))
}
private fun clickAddonsManagerButton() {
onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown())
onView(withId(mozilla.components.browser.menu.R.id.mozac_browser_menu_menuView)).perform(swipeDown())
addOnsButton().check(matches(isCompletelyDisplayed())).click()
}

View File

@ -3,5 +3,5 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<resources>
<color name="ic_launcher_background">@color/photonInk20</color>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@ -44,7 +44,6 @@
<application
android:name=".WaterfoxApplication"
android:allowBackup="false"
android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="LeOSium"
android:roundIcon="@mipmap/ic_launcher"
@ -333,6 +332,23 @@
android:value="This foreground service allows users to easily remove private tabs from the notification" />
</service>
<service
android:name=".push.FirebasePushService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="true" />
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />
<meta-data
android:name="firebase_analytics_collection_deactivated"
android:value="true" />
<!-- Removes the default Workmanager initialization so that we can use on-demand initializer. -->
<provider
android:name="androidx.startup.InitializationProvider"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 143 KiB

View File

@ -32,7 +32,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.action.MediaSessionAction
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
@ -55,6 +54,7 @@ import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.android.arch.lifecycle.addObservers
import mozilla.components.support.ktx.android.content.call
import mozilla.components.support.ktx.android.content.email
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.content.share
import mozilla.components.support.ktx.kotlin.isUrl
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
@ -228,6 +228,23 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
// Enable edge-to-edge display for modern Android versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false)
// Ensure navigation bar color matches theme
window.navigationBarColor = getColorFromAttr(R.attr.layer1)
} else
@Suppress("DEPRECATION")
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
window.navigationBarColor = getColorFromAttr(R.attr.layer1)
}
ProfilerMarkers.addListenerForOnGlobalLayout(components.core.engine, this, binding.root)
// Must be after we set the content view

View File

@ -17,8 +17,8 @@ import androidx.core.content.getSystemService
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.Configuration.Builder
import androidx.work.Configuration.Provider
import coil.Coil
import coil.ImageLoader
import coil3.SingletonImageLoader
import coil3.ImageLoader
import kotlinx.coroutines.*
import mozilla.appservices.Megazord
import mozilla.components.browser.state.action.SystemAction
@ -62,6 +62,8 @@ import net.waterfox.android.session.VisibilityLifecycleCallback
import net.waterfox.android.utils.BrowsersCache
import net.waterfox.android.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
import java.util.concurrent.TimeUnit
import mozilla.appservices.init_rust_components.initialize as InitializeRustComponents
/**
*The main application class for Waterfox. Records data to measure initialization performance.
@ -115,11 +117,10 @@ open class WaterfoxApplication : LocaleAwareApplication(), Provider {
ProfilerMarkerFactProcessor.create { components.core.engine.profiler }.register()
// This is a workaround for https://github.com/coil-kt/coil/issues/383
Coil.setImageLoader(
ImageLoader.Builder(this)
.addLastModifiedToFileCacheKey(false)
SingletonImageLoader.setSafe {
ImageLoader.Builder(this@WaterfoxApplication)
.build()
)
}
run {
// Make sure the engine is initialized and ready to use.
@ -136,7 +137,7 @@ open class WaterfoxApplication : LocaleAwareApplication(), Provider {
val megazordSetup = finishSetupMegazord()
setDayNightTheme()
components.strictMode.enableStrictMode(true)
//components.strictMode.enableStrictMode(true)
warmBrowsersCache()
initializeWebExtensionSupport()
@ -160,7 +161,7 @@ open class WaterfoxApplication : LocaleAwareApplication(), Provider {
}
setupLeakCanary()
setupPush()
visibilityLifecycleCallback = VisibilityLifecycleCallback(getSystemService())
registerActivityLifecycleCallbacks(visibilityLifecycleCallback)
@ -292,7 +293,25 @@ open class WaterfoxApplication : LocaleAwareApplication(), Provider {
// no-op, LeakCanary is disabled by default
}
private fun setupPush() {
// Sets the PushFeature as the singleton instance for push messages to go to.
// We need the push feature setup here to deliver messages in the case where the service
// starts up the app first.
components.push.feature?.let {
Logger.info("AutoPushFeature is configured, initializing it...")
// Install the AutoPush singleton to receive messages.
PushProcessor.install(it)
WebPushEngineIntegration(components.core.engine, it).start()
// Perform a one-time initialization of the account manager if a message is received.
PushFxaIntegration(it, lazy { components.backgroundServices.accountManager }).launch()
// Initialize the service. This could potentially be done in a coroutine in the future.
it.initialize()
}
}
private fun setupCrashReporting() {
components.analytics.crashReporter.install(this)
@ -313,6 +332,9 @@ open class WaterfoxApplication : LocaleAwareApplication(), Provider {
* thread, early in the app startup sequence.
*/
private fun beginSetupMegazord() {
// Rust components must be initialized at the very beginning, before any other Rust call, ...
InitializeRustComponents()
// Note: Megazord.init() must be called as soon as possible ...
Megazord.init()

View File

@ -65,11 +65,11 @@ class AddonDetailsBindingDelegate(
addon.rating?.let { rating ->
val resources = binding.root.resources
val ratingContentDescription =
resources.getString(R.string.mozac_feature_addons_rating_content_description_2)
resources.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_rating_content_description_2)
binding.ratingLabel.contentDescription = String.format(ratingContentDescription, rating.average)
binding.ratingView.rating = rating.average
val reviewCount = resources.getString(R.string.mozac_feature_addons_user_rating_count_2)
val reviewCount = resources.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_user_rating_count_2)
binding.reviewCount.contentDescription = String.format(reviewCount, numberFormatter.format(rating.reviews))
binding.reviewCount.text = numberFormatter.format(rating.reviews)

View File

@ -119,7 +119,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
binding?.let {
showSnackBar(
it.root,
getString(R.string.mozac_feature_addons_failed_to_query_extensions),
getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_query_extensions),
)
}
binding?.addOnsProgressBar?.isVisible = false

View File

@ -130,7 +130,7 @@ class InstalledAddonDetailsFragment : Fragment() {
runIfFragmentIsAttached {
showSnackBar(
binding.root,
getString(R.string.mozac_feature_addons_failed_to_query_extensions),
getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_query_extensions),
)
findNavController().popBackStack()
}
@ -189,7 +189,7 @@ class InstalledAddonDetailsFragment : Fragment() {
showSnackBar(
binding.root,
getString(
R.string.mozac_feature_addons_successfully_enabled,
mozilla.components.feature.addons.R.string.mozac_feature_addons_successfully_enabled,
addon.translateName(it),
),
)
@ -205,7 +205,7 @@ class InstalledAddonDetailsFragment : Fragment() {
showSnackBar(
binding.root,
getString(
R.string.mozac_feature_addons_failed_to_enable,
mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_enable,
addon.translateName(it),
),
)
@ -227,7 +227,7 @@ class InstalledAddonDetailsFragment : Fragment() {
showSnackBar(
binding.root,
getString(
R.string.mozac_feature_addons_successfully_disabled,
mozilla.components.feature.addons.R.string.mozac_feature_addons_successfully_disabled,
addon.translateName(it),
),
)
@ -243,7 +243,7 @@ class InstalledAddonDetailsFragment : Fragment() {
showSnackBar(
binding.root,
getString(
R.string.mozac_feature_addons_failed_to_disable,
mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_disable,
addon.translateName(it),
),
)
@ -285,7 +285,7 @@ class InstalledAddonDetailsFragment : Fragment() {
if (addon.incognito == Addon.Incognito.NOT_ALLOWED) {
switch.isChecked = false
switch.isEnabled = false
switch.text = requireContext().getString(R.string.mozac_feature_addons_not_allowed_in_private_browsing)
switch.text = requireContext().getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_not_allowed_in_private_browsing)
return
}
@ -392,7 +392,7 @@ class InstalledAddonDetailsFragment : Fragment() {
showSnackBar(
binding.root,
getString(
R.string.mozac_feature_addons_successfully_uninstalled,
mozilla.components.feature.addons.R.string.mozac_feature_addons_successfully_uninstalled,
addon.translateName(it),
),
)
@ -407,7 +407,7 @@ class InstalledAddonDetailsFragment : Fragment() {
showSnackBar(
binding.root,
getString(
R.string.mozac_feature_addons_failed_to_uninstall,
mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_uninstall,
addon.translateName(it),
),
)

View File

@ -55,12 +55,12 @@ class NotYetSupportedAddonFragment :
override fun onResume() {
super.onResume()
showToolbar(getString(R.string.mozac_feature_addons_unavailable_section))
showToolbar(getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_unavailable_section))
}
override fun onUninstallError(addonId: String, throwable: Throwable) {
this@NotYetSupportedAddonFragment.view?.let { view ->
showSnackBar(view, getString(R.string.mozac_feature_addons_failed_to_remove, ""))
showSnackBar(view, getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_remove, ""))
}
if (unsupportedAddonsAdapter?.itemCount == 0) {
@ -70,7 +70,7 @@ class NotYetSupportedAddonFragment :
override fun onUninstallSuccess() {
this@NotYetSupportedAddonFragment.view?.let { view ->
showSnackBar(view, getString(R.string.mozac_feature_addons_successfully_removed, ""))
showSnackBar(view, getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_successfully_removed, ""))
}
}
}

View File

@ -416,7 +416,7 @@ abstract class BaseBrowserFragment :
view = view
)
browserToolbarView.view.display.setOnSiteSecurityClickedListener {
browserToolbarView.view.display.setOnSiteInfoClickedListener {
showQuickSettingsDialog()
}
@ -720,7 +720,7 @@ abstract class BaseBrowserFragment :
gravity = getAppropriateLayoutGravity(),
shouldWidthMatchParent = true,
positiveButtonBackgroundColor = accentHighContrastColor,
positiveButtonTextColor = R.color.photonWhite
positiveButtonTextColor = mozilla.components.ui.colors.R.color.photonWhite
),
sessionId = customTabSessionId,
onNeedToRequestPermissions = { permissions ->

View File

@ -69,7 +69,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val homeAction = BrowserToolbar.Button(
imageDrawable = AppCompatResources.getDrawable(
context,
R.drawable.mozac_ic_home_24
mozilla.components.ui.icons.R.drawable.mozac_ic_home_24
)!!,
contentDescription = context.getString(R.string.browser_toolbar_home),
iconTintColorResource = ThemeManager.resolveAttribute(R.attr.textPrimary, context),
@ -84,7 +84,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val backAction = BrowserToolbar.TwoStateButton(
primaryImage = AppCompatResources.getDrawable(
context,
R.drawable.mozac_ic_back_24
mozilla.components.ui.icons.R.drawable.mozac_ic_back_24
)!!,
primaryContentDescription = context.getString(R.string.browser_menu_back),
primaryImageTintResource = enableTint,
@ -106,7 +106,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val forwardAction = BrowserToolbar.TwoStateButton(
primaryImage = AppCompatResources.getDrawable(
context,
R.drawable.mozac_ic_forward_24
mozilla.components.ui.icons.R.drawable.mozac_ic_forward_24
)!!,
primaryContentDescription = context.getString(R.string.browser_menu_forward),
primaryImageTintResource = enableTint,
@ -128,7 +128,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val refreshAction = BrowserToolbar.TwoStateButton(
primaryImage = AppCompatResources.getDrawable(
context,
R.drawable.mozac_ic_arrow_clockwise_24
mozilla.components.ui.icons.R.drawable.mozac_ic_arrow_clockwise_24
)!!,
primaryContentDescription = context.getString(R.string.browser_menu_refresh),
primaryImageTintResource = enableTint,
@ -137,7 +137,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
},
secondaryImage = AppCompatResources.getDrawable(
context,
R.drawable.mozac_ic_stop
mozilla.components.ui.icons.R.drawable.mozac_ic_stop
)!!,
secondaryContentDescription = context.getString(R.string.browser_menu_stop),
disableInSecondaryState = false,

View File

@ -44,8 +44,8 @@ class TabPreview @JvmOverloads constructor(
}
// Change view properties to avoid confusing the UI tests
binding.tabButton.findViewById<View>(R.id.counter_box).id = View.NO_ID
binding.tabButton.findViewById<View>(R.id.counter_text).id = View.NO_ID
binding.tabButton.findViewById<View>(mozilla.components.ui.tabcounter.R.id.counter_box).id = View.NO_ID
binding.tabButton.findViewById<View>(mozilla.components.ui.tabcounter.R.id.counter_text).id = View.NO_ID
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {

View File

@ -21,7 +21,7 @@ import mozilla.components.browser.toolbar.BrowserToolbar
* - immediately below the toolbar (toolbar fully expanded).
*/
class DynamicInfoBannerBehavior(
context: Context?,
context: Context,
attrs: AttributeSet?
) : CoordinatorLayout.Behavior<View>(context, attrs) {
@VisibleForTesting

View File

@ -67,8 +67,8 @@ class DefaultReaderModeController(
private fun themeReaderViewControlsForPrivateMode(view: View) = with(view) {
listOf(
R.id.mozac_feature_readerview_font_size_decrease,
R.id.mozac_feature_readerview_font_size_increase,
mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_size_decrease,
mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_size_increase,
).map {
findViewById<Button>(it)
}.forEach {
@ -76,8 +76,8 @@ class DefaultReaderModeController(
}
listOf(
R.id.mozac_feature_readerview_font_serif,
R.id.mozac_feature_readerview_font_sans_serif,
mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_serif,
mozilla.components.feature.readerview.R.id.mozac_feature_readerview_font_sans_serif,
).map {
findViewById<RadioButton>(it)
}.forEach {

View File

@ -40,7 +40,7 @@ class CollectionCreationBottomBarView(
iconButton.apply {
val drawable = context.getDrawableWithTint(
R.drawable.ic_close,
ContextCompat.getColor(context, R.color.photonWhite)
ContextCompat.getColor(context, mozilla.components.ui.colors.R.color.photonWhite)
)
setImageDrawable(drawable)
contentDescription = context.getString(R.string.create_collection_close)
@ -87,7 +87,7 @@ class CollectionCreationBottomBarView(
iconButton.apply {
val drawable = context.getDrawableWithTint(
R.drawable.ic_new,
ContextCompat.getColor(context, R.color.photonWhite)
ContextCompat.getColor(context, mozilla.components.ui.colors.R.color.photonWhite)
)
setImageDrawable(drawable)
contentDescription = null

View File

@ -11,7 +11,7 @@ import android.os.Build
import mozilla.components.concept.base.crash.Breadcrumb
import mozilla.components.lib.crash.Crash
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.crash.sentry.SentryService
//import mozilla.components.lib.crash.sentry.SentryService
import mozilla.components.lib.crash.service.CrashReporterService
import net.waterfox.android.*
import net.waterfox.android.ext.components
@ -27,24 +27,8 @@ class Analytics(
val crashReporter: CrashReporter by lazyMonitored {
val services = mutableListOf<CrashReporterService>()
if (isSentryEnabled()) {
val shouldSendCaughtExceptions = Config.channel == ReleaseChannel.Release
val sentryService = SentryService(
context,
BuildConfig.SENTRY_TOKEN,
tags = mapOf(
"geckoview" to "$MOZ_APP_VERSION-$MOZ_APP_BUILDID",
"waterfox.git" to BuildConfig.GIT_HASH
),
environment = BuildConfig.BUILD_TYPE,
sendEventForNativeCrashes = false, // Do not send native crashes to Sentry
sendCaughtExceptions = shouldSendCaughtExceptions,
sentryProjectUrl = getSentryProjectUrl()
)
services.add(sentryService)
} else {
if (isSentryEnabled()) {}
else {
// At least one service needs to be added to the services list,
// so we add a No Op implementation if Sentry is disabled (like in case of debug builds).
services.add(NoOpCrashReporterService)

View File

@ -58,7 +58,7 @@ private val DEFAULT_SYNCED_TABS_COMMANDS_EXTRA_FLUSH_DELAY = 5.seconds
@Suppress("LongParameterList")
class BackgroundServices(
private val context: Context,
private val push: Push,
crashReporter: CrashReporter,
historyStorage: Lazy<PlacesHistoryStorage>,
bookmarkStorage: Lazy<PlacesBookmarksStorage>,
@ -189,7 +189,9 @@ class BackgroundServices(
accountManager.register(AccountManagerReadyObserver(accountManagerAvailableQueue))
// Enable push if it's configured.
push.feature?.let { autoPushFeature ->
FxaPushSupportFeature(context, accountManager, autoPushFeature, crashReporter)
}
SendTabFeature(accountManager) { device, tabs ->
notificationManager.showReceivedTabs(context, device, tabs)

View File

@ -60,6 +60,7 @@ class Components(private val context: Context) {
val backgroundServices by lazyMonitored {
BackgroundServices(
context,
push,
analytics.crashReporter,
core.lazyHistoryStorage,
core.lazyBookmarksStorage,
@ -155,7 +156,7 @@ class Components(private val context: Context) {
val publicSuffixList by lazyMonitored { PublicSuffixList(context) }
val clipboardHandler by lazyMonitored { ClipboardHandler(context) }
val performance by lazyMonitored { PerformanceComponent() }
val push by lazyMonitored { Push(context, analytics.crashReporter) }
val wifiConnectionMonitor by lazyMonitored { WifiConnectionMonitor(context as Application) }
val strictMode by lazyMonitored { StrictModeManager(Config, this) }

View File

@ -0,0 +1,47 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package net.waterfox.android.components
import android.content.Context
import mozilla.components.feature.push.AutoPushFeature
import mozilla.components.feature.push.PushConfig
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.support.base.log.logger.Logger
import net.waterfox.android.R
import net.waterfox.android.perf.lazyMonitored
import net.waterfox.android.push.FirebasePushService
/**
* Component group for push services. These components use services that strongly depend on
* push messaging (e.g. WebPush, SendTab).
*/
class Push(context: Context, crashReporter: CrashReporter) {
val feature by lazyMonitored {
pushConfig?.let { config ->
AutoPushFeature(
context = context,
service = pushService,
config = config,
crashReporter = crashReporter
)
}
}
private val pushConfig: PushConfig? by lazyMonitored {
val logger = Logger("PushConfig")
val projectIdKey = context.getString(R.string.pref_key_push_project_id)
val resId = context.resources.getIdentifier(projectIdKey, "string", context.packageName)
if (resId == 0) {
logger.warn("No firebase configuration found; cannot support push service.")
return@lazyMonitored null
}
logger.debug("Creating push configuration for autopush.")
val projectId = context.resources.getString(resId)
PushConfig(projectId)
}
private val pushService by lazyMonitored { FirebasePushService() }
}

View File

@ -92,7 +92,7 @@ class BrowserToolbarCFRPresenter(
CFRPopup(
text = context.getString(R.string.tcp_cfr_message),
anchor = toolbar.findViewById(
R.id.mozac_browser_toolbar_security_indicator
mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_site_info_indicator
),
properties = CFRPopupProperties(
popupAlignment = INDICATOR_CENTERED_IN_ANCHOR,

View File

@ -114,8 +114,8 @@ class BrowserToolbarView(
display.colors = display.colors.copy(
text = primaryTextColor,
securityIconSecure = primaryTextColor,
securityIconInsecure = Color.TRANSPARENT,
siteInfoIconSecure = primaryTextColor,
siteInfoIconInsecure = Color.TRANSPARENT,
menu = primaryTextColor,
hint = secondaryTextColor,
separator = separatorColor,

View File

@ -177,7 +177,7 @@ open class DefaultToolbarMenu(
private val installToHomescreen = BrowserMenuHighlightableItem(
label = context.getString(R.string.browser_menu_install_on_homescreen),
startImageResource = R.drawable.mozac_ic_add_to_homescreen_24,
startImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_add_to_homescreen_24,
iconTintColorResource = primaryTextColor(),
highlight = BrowserMenuHighlight.LowPriority(
label = context.getString(R.string.browser_menu_install_on_homescreen),
@ -222,7 +222,7 @@ open class DefaultToolbarMenu(
private val findInPageItem = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_find_in_page),
imageResource = R.drawable.mozac_ic_search_24,
imageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_search_24,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.FindInPage)
@ -266,7 +266,7 @@ open class DefaultToolbarMenu(
private val addToHomeScreenItem = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_add_to_homescreen),
imageResource = R.drawable.mozac_ic_add_to_homescreen_24,
imageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_add_to_homescreen_24,
iconTintColorResource = primaryTextColor(),
isCollapsingMenuLimit = true
) {
@ -302,7 +302,7 @@ open class DefaultToolbarMenu(
@VisibleForTesting
internal val settingsItem = BrowserMenuHighlightableItem(
label = context.getString(R.string.browser_menu_settings),
startImageResource = R.drawable.mozac_ic_settings_24,
startImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_settings_24,
iconTintColorResource = if (hasAccountProblem) {
ThemeManager.resolveAttribute(R.attr.syncDisconnected, context)
} else {
@ -342,7 +342,7 @@ open class DefaultToolbarMenu(
private val quitItem = BrowserMenuImageText(
label = context.getString(R.string.delete_browsing_data_on_quit_action),
imageResource = R.drawable.mozac_ic_cross_circle_24,
imageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_cross_circle_24,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.Quit)

View File

@ -67,7 +67,7 @@ fun ClearableEditText(
if (shouldShowClearButton()) {
IconButton(onClick = onClearClicked) {
Image(
painter = painterResource(id = R.drawable.mozac_ic_cross_circle_fill_24),
painter = painterResource(id = mozilla.components.ui.icons.R.drawable.mozac_ic_cross_circle_fill_24),
contentDescription = null,
colorFilter = ColorFilter.tint(WaterfoxTheme.colors.textPrimary),
)
@ -120,7 +120,7 @@ fun ClearableEditTextPreview() {
onValueChanged = { value.value = it },
onClearClicked = { value.value = "" },
errorMessage = stringResource(id = R.string.bookmark_invalid_url_error),
errorDrawable = R.drawable.mozac_ic_warning_fill_24,
errorDrawable = mozilla.components.ui.icons.R.drawable.mozac_ic_warning_fill_24,
keyboardType = KeyboardType.Uri,
)
}

View File

@ -28,7 +28,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import net.waterfox.android.R
import net.waterfox.android.R.drawable
import net.waterfox.android.theme.WaterfoxTheme
/**
@ -124,7 +123,7 @@ fun CFRPopupContent(
.size(48.dp)
) {
Icon(
painter = painterResource(drawable.mozac_ic_cross_20),
painter = painterResource(mozilla.components.ui.icons.R.drawable.mozac_ic_cross_20),
contentDescription = stringResource(R.string.cfr_dismiss_button_default_content_description),
modifier = Modifier
// Following alignment and padding are necessary to visually align the middle

View File

@ -40,10 +40,10 @@ fun MediaImage(
) {
val (icon, contentDescription) = when (tab.mediaSessionState?.playbackState) {
PlaybackState.PAUSED -> {
R.drawable.media_state_play to R.string.mozac_feature_media_notification_action_play
R.drawable.media_state_play to mozilla.components.feature.media.R.string.mozac_feature_media_notification_action_play
}
PlaybackState.PLAYING -> {
R.drawable.media_state_pause to R.string.mozac_feature_media_notification_action_pause
R.drawable.media_state_pause to mozilla.components.feature.media.R.string.mozac_feature_media_notification_action_pause
}
else -> return
}

View File

@ -230,7 +230,7 @@ fun TabGridItem(
},
) {
Icon(
painter = painterResource(id = R.drawable.mozac_ic_cross_20),
painter = painterResource(id = mozilla.components.ui.icons.R.drawable.mozac_ic_cross_20),
contentDescription = stringResource(id = R.string.close_tab),
tint = WaterfoxTheme.colors.iconPrimary,
)
@ -313,12 +313,12 @@ private fun Thumbnail(
backgroundColor = WaterfoxTheme.colors.layerAccent,
) {
Icon(
painter = painterResource(id = R.drawable.mozac_ic_checkmark_24),
painter = painterResource(id = mozilla.components.ui.icons.R.drawable.mozac_ic_checkmark_24),
modifier = Modifier
.matchParentSize()
.padding(all = 8.dp),
contentDescription = null,
tint = colorResource(id = R.color.mozac_ui_icons_fill),
tint = colorResource(id = mozilla.components.ui.icons.R.color.mozac_ui_icons_fill),
)
}
}

View File

@ -187,7 +187,7 @@ fun TabListItem(
.testTag(TabsTrayTestTag.tabItemClose),
) {
Icon(
painter = painterResource(id = R.drawable.mozac_ic_cross_24),
painter = painterResource(id = mozilla.components.ui.icons.R.drawable.mozac_ic_cross_24),
contentDescription = stringResource(
id = R.string.close_tab_title,
tab.content.title,
@ -228,7 +228,7 @@ private fun Thumbnail(
.semantics(mergeDescendants = true) {
testTag = TabsTrayTestTag.tabItemThumbnail
},
contentDescription = stringResource(id = R.string.mozac_browser_tabstray_open_tab),
contentDescription = stringResource(id = mozilla.components.browser.tabstray.R.string.mozac_browser_tabstray_open_tab),
)
if (isSelected) {
@ -247,12 +247,12 @@ private fun Thumbnail(
backgroundColor = WaterfoxTheme.colors.layerAccent,
) {
Icon(
painter = painterResource(id = R.drawable.mozac_ic_checkmark_24),
painter = painterResource(id = mozilla.components.ui.icons.R.drawable.mozac_ic_checkmark_24),
modifier = Modifier
.matchParentSize()
.padding(all = 8.dp),
contentDescription = null,
tint = colorResource(id = R.color.mozac_ui_icons_fill),
tint = colorResource(id = mozilla.components.ui.icons.R.color.mozac_ui_icons_fill),
)
}
}

View File

@ -142,7 +142,7 @@ class CustomTabToolbarMenu(
private val findInPage = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_find_in_page),
imageResource = R.drawable.mozac_ic_search_24,
imageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_search_24,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.FindInPage)

View File

@ -81,7 +81,7 @@ class PoweredByNotification(
val channel = NotificationChannel(
NOTIFICATION_CHANNEL_ID,
applicationContext.getString(R.string.mozac_feature_pwa_site_controls_notification_channel),
applicationContext.getString(mozilla.components.feature.pwa.R.string.mozac_feature_pwa_site_controls_notification_channel),
NotificationManager.IMPORTANCE_MIN
)

View File

@ -6,6 +6,8 @@ package net.waterfox.android.downloads
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.feature.downloads.AbstractFetchDownloadService
import mozilla.components.feature.downloads.DefaultFileSizeFormatter
import mozilla.components.feature.downloads.FileSizeFormatter
import mozilla.components.support.base.android.NotificationsDelegate
import net.waterfox.android.R
import net.waterfox.android.ext.components
@ -15,4 +17,5 @@ class DownloadService : AbstractFetchDownloadService() {
override val store: BrowserStore by lazy { components.core.store }
override val style: Style by lazy { Style(R.color.fx_mobile_text_color_accent) }
override val notificationsDelegate: NotificationsDelegate by lazy { components.notificationsDelegate }
override val fileSizeFormatter: FileSizeFormatter by lazy { DefaultFileSizeFormatter(this) }
}

View File

@ -63,7 +63,7 @@ class DynamicDownloadDialog(
if (didFail) {
binding.downloadDialogTitle.text =
context.getString(R.string.mozac_feature_downloads_failed_notification_text2)
context.getString(mozilla.components.feature.downloads.R.string.mozac_feature_downloads_failed_notification_text2)
binding.downloadDialogIcon.setImageResource(
mozilla.components.feature.downloads.R.drawable.mozac_feature_download_ic_download_failed
@ -80,7 +80,7 @@ class DynamicDownloadDialog(
}
} else {
val titleText = context.getString(
R.string.mozac_feature_downloads_completed_notification_text2
mozilla.components.feature.downloads.R.string.mozac_feature_downloads_completed_notification_text2
) + " (${downloadState.contentLength?.toMegabyteOrKilobyteString()})"
binding.downloadDialogTitle.text = titleText
@ -96,7 +96,9 @@ class DynamicDownloadDialog(
setOnClickListener {
val fileWasOpened = AbstractFetchDownloadService.openFile(
applicationContext = context.applicationContext,
download = downloadState
downloadFileName = downloadState.fileName,
downloadFilePath = downloadState.filePath,
downloadContentType = downloadState.contentType
)
if (!fileWasOpened) {
@ -134,7 +136,7 @@ class DynamicDownloadDialog(
download.filePath
)
return context.getString(
R.string.mozac_feature_downloads_open_not_supported1, fileExt
mozilla.components.feature.downloads.R.string.mozac_feature_downloads_open_not_supported1, fileExt
)
}
}

View File

@ -29,7 +29,7 @@ import kotlin.math.min
private const val SNAP_ANIMATION_DURATION = 150L
class DynamicDownloadDialogBehavior<V : View>(
context: Context?,
context: Context,
attrs: AttributeSet?,
private val bottomToolbarHeight: Float = 0f
) : CoordinatorLayout.Behavior<V>(context, attrs) {

View File

@ -167,17 +167,17 @@ class WebExtensionPromptFeature(
val addonName = exception.extensionName ?: ""
val appName = context.getString(R.string.app_name)
var title = context.getString(R.string.mozac_feature_addons_cant_install_extension)
var title = context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_cant_install_extension)
var url: String? = null
val message = when (exception) {
is WebExtensionInstallException.Blocklisted -> {
url = formatBlocklistURL(exception)
context.getString(R.string.mozac_feature_addons_blocklisted_2, addonName, appName)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_blocklisted_2, addonName, appName)
}
is WebExtensionInstallException.SoftBlocked -> {
url = formatBlocklistURL(exception)
context.getString(R.string.mozac_feature_addons_soft_blocked_1, addonName, appName)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_soft_blocked_1, addonName, appName)
}
is WebExtensionInstallException.UserCancelled -> {
@ -193,34 +193,34 @@ class WebExtensionPromptFeature(
// Message = Failed to install $addonName
title = ""
if (addonName.isNotEmpty()) {
context.getString(R.string.mozac_feature_addons_failed_to_install, addonName)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_install, addonName)
} else {
context.getString(R.string.mozac_feature_addons_extension_failed_to_install)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_extension_failed_to_install)
}
}
is WebExtensionInstallException.AdminInstallOnly -> {
context.getString(R.string.mozac_feature_addons_admin_install_only, addonName)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_admin_install_only, addonName)
}
is WebExtensionInstallException.NetworkFailure -> {
context.getString(R.string.mozac_feature_addons_extension_failed_to_install_network_error)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_extension_failed_to_install_network_error)
}
is WebExtensionInstallException.CorruptFile -> {
context.getString(R.string.mozac_feature_addons_extension_failed_to_install_corrupt_error)
context.getString(mozilla.components.feature.addons.R.string.mozac_feature_addons_extension_failed_to_install_corrupt_error)
}
is WebExtensionInstallException.NotSigned -> {
context.getString(
R.string.mozac_feature_addons_extension_failed_to_install_not_signed_error,
mozilla.components.feature.addons.R.string.mozac_feature_addons_extension_failed_to_install_not_signed_error,
)
}
is WebExtensionInstallException.Incompatible -> {
val version = context.appVersionName
context.getString(
R.string.mozac_feature_addons_failed_to_install_incompatible_error,
mozilla.components.feature.addons.R.string.mozac_feature_addons_failed_to_install_incompatible_error,
addonName,
appName,
version,

View File

@ -79,7 +79,7 @@ class HomeMenu(
private val quitItem by lazy {
BrowserMenuImageText(
context.getString(R.string.delete_browsing_data_on_quit_action),
R.drawable.mozac_ic_cross_circle_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_cross_circle_24,
primaryTextColor
) {
onItemTapped.invoke(Item.Quit)
@ -154,7 +154,7 @@ class HomeMenu(
val helpItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_help),
R.drawable.mozac_ic_help_circle_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_help_circle_24,
primaryTextColor
) {
onItemTapped.invoke(Item.Help)
@ -170,7 +170,7 @@ class HomeMenu(
val settingsItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_settings),
R.drawable.mozac_ic_settings_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_settings_24,
primaryTextColor
) {
onItemTapped.invoke(Item.Settings)

View File

@ -121,7 +121,7 @@ fun <T> LibrarySiteItem(
),
) {
Icon(
painter = painterResource(R.drawable.mozac_ic_checkmark_24),
painter = painterResource(mozilla.components.ui.icons.R.drawable.mozac_ic_checkmark_24),
contentDescription = null,
modifier = Modifier
.padding(10.dp)
@ -129,7 +129,7 @@ fun <T> LibrarySiteItem(
testTagsAsResourceId = true
testTag = "library.site.item.checkmark"
},
tint = colorResource(R.color.mozac_ui_icons_fill),
tint = colorResource(mozilla.components.ui.icons.R.color.mozac_ui_icons_fill),
)
}
}

View File

@ -230,7 +230,7 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
} catch (e: PlacesApiException.UrlParseFailed) {
withContext(Main) {
binding.bookmarkContent.bookmarkUrlErrorMessage = getString(R.string.bookmark_invalid_url_error)
binding.bookmarkContent.bookmarkUrlErrorDrawable = R.drawable.mozac_ic_warning_fill_24
binding.bookmarkContent.bookmarkUrlErrorDrawable = mozilla.components.ui.icons.R.drawable.mozac_ic_warning_fill_24
}
}
}

View File

@ -48,7 +48,7 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
_binding = FragmentDownloadsBinding.inflate(inflater, container, false)
@ -60,15 +60,15 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
items = items,
mode = DownloadFragmentState.Mode.Normal,
pendingDeletionIds = emptySet(),
isDeletingItems = false
)
isDeletingItems = false,
),
)
}
val downloadController: DownloadController = DefaultDownloadController(
downloadStore,
::openItem,
::invalidateOptionsMenu,
::deleteDownloadItems
::deleteDownloadItems,
)
downloadInteractor = DownloadInteractor(downloadController)
binding.downloadContent.interactor = downloadInteractor
@ -98,7 +98,7 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
filePath = it.filePath,
size = it.contentLength?.toString() ?: "0",
contentType = it.contentType,
status = it.status
status = it.status,
)
}.filter {
it.status == DownloadState.Status.COMPLETED
@ -130,7 +130,7 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
onCancel = {
undoPendingDeletion(items)
},
operation = getDeleteDownloadItemsOperation(items)
operation = getDeleteDownloadItemsOperation(items),
)
}
@ -141,13 +141,14 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
binding.downloadContent.updateState(state)
when (state.mode) {
is DownloadFragmentState.Mode.Normal -> setUiForNormalMode(
context?.getString(R.string.library_downloads)
context?.getString(R.string.library_downloads),
)
is DownloadFragmentState.Mode.Editing -> setUiForSelectingMode(
context?.getString(
R.string.download_multi_select_title,
state.mode.selectedItems.size,
)
),
)
}
}
@ -189,6 +190,7 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
}
true
}
else -> super.onOptionsItemSelected(item)
}
@ -201,9 +203,9 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
} else {
String.format(
requireContext().getString(
R.string.download_delete_single_item_snackbar
R.string.download_delete_single_item_snackbar,
),
downloadItems.first().fileName
downloadItems.first().fileName,
)
}
}
@ -223,20 +225,15 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
}
AbstractFetchDownloadService.openFile(
applicationContext = it.applicationContext,
download = DownloadState(
id = item.id,
url = item.url,
fileName = item.fileName,
contentType = item.contentType,
status = item.status,
contentLength = contentLength
)
downloadFileName = item.fileName,
downloadFilePath = item.filePath,
downloadContentType = item.contentType,
)
}
}
private fun getDeleteDownloadItemsOperation(
items: Set<DownloadItem>
items: Set<DownloadItem>,
): (suspend (context: Context) -> Unit) {
return { context ->
CoroutineScope(IO).launch {

View File

@ -86,7 +86,7 @@ fun Onboarding(
onClick = { onDismiss() },
) {
Icon(
painter = painterResource(id = R.drawable.mozac_ic_cross_20),
painter = painterResource(id = mozilla.components.ui.icons.R.drawable.mozac_ic_cross_20),
contentDescription = stringResource(R.string.onboarding_home_content_description_close_button),
tint = WaterfoxTheme.colors.iconPrimary,
)

View File

@ -7,20 +7,42 @@ package net.waterfox.android.perf
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import mozilla.components.concept.base.profiler.Profiler
import net.waterfox.android.HomeActivity
import net.waterfox.android.ext.components
import net.waterfox.android.perf.ProfilerMarkers.MEASURE_LAYOUT_DRAW_MARKER_NAME
/**
* A [LinearLayout] that adds profiler markers for various methods. This is intended to be used on
* the root view of [HomeActivity]'s view hierarchy to understand global measure/layout events.
* A [LinearLayout] that adds profiler markers for various methods and handles system window insets.
* This is intended to be used on the root view of [HomeActivity]'s view hierarchy to understand
* global measure/layout events and properly handle system bars.
*/
class HomeActivityRootLinearLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private val profiler: Profiler? = context.components.core.engine.profiler
init {
// Handle system window insets to prevent content from going behind status bar
ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
view.updatePadding(
top = systemBars.top,
bottom = systemBars.bottom,
left = systemBars.left,
right = systemBars.right
)
insets
}
// Request that the system send us window insets
requestApplyInsets()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val profilerStartTime = profiler?.getProfilerTime()
super.onMeasure(widthMeasureSpec, heightMeasureSpec)

View File

@ -6,9 +6,11 @@ package net.waterfox.android.push
import android.annotation.SuppressLint
import mozilla.components.feature.push.AutoPushFeature
import mozilla.components.lib.push.firebase.AbstractFirebasePushService
/**
* A singleton instance of the FirebasePushService needed for communicating between FCM and the
* [AutoPushFeature].
*/
@SuppressLint("MissingFirebaseInstanceTokenRefresh") // Implemented internally.
class FirebasePushService : AbstractFirebasePushService()

View File

@ -18,7 +18,7 @@ import mozilla.components.feature.push.PushScope
import mozilla.components.service.fxa.manager.FxaAccountManager
import mozilla.components.service.fxa.manager.ext.withConstellation
import net.waterfox.android.components.BackgroundServices
import net.waterfox.android.components.Push
/**
* A lazy initializer for FxaAccountManager if it isn't already initialized.

View File

@ -201,7 +201,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
binding.toolbar,
fromHomeFragment
).also {
inlineAutocompleteEditText = it.view.findViewById(R.id.mozac_browser_toolbar_edit_url_view)
inlineAutocompleteEditText = it.view.findViewById(mozilla.components.browser.toolbar.R.id.mozac_browser_toolbar_edit_url_view)
}
val awesomeBar = binding.awesomeBar

View File

@ -29,7 +29,7 @@ class ShortcutsSuggestionProvider(
override val id: String = UUID.randomUUID().toString()
private val settingsIcon by lazy {
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_settings_24)?.apply {
AppCompatResources.getDrawable(context, mozilla.components.ui.icons.R.drawable.mozac_ic_settings_24)?.apply {
colorFilter = createBlendModeColorFilterCompat(
context.getColorFromAttr(R.attr.textPrimary),
SRC_IN

View File

@ -55,7 +55,7 @@ class SearchSelectorMenu(
start = DrawableMenuIcon(
drawable = AppCompatResources.getDrawable(
context,
R.drawable.mozac_ic_settings_24
mozilla.components.ui.icons.R.drawable.mozac_ic_settings_24
),
tint = context.getColorFromAttr(R.attr.textPrimary)
)

View File

@ -27,7 +27,7 @@ import net.waterfox.android.ext.settings
class PreferenceBackedRadioButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.radioButtonStyle,
defStyleAttr: Int = androidx.appcompat.R.attr.radioButtonStyle,
) : AppCompatRadioButton(context, attrs, defStyleAttr) {
@VisibleForTesting
internal var externalOnCheckedChangeListener: OnCheckedChangeListener? = null

View File

@ -125,7 +125,7 @@ fun FontSizePreference(
Text(
text = stringResource(R.string.accessibility_text_size_sample_text_1),
modifier = Modifier
.background(colorResource(R.color.photonViolet05))
.background(colorResource(mozilla.components.ui.colors.R.color.photonViolet05))
.padding(16.dp),
color = colorResource(R.color.text_scale_example_text_color).copy(
alpha = if (enabled) 1f else 0.5f,

View File

@ -112,7 +112,7 @@ class LocaleSettingsComposeView @JvmOverloads constructor(
) {
if (selected) {
Image(
painterResource(R.drawable.mozac_ic_checkmark_24),
painterResource(mozilla.components.ui.icons.R.drawable.mozac_ic_checkmark_24),
contentDescription = stringResource(R.string.a11y_selected_locale_content_description),
modifier = Modifier
.align(Alignment.CenterVertically)

View File

@ -18,7 +18,7 @@ fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButt
) {
passwordText.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
revealPasswordButton.setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_eye_slash_24)
AppCompatResources.getDrawable(context, mozilla.components.ui.icons.R.drawable.mozac_ic_eye_slash_24)
)
revealPasswordButton.contentDescription =
context.getString(R.string.saved_login_hide_password)
@ -26,7 +26,7 @@ fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButt
passwordText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
revealPasswordButton.setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_eye_24)
AppCompatResources.getDrawable(context, mozilla.components.ui.icons.R.drawable.mozac_ic_eye_24)
)
revealPasswordButton.contentDescription =
context.getString(R.string.saved_login_reveal_password)

View File

@ -40,7 +40,7 @@ class SavedLoginsSortingStrategyMenu(
)
val highlight = HighPriorityHighlightEffect(
backgroundTint = context.getColorFromAttr(R.attr.colorControlHighlight)
backgroundTint = context.getColorFromAttr(androidx.appcompat.R.attr.colorControlHighlight)
)
return listOf(

View File

@ -33,7 +33,7 @@ import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import coil3.compose.AsyncImage
import net.waterfox.android.R
import net.waterfox.android.compose.button.Button
import net.waterfox.android.compose.ext.dashedBorder

View File

@ -52,7 +52,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import coil3.compose.AsyncImage
import kotlinx.coroutines.launch
import net.waterfox.android.R
import net.waterfox.android.compose.button.TextButton

View File

@ -69,38 +69,38 @@ class AccountDeviceViewHolder(
when (option) {
SyncShareOption.SignIn -> Triple(
context.getText(R.string.sync_sign_in),
R.drawable.mozac_ic_sync_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_sync_24,
R.color.default_share_background
)
SyncShareOption.Reconnect -> Triple(
context.getText(R.string.sync_reconnect),
R.drawable.mozac_ic_warning_fill_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_warning_fill_24,
R.color.default_share_background
)
SyncShareOption.Offline -> Triple(
context.getText(R.string.sync_offline),
R.drawable.mozac_ic_warning_fill_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_warning_fill_24,
R.color.default_share_background
)
SyncShareOption.AddNewDevice -> Triple(
context.getText(R.string.sync_connect_device),
R.drawable.mozac_ic_plus_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_plus_24,
R.color.default_share_background
)
is SyncShareOption.SendAll -> Triple(
context.getText(R.string.sync_send_to_all),
R.drawable.mozac_ic_select_all,
mozilla.components.ui.icons.R.drawable.mozac_ic_select_all,
R.color.default_share_background
)
is SyncShareOption.SingleDevice -> when (option.device.deviceType) {
DeviceType.MOBILE -> Triple(
option.device.displayName,
R.drawable.mozac_ic_device_mobile_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_device_mobile_24,
R.color.device_type_mobile_background
)
else -> Triple(
option.device.displayName,
R.drawable.mozac_ic_device_desktop_24,
mozilla.components.ui.icons.R.drawable.mozac_ic_device_desktop_24,
R.color.device_type_desktop_background
)
}

View File

@ -160,7 +160,7 @@ abstract class AbstractBrowserTabViewHolder(
MediaSession.PlaybackState.PAUSED -> {
showAndEnable()
contentDescription =
context.getString(R.string.mozac_feature_media_notification_action_play)
context.getString(mozilla.components.feature.media.R.string.mozac_feature_media_notification_action_play)
setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.media_state_play),
)
@ -169,7 +169,7 @@ abstract class AbstractBrowserTabViewHolder(
MediaSession.PlaybackState.PLAYING -> {
showAndEnable()
contentDescription =
context.getString(R.string.mozac_feature_media_notification_action_pause)
context.getString(mozilla.components.feature.media.R.string.mozac_feature_media_notification_action_pause)
setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.media_state_pause),
)

View File

@ -9,7 +9,6 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.VisibilityThreshold
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
@ -241,7 +240,7 @@ fun LazyGridItemScope.DragItemContainer(
else -> {
Modifier
.zIndex(0f)
.animateItemPlacement(tween())
.animateItem()
}
}

View File

@ -7,7 +7,6 @@ package net.waterfox.android.tabstray.browser.compose
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
import androidx.compose.foundation.gestures.scrollBy
@ -235,7 +234,7 @@ fun LazyItemScope.DragItemContainer(
else -> {
Modifier
.zIndex(0f)
.animateItemPlacement(tween())
.animateItem()
}
}
Box(modifier = modifier, propagateMinConstraints = true) {

View File

@ -114,7 +114,7 @@ fun InactiveTabsList(
faviconPainter = faviconPainter,
onClick = { onTabClick(tab) },
url = tabUrl,
iconPainter = painterResource(R.drawable.mozac_ic_cross_24),
iconPainter = painterResource(mozilla.components.ui.icons.R.drawable.mozac_ic_cross_24),
iconDescription = stringResource(R.string.content_description_close_button),
onIconClick = { onTabCloseClick(tab) },
)
@ -202,7 +202,7 @@ private fun InactiveTabsAutoClosePrompt(
modifier = Modifier.size(20.dp),
) {
Icon(
painter = painterResource(R.drawable.mozac_ic_cross_20),
painter = painterResource(mozilla.components.ui.icons.R.drawable.mozac_ic_cross_20),
contentDescription =
stringResource(R.string.tab_tray_inactive_auto_close_button_content_description),
tint = WaterfoxTheme.colors.iconPrimary,

View File

@ -23,7 +23,7 @@ import net.waterfox.android.R
class ClearableEditText @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.editTextStyle
defStyleAttr: Int = androidx.appcompat.R.attr.editTextStyle
) :
AppCompatEditText(context, attrs, defStyleAttr) {
@ -53,7 +53,7 @@ class ClearableEditText @JvmOverloads constructor(
// lengthAfter has inconsistent behaviour when there are spaces in the entered text, so we'll use text.length.
val textLength = text?.length ?: 0
val drawable = if (shouldShowClearButton(textLength)) {
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_cross_circle_fill_24)?.apply {
AppCompatResources.getDrawable(context, mozilla.components.ui.icons.R.drawable.mozac_ic_cross_circle_fill_24)?.apply {
colorFilter = createBlendModeColorFilterCompat(context.getColorFromAttr(R.attr.textPrimary), SRC_IN)
}
} else {

View File

@ -48,7 +48,7 @@ object ToolbarPopupWindow {
true
)
popupWindow.elevation =
context.resources.getDimension(R.dimen.mozac_browser_menu_elevation)
context.resources.getDimension(mozilla.components.browser.menu.R.dimen.mozac_browser_menu_elevation)
// This is a workaround for SDK<23 to allow popup dismissal on outside or back button press
// See: https://github.com/mozilla-mobile/fenix/issues/10027

View File

@ -16,7 +16,7 @@ import android.os.Handler
import android.os.Looper
import android.view.View
import android.widget.ImageView
import coil.load
import coil3.load
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import mozilla.components.support.base.log.logger.Logger

View File

@ -0,0 +1,91 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="1419"
android:viewportHeight="1419">
<group android:scaleX="0.46"
android:scaleY="0.46"
android:translateX="383.13"
android:translateY="383.13">
<path
android:pathData="M614.7,191.6c5.8,-6.1 12.9,-11.4 19.7,-16.3 29,-21 63.1,-35.8 99.3,-36.6 29.9,-0.6 60.6,9.3 82.3,30.2 9.6,9.2 17.8,21 22.1,33.6 3.2,7.1 4.6,15.9 5,23.6 1,18.6 -4.5,36.8 -14.1,52.7 -19.8,32.8 -54.8,55.2 -89.2,70.5 -16,7.1 -32.5,13.2 -48.5,20.3 -20.3,8.9 -39.9,19.4 -58.6,31.3 -18,11.6 -36,25.4 -49.3,42.2 -5.8,7.3 -10.5,16.2 -16.8,23 -1.4,1.5 -4.5,4.5 -6.8,4.2 -2.8,-0.3 -5.5,-3.5 -7.1,-5.6 -4.4,-6.1 -7,-14.4 -9.1,-21.6 -10.7,-36 -11.4,-76.6 -5.1,-113.4 7.2,-43.9 26.6,-84.9 56,-118.3 6,-6.9 12.6,-14.6 20.1,-19.8"
android:fillColor="#68edfc"/>
<path
android:pathData="M420,382.1c2.8,-0 5.8,0.2 8.6,0.5 14.1,1.4 27.7,9 36.6,19.9 13.5,16.4 14,38 6.8,57.3 -3.5,9.5 -8.6,18.4 -12.6,27.7 -4.9,11.5 -8.9,23.4 -11.8,35.6 -3.4,14.2 -4.8,29.2 -5.3,43.7 -0.2,7.2 0.1,14.7 -0.7,21.9 -0.3,2.9 -0.4,6 -2.8,7.9 -6.8,0.3 -15.4,-5.2 -21.3,-8.3 -7.1,-4 -13.7,-8.8 -19.9,-14.1 -27.3,-23.8 -44.6,-59.6 -46.9,-95.7 -1.7,-26.3 5.3,-53.8 23,-73.9 12.3,-13.9 27.7,-21.2 46.2,-22.5">
<aapt:attr name="android:fillColor">
<gradient
android:startX="427.1"
android:startY="596.2"
android:endX="406.3"
android:endY="384.1"
android:type="linear">
<item android:offset="0" android:color="#FF00DFFE"/>
<item android:offset="1" android:color="#FF62FEFA"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M988.3,98.9c36.8,-6.2 71.7,18.7 77.9,55.5 6.1,36.9 -18.8,71.7 -55.7,77.8 -36.8,6.1 -71.5,-18.8 -77.6,-55.6 -6.1,-36.8 18.7,-71.5 55.4,-77.7"
android:fillColor="#68edfc"/>
<path
android:pathData="M713.8,445.8c14.1,-11.1 31.8,-20.1 47.8,-28.1 60.9,-30.3 130.8,-50.7 199.4,-42.6 37.9,4.5 76.2,19.3 100.4,50.1 7.6,9.6 15.7,21.9 14.2,34.8 -0.9,8 -5.4,14.9 -10.6,20.9 -10.1,11.6 -22.4,21.5 -34.1,31.4 -15.5,13 -30.7,26.2 -45.7,39.8 -11.5,10.6 -22.7,21.6 -33.7,32.8 -5.5,5.6 -10.9,12.5 -16.9,17.4 -14.2,15.8 -28.4,31.7 -41.6,48.3 -74.4,88.3 -127.7,191.6 -183.5,292l-119.4,213.3 -32,56.9c-11.3,20 -21.6,40.7 -37.1,57.8 -19.2,20.9 -43.8,35.9 -71.2,43.4 -4.4,1.2 -8.9,2.3 -13.4,3.3 -1.5,0.1 -2.7,0.3 -4.2,0.7 -7.4,2.4 -35.6,2.9 -42.7,0.6 -2.1,-0.7 -3.9,-1.1 -6.1,-1.3l-0.8,-0.1c-6.8,-1.6 -13.4,-3.1 -20.1,-5.2 -28.2,-9 -53.1,-26.2 -71.6,-49.4 -18.5,-23.3 -29,-53.1 -41,-80.1l-44.5,-100.6c-7.9,-18 -15.3,-36.6 -24.2,-54.1 -2.9,-10 -9.1,-19.6 -12.6,-29.6 2.9,3 5.3,6.8 8,10.1 6.8,8.3 14.3,15.2 23.4,20.9 21.9,13.6 48.3,18 73.3,12 17.6,-4.2 33.7,-13.3 46.3,-26.3 15.7,-16.2 28.5,-43.2 40,-63.2l40.8,-70.8c8.9,-15.5 17.4,-31.2 26.7,-46.4l79.3,-137.7c21.5,-37.1 42,-75.7 66,-111.2 25.6,-38 56.2,-72.3 91,-102.2 15.6,-13.4 32.6,-27.4 50.4,-37.7">
<aapt:attr name="android:fillColor">
<gradient
android:startX="729.8"
android:startY="1172"
android:endX="432.8"
android:endY="592"
android:type="linear">
<item android:offset="0" android:color="#FF10B8F7"/>
<item android:offset="1" android:color="#FF2BFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M713.8,445.8c14.1,-11.1 31.8,-20.1 47.8,-28.1 60.9,-30.3 130.8,-50.7 199.4,-42.6 37.9,4.5 76.2,19.3 100.4,50.1 7.6,9.6 15.7,21.9 14.2,34.8 -0.9,8 -5.4,14.9 -10.6,20.9 -10.1,11.6 -22.4,21.5 -34.1,31.4 -15.5,13 -30.7,26.2 -45.7,39.8 -11.5,10.6 -22.7,21.6 -33.7,32.8 -5.5,5.6 -10.9,12.5 -16.9,17.4 -20.9,9.7 -40.3,20.1 -63.2,25.1 -15.9,3.4 -34.8,4.5 -48.9,-5 -10.4,-7 -14.4,-17.1 -16.9,-28.9 -21.5,20.2 -50.9,43.4 -80.6,47.8 -12.5,1.9 -25,0 -35.2,-7.8 -14.2,-10.8 -20.5,-30.1 -22.7,-47.1 -4.9,-37.8 5.8,-78.1 25.2,-110.5 6.3,-10.6 13.8,-20.3 21.4,-30"
android:fillColor="#bafafc"/>
<path
android:pathData="M709.5,942.6c55.8,-100.3 109.2,-203.6 183.5,-292 12.3,20.3 23.4,41.5 35,62.3l65.7,118.3 61,109.7L1075.5,978.2c7,12.6 13.4,25.5 23.1,36.2 10.8,11.9 26.6,21 42,25.6 24.7,7.4 51.3,4.5 73.9,-8 15,-8.3 25.1,-19.4 35.1,-33.1l0.6,0.3c-3.8,9.4 -9.8,19.2 -12.5,28.8 -9.1,17.5 -16.4,36.3 -24.4,54.4l-45.9,103.6c-8.3,18.8 -15.8,39.3 -26.4,57 -9.4,15.7 -21.8,30.6 -35.9,42.2 -20.9,18.3 -48.8,29.3 -76.2,33.4l-3.5,0.5c-15.4,1.2 -29.6,0.2 -44.9,-1.8 -5.2,-1.3 -10.3,-2.7 -15.5,-4.1 -26.8,-7.9 -50.9,-23.2 -69.4,-44.1 -15.1,-17.1 -25.2,-37.7 -36.2,-57.5l-33.4,-60.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="782.1"
android:startY="1081.2"
android:endX="1178.1"
android:endY="878.1"
android:type="linear">
<item android:offset="0" android:color="#FF08A9F8"/>
<item android:offset="1" android:color="#FF0CDBFE"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M3.2,560.7c7.2,-32.5 21.8,-61.3 46.6,-84 24.5,-22.3 55.5,-36 88.5,-39.1 9.7,-0.8 19.4,-0.3 29.1,0.1 42.5,6 79,24.6 105.3,59.3 13.9,18.3 22.1,40 31.4,60.9l27.3,61.6 95.6,215.3c-9.3,15.2 -17.9,30.9 -26.7,46.4l-40.8,70.8c-11.4,19.9 -24.2,46.9 -40,63.2 -12.7,12.9 -28.7,22.1 -46.3,26.3 -25.1,6 -51.5,1.7 -73.3,-12 -9.1,-5.7 -16.6,-12.6 -23.4,-20.9 -2.7,-3.3 -5.1,-7 -8,-10.1 -3.1,-6.4 -5.7,-13.3 -8.6,-19.9l-20.3,-45.8L76.5,790.5l-43.9,-98.7C24.5,673.4 15.1,654.9 8.6,635.8c-5.3,-15.7 -7.6,-31.8 -7.9,-48.3 -0,-9 1.3,-18 2.5,-26.9">
<aapt:attr name="android:fillColor">
<gradient
android:startX="369.8"
android:startY="984.8"
android:endX="49.9"
android:endY="474.8"
android:type="linear">
<item android:offset="0" android:color="#FF008AED"/>
<item android:offset="1" android:color="#FF05D1EA"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m993.7,831.2 l96.4,-217.3 26.2,-58.9c8.7,-19.5 16.6,-39.5 29.3,-56.8 17.1,-23.1 40.5,-40.9 67.3,-51.1 37.7,-14.5 79.7,-13.2 116.5,3.5 36.6,16.5 65.1,47 79.1,84.7 10.1,26.8 12.3,55.9 6.4,83.9 -5,23.3 -16.3,45.1 -25.9,66.8l-37.4,84.3 -68.3,154.1c-11,24.8 -21.3,50.1 -32.9,74.5 -0.1,0.2 -0.2,0.3 -0.3,0.5l-0.6,-0.3c-10,13.7 -20.1,24.8 -35.1,33.1 -22.6,12.5 -49.2,15.4 -73.9,8 -15.4,-4.6 -31.2,-13.7 -42,-25.6 -9.8,-10.8 -16.1,-23.6 -23.1,-36.2l-20.8,-37.3Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="1082.2"
android:startY="1014.3"
android:endX="1323.2"
android:endY="449"
android:type="linear">
<item android:offset="0" android:color="#FF2F76EB"/>
<item android:offset="1" android:color="#FF7E94F3"/>
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View File

@ -1,663 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="208"
android:viewportHeight="208">
<path
android:pathData="M136,129.9c-1.1,-0.4 -2.2,-1 -3,-2 -1.2,-1.1 -8,-13.3 -8,-14.1 0,-0.5 0.2,-0.7 0.5,-0.6 0.2,0 1,-1.4 2.4,-4.7 2.4,-5.4 2.4,-5.4 4.4,-4a28.7,28.7 0,0 0,15.2 6.7c2,0.2 2.6,0.5 2.6,1.2 0,0.3 1,-1 1,-0.9 0.2,0 -2,5.2 -4,9.5 -3.3,7.5 -3.6,8 -4.5,8.5a15,15 0,0 1,-6.5 0.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="130.7"
android:startY="124.8"
android:endX="152.9"
android:endY="86.6"
android:type="linear">
<item android:offset="0" android:color="#FF1964E7"/>
<item android:offset="1" android:color="#FF6884F2"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M65.8,129.7c-1.3,-0.5 -1.3,-0.6 -3,-4.5l-2.9,-6.5 -1.7,-4.1 1.9,1.6a28,28 0,0 0,7.5 -1.9l3.2,-1c1,-0.3 1.4,-0.5 1.4,-0.9 0,-0.2 0.3,-0.5 0.7,-0.6 0.3,0 1.8,-0.7 3.2,-1.3 1.4,-0.7 2.8,-1.2 3,-1.2 0.2,0 0.4,0 0.4,-0.2s0.2,-0.3 0.4,-0.3 0.8,1 1.3,2.3c1,2.4 1.3,2.8 1.7,2.2 0.2,-0.3 0.3,-0.2 0.3,0.4 0,1 -6.6,12.7 -8,14.1 -1.5,1.7 -2.8,2.2 -5.7,2.3a9,9 0,0 1,-3.7 -0.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M136.3,129.9c0,-0.2 -0.3,-0.3 -0.8,-0.3 -0.7,0 -0.8,-0.1 -0.8,-0.7s-0.2,-0.7 -1,-0.7c-1,0 -1,0 -1,-1v-1l1,1a7.3,7.3 0,0 0,3.7 2c1.3,0.2 1.2,1 0,1 -0.6,0 -1,-0.2 -1,-0.3Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M138,129.4c0,-0.2 1.8,-0.1 2.5,-0.4 0.6,-0.2 1.6,-0.6 2.2,-1 1.2,-0.8 1.4,-0.7 1.1,0.3 -0.1,0.5 -0.3,0.7 -0.8,0.7s-0.8,0.2 -0.8,0.4c0,0.4 -0.8,0.8 -2,0.8 -0.5,0 -2.2,-0.5 -2.2,-0.8ZM105.2,123.5c-0.6,-1.2 -1.1,-1.8 -1.4,-1.7 -0.3,0.1 -0.4,0 -0.4,-0.6 0,-1.3 6.3,-12 10.3,-17.7 2.3,-3.2 2.7,-3.6 3.5,-3.7 0.7,0 0.9,0 1,0.7v1.1a47.8,47.8 0,0 0,-4.9 8.2,200.2 200.2,0 0,0 -6,14.5l1.2,4.3c0,1 -2.3,-3.3 -3.3,-5ZM130.7,124.1c0,-1.2 0.4,-1.3 1,-0.1 0.6,1 0.5,1 -0.3,1 -0.6,0 -0.7,0 -0.7,-0.9Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M129.3,121.6c0,-1.2 0.4,-1.3 1,-0.1 0.6,1 1.5,2.3 0.6,2.3 -0.6,0 -1.6,-1.3 -1.6,-2.2ZM128,119c0,-0.7 -0.1,-1 -0.5,-1 -0.6,0 -0.9,-0.5 -0.9,-1.7 0,-0.6 -0.1,-0.8 -0.6,-0.8 -0.3,0 -0.6,-0.2 -0.7,-0.6 -0.2,-1 -0.3,-2 0.1,-1.8 0.4,0.1 4,6.5 4,6.8l-0.7,0.1c-0.6,0 -0.7,0 -0.7,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M135.2,129.6c0,-0.1 -0.2,-0.3 -0.5,-0.3 -0.4,0 -0.6,-0.2 -0.6,-0.4s-0.2,-0.4 -0.5,-0.4c-0.7,0 -1.2,-0.8 -1.2,-1.7 0,-1 0.2,-1 0.8,-0.2a9,9 0,0 0,3.2 2.3c1.2,0.3 1,1 -0.2,1 -0.5,0 -1,-0.1 -1,-0.3ZM106.6,125.4c-0.3,-0.8 -0.5,-1.7 -0.2,-2a266,266 0,0 1,8 -18.5,53.2 53.2,0 0,0 -2,2.6 26.2,26.2 0,0 1,-2.3 3.3l-0.2,-1c0,-0.9 0,-1 0.7,-1 0.5,0 0.7,-0.2 1,-1l0.3,-1.6c0,-0.3 0.1,-0.5 0.3,-0.5 0.4,0 1,-0.9 1,-1.5 0,-0.3 0.2,-0.5 0.4,-0.5l0.2,-0.4c0,-0.2 0.2,-0.4 0.5,-0.5 0.2,-0.1 0.4,-0.4 0.4,-0.6 0,-0.2 0.2,-0.5 0.4,-0.6 0.2,0 0.4,-0.2 0.4,-0.4 0,-0.3 1.6,-2 2,-2 0.2,0 1.6,2.8 1.9,3.4 0,0.2 -0.6,0 -0.7,0l-0.7,1 -3,5.9a69.3,69.3 0,0 0,-2.7 5.9c-0.3,1 -2.2,5.8 -3.2,8s-1.5,2.8 -2,2.8c-0.3,0 -0.3,-0.4 -0.5,-0.8ZM129.6,122.1c0,-1.2 0.3,-1.2 1,-0.1 0.5,1 0.5,1.1 -0.3,1.1 -0.6,0 -0.7,0 -0.7,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M128.2,119.6c0,-1.2 0.3,-1.3 1,-0.2 1.1,2.1 0.8,1.7 -0.3,1.2 -0.6,-0.3 -0.7,-0.1 -0.7,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M59.6,117.3c-0.3,-0.4 -1.2,-2 -1.9,-3.5l-1.6,-3.9 1.8,1c3.4,-0.3 17.7,-7.2 17.7,-8.4 0,-0.4 1,-1.6 1.2,-1.3l2,4.4c1.8,4.1 2,5 1.3,4.7 -1,0.1 -2,0.4 -2.8,0.9l-3.4,1.4 -1,0.4 1.3,-0.1c1.6,-0.2 1,0.2 -2,1l-3.8,1.3 -7.4,2.1c-0.3,0 -0.5,0.2 -0.6,0.4 0,0.2 -0.4,0 -0.8,-0.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M57.6,112.4c0,-0.3 -0.2,-0.5 -0.4,-0.5 -0.3,0 -1,-1.4 -2.2,-4.5 -0.1,-0.1 1.1,0 2.5,-0.6 4.6,-1.6 8.7,-3.9 12.6,-6.8 2.4,-2 3,-2.4 3,-2.9 0,-0.2 0.2,-0.4 0.4,-0.4s0.4,-0.1 0.4,-0.3c0,-0.1 0.2,-0.3 0.4,-0.3a28,28 0,0 1,3 7c0.3,0.7 0.2,0.7 -0.1,0.3 -0.5,-0.6 -0.8,-0.7 -0.8,-0.1 0,1 -10.9,6.5 -16.8,8.4l-1.8,0.8c-0.1,0.2 -0.2,0.2 -0.2,-0.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m72,129 l0.8,-0.6 1.8,-1.5 1,-1v0.9c0,1 -0.5,1.7 -1.2,1.7 -0.3,0 -0.5,0.2 -0.5,0.4 0,0.3 -0.3,0.4 -1,0.4l-1,-0.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m54.3,106.1 l-1.1,-2.5 0.7,-0.2c2.5,-0.5 8,-3.4 11,-5.8a32.7,32.7 0,0 0,6.8 -7.1c0.2,0 0.3,0.1 0.7,0.7l2.4,5.7 0.7,1.6c0.2,0.4 -0.3,-0.1 -0.5,-0.1 -0.1,0 -0.3,-0.2 -0.3,-0.4 0,-0.3 -0.1,-0.5 -0.4,-0.5 -0.2,0 -0.4,0.2 -0.4,0.5a48,48 0,0 1,-14.7 9.4l-2.3,0.8 -1.2,0.4c-0.1,0.1 -0.8,-1 -1.4,-2.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M124.1,149.8c-3.2,-0.8 -5.9,-3 -7.5,-6 -1.5,-2.6 -1.6,-2.7 -0.6,-2.7 0.5,0 1.8,-0.4 2.8,-0.9 2,-1 4.4,-1.3 6.7,-0.8 2.2,1.4 4.2,3.1 5.8,5.2l1.2,1.6 1.6,-0.2 4.4,-6a22,22 0,0 1,-3.8 6.8,12 12,0 0,1 -10.6,3ZM136.1,129.6c0,-0.6 0.2,-0.7 1.3,-0.4 1,0.3 0.8,1 -0.4,1 -0.7,0 -1,-0.2 -1,-0.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M107.2,127.1c-0.8,-1.6 -0.8,-1.6 -0.3,-2.1 0.7,-0.8 4,-8.3 4.5,-10.4a110.8,110.8 0,0 1,6.5 -13.1c-0.2,0 -0.3,-0.2 -0.3,-0.5 0,-0.8 0.7,-0.3 1.5,1.1 0.9,1.4 1,2.5 0.4,2.5 -0.4,0 -6.2,11.8 -6.4,13 -0.4,2.4 -1.3,4.7 -2.5,6.8 -1,2 5.6,18.7 5.7,18.9ZM133.2,127.9v-0.9l0.9,0.6c1.2,0.9 1.3,1.2 0.2,1.2 -1,0 -1,-0.1 -1,-1ZM142.6,128.1s0.7,-0.3 1.2,-0.9l1,-1 -0.5,1.1c-0.3,0.8 -0.6,1.2 -1,1.2 -0.3,0 -0.7,-0.3 -0.7,-0.4ZM131,124.7c0,-1.3 0.3,-1.3 1,0l0.7,1h-0.9c-0.7,0 -0.8,-0.1 -0.8,-1ZM127,117.7c0,-1.3 0.3,-1.3 1.1,0l0.7,1h-0.9c-0.8,0 -0.8,-0.2 -0.8,-1ZM125.7,115.1c0,-1.2 0.2,-1.2 1,0l0.8,1.3 -1,-0.3c-0.8,0 -0.8,0 -0.8,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m77.4,103.8 l-0.3,-0.8 0.6,0.7c0.5,1 0.4,1.1 -0.3,0.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M71.9,145.1c-0.2,0 -0.2,-0.5 -0.2,-1 0,-0.6 0,-0.7 1,-0.7 0.9,0 1,0 1,1 0,0.9 -0.2,1 -0.9,1 -0.4,0 -0.9,-0.1 -1,-0.3Z"
android:fillColor="#00b0e7"/>
<path
android:pathData="M53.8,104.6c0,-0.1 0,-0.2 -0.2,-0.2 -0.2,-0.1 -2.3,-4.6 -2.1,-4.8a115.4,115.4 0,0 1,6.4 -2.7l2,-1.5c3.4,-2.6 7.2,-6.6 7.7,-8.3 0.3,-1.6 0.6,-1.6 2,-0.3 1.3,1.4 2.3,3 2.8,4.9 0.1,0.6 0,0.7 -0.3,0.6a31.7,31.7 0,0 1,-14.4 10.9c-1.5,0.6 -2.4,1.1 -2.4,1.4 0,0.3 0,0.3 -0.2,0s-0.4,-0.3 -0.5,-0.2c-0.3,0.4 -1,0.6 -0.8,0.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M78.6,149.8c-1.4,-0.3 -3.8,-1.6 -3.8,-2 0,0 0.4,-0.2 1,-0.2 0.5,0 1,0 1,0.2 0,0.1 1.2,0.2 2.6,0.2 2,-0.1 3,0 3.6,0.3l1.2,0.4c0.6,0 0.5,0.8 0,1 -1,0.3 -4.5,0.4 -5.6,0.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M133.3,147.5c0,-0.4 -0.2,-0.4 -0.7,-0.3 -0.5,0.1 -0.9,-0.2 -2.1,-1.7 -1.6,-2 -3.5,-3.8 -5.7,-5.2 -0.5,-0.2 -1.5,-0.3 -2.1,-0.2 -1.4,0.1 -4.5,1.5 -5.3,2.3 -0.6,0.6 -1.2,0.8 -1.2,0.3 0,-0.2 0,-0.3 -0.2,-0.4 -0.2,0 -1,-1.4 -3.6,-6l-1.1,-2h0.9c0.5,0 0.8,0.2 0.8,0.5 0,0.4 0.5,0.6 0.6,0.2a25,25 0,0 1,2.5 -2.1c2.3,-2 2.4,-2 2.3,-3 0,-1.1 0,-1.2 0.8,-1.2 1,0 1,0.2 2.5,2.5a27,27 0,0 0,3.4 4.2c2.4,2.2 3.9,2.7 6.4,2.5 1.2,-0.2 1.8,-0.1 1.8,0.1s0,0.3 0.3,0.3c0.2,0 1,0.5 1.6,1.1a5,5 0,0 0,2 1.2l1,0.1c-0.4,0.9 -2.2,4.6 -3.5,6 -1.6,1.7 -1.4,1.4 -1.4,0.8ZM108.8,129.8c-1,-1.7 -1.2,-2.7 -0.7,-3.2 1.7,-2.9 3,-6 4,-9.2l1.6,-4.1c0.6,-1.4 1.1,-2.6 1,-2.7l0.2,-0.1a46.7,46.7 0,0 1,4 -7.7c0.5,-0.6 0.5,0 1.4,1.4 0.8,1.3 0.8,1.3 0.3,2.2 -1.6,2.7 -3,5.5 -4.5,8.3 -1.2,2.4 -1.5,3.2 -1.4,4.3 0,1.5 -0.6,3.5 -2,6.7 -0.6,1.2 -1.1,2.5 -1.2,3 -0.1,0.4 -0.3,0.9 -0.6,1.2 -0.3,0.2 -0.4,0.6 -0.4,1 0,1.1 -0.7,0.7 -1.7,-1ZM139.8,129.8c0,-0.3 0.4,-0.6 0.7,-0.7a2,2 0,0 0,1 -0.3c0.2,-0.2 0.5,-0.2 0.6,-0.1 0,0 0.2,0 0.2,-0.2s0,-0.3 0.3,-0.3c0.2,0 0.4,-0.3 0.7,-0.5 0.5,-0.4 0.3,-0.4 0.4,0.4 0,0.7 -0.2,1 -0.5,1.1 -0.3,0.1 -0.6,0.3 -0.7,0.5l-1.5,0.4c-1.2,0.1 -1.3,0 -1.3,-0.4ZM132.1,127.3 L131.7,126.6c-0.4,-0.4 -0.6,-2.3 -0.2,-2.3 0.2,0 0.7,0.7 1.9,2.6l0.4,0.7h-0.8c-0.5,0 -0.9,-0.1 -0.9,-0.3ZM129.9,122.7c0,-1.2 0.2,-1.2 1,0l0.7,1.2 -0.9,-0.2c-0.8,0 -0.8,-0.1 -0.8,-1ZM128.5,120.2c0,-0.8 -0.1,-1 -0.6,-1 -0.4,0 -0.6,-0.2 -0.6,-1l0.2,-1c0.3,0 1.2,1.3 1.3,1.6l0.7,1.3 0.8,1.3 -1,-0.2c-0.8,0 -0.8,-0.1 -0.8,-1ZM125.9,115.7c0,-1.2 0.2,-1.2 1,-0.4 0.6,1 0.6,1.4 -0.3,1.4 -0.6,0 -0.7,-0.2 -0.7,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M131.7,126.6a5,5 0,0 1,-0.1 -1.3c0,-0.6 -0.2,-0.8 -0.6,-0.8 -0.4,0 -0.6,-0.2 -0.6,-1 0,-0.9 0,-1 0.5,-0.6l0.9,1.4c0.2,0.6 0.1,1.1 0.3,1.1 0.1,0 0.5,0.1 0.4,0.3l0.1,0.2c0.2,0 0.4,0.3 0.5,0.6 0,0.5 0,0.6 -0.6,0.6 -0.3,0 -0.7,-0.2 -0.8,-0.5ZM129,121c0,-1 0,-1 0.6,-0.6l0.6,1c0.2,0.5 0,0.6 -0.5,0.6 -0.6,0 -0.7,-0.1 -0.7,-1ZM127.6,118.4c0,-1 0,-1 0.5,-0.4 0.3,0.2 0.6,0.7 0.7,1 0.2,0.4 0,0.5 -0.5,0.5 -0.6,0 -0.7,-0.1 -0.7,-1ZM126.2,115.9c0,-1 0,-1 0.5,-0.5l0.7,1c0.2,0.4 0,0.5 -0.5,0.5 -0.6,0 -0.7,0 -0.7,-1ZM124.8,113.6c0,-0.8 -0.4,-2 0.5,-0.6l0.7,1c0,0.3 0,0.4 -0.5,0.4 -0.6,0 -0.7,-0.1 -0.7,-0.8Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M149.2,114c-0.1,-0.2 -0.1,-0.6 0,-0.8 0.2,-0.7 -0.5,-1 -2.6,-1.2 -5,-0.4 -9.8,-2.5 -15.2,-6.6l-1,-0.9 -1,1.5 -0.9,1.2 3.2,-7.2c2.5,-5.6 3.2,-7 3.6,-7 0.3,0 1.3,0.8 2.2,1.9 2.3,2.4 5,4.2 8.2,5.3 2,0.7 4.2,1 6.3,0.8h4l-0.5,1.1c-1.7,4 -3.5,8 -5.5,12 -0.5,0.4 -0.6,0.4 -0.8,-0.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="130.7"
android:startY="124.8"
android:endX="152.9"
android:endY="86.6"
android:type="linear">
<item android:offset="0" android:color="#FF1964E7"/>
<item android:offset="1" android:color="#FF6884F2"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M52.4,100.7c0,-0.2 -0.3,-0.3 -0.4,-0.2 -0.3,0.1 -1,-1.7 -1.4,-3.5 -0.5,-2 -0.4,-2.3 0.4,-2.3 1,0 3.5,-1.1 3.5,-1.5 0,-0.2 0.6,-0.8 1.3,-1.3 1.8,-1.2 3.4,-2.6 4.7,-4.3 0.8,-0.9 1,-1.6 1.2,-2.7l0.2,-1.4c0.6,-0.1 2.8,0.3 2.6,0.4 -1,-0.4 1.3,0.4 2.8,1.2l1.4,1c0.6,0.5 0.4,0.8 0,1.2 -0.3,0.2 -0.4,0.6 -0.3,0.7 0.3,0.4 -2.2,3.4 -4.3,5.3 -3.4,3.2 -4.3,4 -4,3.6 0.1,-0.4 -0.7,0.2 -1.2,0.8l-1,0.5c-4.2,1.6 -5,2 -5.1,2.4 -0.1,0.4 -0.2,0.4 -0.4,0Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M83.3,149.6c-0.3,0 -0.6,-0.2 -0.8,-0.3 -0.5,-0.4 -3.8,-0.6 -4.8,-0.3 -1.5,0.4 -4.4,-1.6 -6,-4.2l-0.7,-1.5 1,-0.4 2.5,-1.8 1.6,-1.1c0.2,0 0.3,-0.2 0.3,-0.4 0,-0.3 0.3,-0.4 1.2,-0.4 3,0 6.3,-2.8 9.2,-7.4 1.5,-2.3 1.7,-2.5 2.5,-2.5 0.5,0 1,0.2 1,0.4 0.2,0.5 0,7.3 -0.4,10.5 -0.4,3 -0.2,3.7 1,3.7 0.4,0 0.4,0.2 -0.4,1.2 -1.8,2.7 -5.3,5 -7.2,4.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M137.2,141.8c0,-0.3 -0.1,-0.4 -0.5,-0.1 -0.4,0.2 -0.8,0 -2,-1.2a7.1,7.1 0,0 0,-2 -1.3l-0.3,-0.2c0,-0.2 -0.8,-0.2 -1.7,-0.2 -2,0.2 -4,-0.5 -5.5,-1.8l-1,-1h1a17.8,17.8 0,0 0,9.5 -0.7c1.4,-0.4 2.8,-0.7 4.2,-0.8l2.4,-0.7 -0.5,1.4c-2.5,5.7 -3.6,7.8 -3.6,6.6ZM112.7,136.6c-0.2,-0.1 -0.3,-0.3 -0.2,-0.3 0.2,0 0,-0.2 -0.2,-0.4 -0.3,-0.2 -0.4,-0.4 -0.3,-0.4 0.2,0 0.2,0 0,-0.2 -1.1,-1.5 -2,-3.1 -2.5,-4.9 -0.1,-0.7 0,-1 0.4,-1.3 0.3,-0.2 0.6,-0.7 0.7,-1.2l1.2,-3c1.5,-3.3 2,-5 1.8,-6.4 0,-1 0.1,-1.6 1.2,-3.8a86,86 0,0 1,5.4 -10.5c0.5,0.7 1,1.4 1.3,2.2 0.8,1.4 1.4,2 1,2.5a97.7,97.7 0,0 0,-5 7.5c-0.7,1.4 -1.2,2.9 -1.3,4.5 0,0.4 1,2.2 2,4a224.4,224.4 0,0 1,3.5 6.2c0.3,0.2 0.7,0.8 0.9,1.3l0.7,1c0.2,0 0.4,0.6 0.4,1.2 0,1 0,1 -0.6,0.4 -0.3,-0.2 -1.2,-1.5 -2,-2.7 -1.4,-2.1 -1.5,-2.2 -1.6,-1.4 -0.1,0.7 -0.7,1.3 -2.6,2.8l-3,2.6c-0.7,0.7 -0.6,0.7 -1.2,0.3ZM136.7,130.2c-0.8,0 -1,-0.2 -1,-0.7 0,-0.7 0.2,-0.7 0.8,-0.5 0.4,0.2 1.5,0.3 2.4,0.3 0.9,0 2,-0.1 2.3,-0.3 0.7,-0.2 0.8,-0.2 0.8,0.4 0,0.6 -0.2,0.7 -1.3,0.9h-4ZM133.5,128.2c0,-0.8 0,-0.9 -0.8,-0.9s-0.9,0 -0.9,-1c0,-1.2 0.3,-1.2 1.1,0 0.4,0.7 1,1.2 1.6,1.7 1.3,0.8 1.3,1 0,1 -0.9,0 -1,0 -1,-0.8Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M75,126.6c0,-0.3 1,-1.8 1.2,-1.8l0.2,1c0,0.9 0,1 -0.7,1 -0.4,0 -0.7,-0.1 -0.7,-0.2Z"
android:fillColor="#00b2f7"/>
<path
android:pathData="M130.3,124.4a5,5 0,0 1,-0.1 -1.3c0,-0.6 -0.2,-0.8 -0.6,-0.8 -0.6,0 -0.8,-0.6 -0.8,-1.7 0,-0.7 -0.2,-0.8 -0.6,-0.8 -0.5,0 -0.6,-0.2 -0.6,-1 0,-0.6 0.1,-1 0.2,-1 0.3,0 4,6.5 4,6.8 0,0.4 -1.3,0.2 -1.5,-0.2ZM126.3,116.2c0,-1.2 0.2,-1.2 0.8,-0.1 0.7,1 0.7,1.1 -0.2,1.1 -0.6,0 -0.7,0 -0.7,-1ZM124.8,113.6v-1l0.7,0.8c1,1 0.9,1.3 0,1.3 -0.6,0 -0.7,-0.1 -0.7,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M72.2,92.4c-0.7,-0.6 -0.7,-0.8 -0.1,-0.8 0.1,0 0.4,0.3 0.5,0.6 0.2,0.8 0.2,0.9 -0.4,0.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M75,126.4c0.9,-1.3 1.2,-1.3 1.2,0 0,0.9 -0.1,1 -0.9,1h-0.8ZM81,116.5c0,-0.4 0.8,-1.8 1,-1.8 0.2,0 0.3,0.4 0.3,1 0,0.8 0,1 -0.7,1 -0.4,0 -0.7,-0.1 -0.7,-0.2Z"
android:fillColor="#00c8e6"/>
<path
android:pathData="M50.3,95.2a12,12 0,0 1,6.2 -10.4c1.9,-0.9 6.2,-1.7 6.4,-1.1 0,0.2 0.2,0.6 0.4,0.5 0.7,-0.3 0.5,0.1 -0.2,1 -0.4,0.5 -0.6,1 -0.5,1.3 0.2,0.7 -3.4,4.6 -5.7,6.1 -0.8,0.6 -1.4,1.1 -1.4,1.3 0,0.5 -4,2.3 -4.3,2 0,-0.3 -0.1,0.2 -0.4,0.5 -0.3,0.2 -0.5,-0.4 -0.5,-1.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="55.1"
android:startY="86.8"
android:endX="77.3"
android:endY="125.1"
android:type="linear">
<item android:offset="0" android:color="#FF00CCE6"/>
<item android:offset="1" android:color="#FF0082E7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M89,144.3c-0.2,-0.4 -0.2,-1.3 0,-3l0.2,-6.1c0,-2 0.1,-3.7 0.3,-3.8 0.3,-0.3 0.2,-0.7 -0.2,-0.7 -0.2,0 -1.1,1.1 -2,2.5 -2.7,4.2 -6,6.8 -8.8,6.8 -1,0 -1.2,0 -1,0.4 0,0.3 0,0.4 -0.4,0.4 -0.2,0 -1,0.5 -1.8,1.1 -0.6,0.6 -1.4,1.1 -2.2,1.6 -0.4,0.3 -0.8,0.7 -0.7,0.9 0.1,0.3 0,0.3 -0.5,0 -0.6,-0.2 -1.1,-1.1 -2.2,-3.4l-3.5,-8.5c5,0.8 11.7,0.3 11.7,0.3 2.2,-0.3 0.5,-1.8 2.6,-1.1 2.3,0.8 -0.7,2.8 1.4,1.4 0.6,-0.4 1.4,-0.3 1.7,-0.4 0.3,-0.2 0.7,0.6 0.7,0.4 0,-0.2 1,0.7 1.3,0.5 0.8,-0.6 1.1,-1.8 5.6,-9.5 2.3,-4 4.6,-7.9 7,-11.7 2.5,-4 2.6,-4.2 3.5,-4.2 0.8,0 0.9,0 0.9,1 0,0.4 -0.3,1.4 -0.7,2 -0.4,0.6 -0.7,1.4 -0.7,1.7 0,0.3 -0.3,1.3 -0.7,2.1a6,6 0,0 0,-0.7 2,83.7 83.7,0 0,0 -4.3,12.7c-0.7,2.2 -1.1,4.4 -1.2,6.6v2.4l-1.8,3.2c-1.5,2.5 -1.9,3 -2.4,3 -0.4,0 -0.8,-0.2 -1,-0.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M125,136.8a29.8,29.8 0,0 1,-6.2 -8.4,29 29,0 0,1 -3.7,-7.6 17,17 0,0 1,1.6 -5.3c1.1,-2.3 4.3,-7.8 4.6,-8.2 0.5,-0.4 0.6,-0.3 1.8,1.8 0.6,1.1 1.2,2 1,2a26,26 0,0 0,-4.5 7.8c-0.5,1.2 -1,2.5 -1.2,3.8 -0.3,1.5 -0.3,1.8 0.4,3.2l1.2,2 0.3,0.7c0,0.4 1.6,1 2.5,1 0.2,0 0.3,0.1 0.3,0.2 0,0.2 1.1,0 2.5,-0.2a42,42 0,0 1,5.2 -0.7c2.3,-0.2 2.8,-0.3 3,-0.7 0,-0.4 0.1,-0.1 1.6,0.4 2.6,0.8 6,1 8.4,-1 0.8,-0.6 0.8,-0.7 -1.6,4.3 -1.5,3.4 -2.2,4.6 -2.2,3.6 0,-0.4 -2.2,0 -4.6,0.7 -2.1,0.9 -4.3,1.2 -6.6,1.1 -0.7,0 -1.2,0 -1,0.1 0,0.2 -0.3,0.3 -0.7,0.3 -0.6,0 -1.3,-0.3 -2,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M131.2,126a4,4 0,0 1,-0.5 -1.8c0,-0.6 -0.1,-0.8 -0.5,-0.8 -0.6,0 -0.9,-0.5 -0.9,-1.7 0,-0.6 -0.1,-0.8 -0.5,-0.8 -0.6,0 -0.9,-0.6 -0.9,-1.7 0,-0.7 -0.1,-0.9 -0.5,-0.9 -0.6,0 -0.9,-0.5 -0.9,-1.7 0,-0.6 -0.1,-0.8 -0.5,-0.8 -0.3,0 -0.7,-0.2 -0.7,-0.4 -0.3,-0.7 -0.2,-2.1 0,-2.1s2,3 4,6.9c3.8,6.7 3.9,6.9 3.1,6.9 -0.6,0 -0.8,-0.3 -1.2,-1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M81.3,115.9c1,-2 1.3,-2.3 1.3,-0.8 0,0.9 0,1 -0.7,1 -0.4,0 -0.7,0 -0.6,-0.2Z"
android:fillColor="#00bff9"/>
<path
android:pathData="m119.8,129.8 l-2.3,-4c-1,-1.7 -1,-1.8 -0.5,-2.3 0.3,-0.4 0.5,-0.7 0.4,-0.9a15,15 0,0 1,1.6 -5l0.8,-1.8c0,-0.5 2.9,-6.4 3.2,-6.4 0.2,0 0.6,0.6 1,1.3 8.1,14.9 9.5,17 11.5,18 0.5,0.4 0.9,0.6 0.7,0.6l0.1,0.3a35.1,35.1 0,0 0,-12 1.2c-1.4,0.4 -1.6,0.4 -2,0 -0.1,-0.3 -0.4,-0.4 -0.5,-0.3l-0.6,-0.1c-0.4,-0.3 -0.4,-0.3 -0.2,0 0.3,0.5 0.5,1.7 0.3,1.7l-1.5,-2.3Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M66.8,130.2c-0.6,0 -0.8,-0.2 -0.8,-0.7 0,-0.7 0,-0.7 0.9,-0.4l2.8,0.2a6,6 0,0 0,3.3 -1l1.5,-1v0.9c0,0.6 -0.2,0.8 -0.5,0.8 -0.2,0 -0.4,0.1 -0.4,0.3 0,0.7 -4.2,1.3 -6.8,1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M137.2,129.9c0.2,-0.1 0.2,-0.3 0.1,-0.4h0.9c0.2,0 0.4,0.2 0.4,0.4 0,0.1 -0.4,0.3 -1,0.3s-0.7,-0.1 -0.4,-0.3Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="136.6"
android:centerY="119.2"
android:gradientRadius="32.3"
android:type="radial">
<item android:offset="0.2" android:color="#FF00CDFF"/>
<item android:offset="0.5" android:color="#FF00BCFA"/>
<item android:offset="0.8" android:color="#FF00ABF8"/>
<item android:offset="1" android:color="#FF0098F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M154.8,102.6c0.3,-0.5 -0.7,-0.7 -4.1,-0.7 -2,0 -4,-0.2 -5.8,-0.8a20,20 0,0 1,-8.2 -5.4l-1.7,-1.8 -0.6,0.7 -0.8,1.4 0.5,-1.3c0.9,-2.6 2.9,-6.3 4,-7.5 2.6,-2.7 6.3,-4 10,-3.5 6.1,1 10.3,6.8 9.4,12.9 -0.4,2 -1.7,5.2 -2,5.2 -0.3,0 -0.3,0.1 -0.2,0.3 0,0.3 0,0.5 -0.3,0.6h-0.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="130.7"
android:startY="124.8"
android:endX="152.9"
android:endY="86.6"
android:type="linear">
<item android:offset="0" android:color="#FF1964E7"/>
<item android:offset="1" android:color="#FF6884F2"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M82,135c-1.9,-0.3 -3.9,-0.4 -5.8,-0.5a58.4,58.4 0,0 1,-8.7 -0.7c-0.2,0 -0.5,-0.2 -0.6,-0.6 -0.2,-0.3 0.4,1.4 0.3,1.4 -0.2,0 -3.2,-6.8 -3.4,-7 0,0 0.7,0.2 1.5,0.7a7,7 0,0 0,5.9 0.9c2.5,-0.7 3.6,-2 7.7,-9.2 4.1,-7.3 4.6,-7.9 4.6,-6.3 0,1 -0.3,1.5 -0.9,1.5 -0.4,0 -0.5,0.2 -0.5,1 0,0.7 -0.2,1 -0.5,1 -0.2,0 -0.4,0.3 -0.4,0.6 0,0.8 -0.3,1.4 -0.7,1.4 -0.2,0 -0.4,0.2 -0.4,0.5 0,0.9 -0.3,1.5 -0.7,1.5 -0.3,0 -0.4,0.2 -0.4,0.5 0,0.8 -0.3,1.4 -0.8,1.4 -0.2,0 -0.4,0.3 -0.4,0.7 0,0.6 0.2,0.7 2.5,0.8l5.1,0.6c1.5,0.3 3.2,0.4 3.8,0.3 1,-0.2 1.1,-0.4 2.7,-3.2a39.2,39.2 0,0 1,2.4 -3.9c0,-0.3 0.3,-0.6 0.4,-0.6 0.2,0 0.3,-0.2 0.3,-0.4l0.4,-0.8 0.6,-1c0,-0.3 0.3,-0.6 0.4,-0.6 0.2,0 0.3,-0.2 0.3,-0.4 0,-0.3 0.2,-0.6 0.4,-0.8 0.2,-0.2 0.5,-0.7 0.5,-1 0.2,-0.4 0.4,-0.6 0.5,-0.6 0.2,0 0.3,-0.2 0.3,-0.5 0,-0.2 0.1,-0.4 0.3,-0.4l0.2,-0.4 0.4,-0.8 0.9,-1.4 1,-1.6 0.5,-0.8c0,-0.2 0.2,-0.3 0.3,-0.3 0.2,0 0.3,-0.2 0.3,-0.5 0,-0.2 0.2,-0.4 0.3,-0.4 0.2,0 0.3,-0.2 0.3,-0.4s0.1,-0.4 0.3,-0.4l0.2,-0.4c0,-0.3 0.2,-0.5 0.3,-0.5 0.2,0 0.3,-0.2 0.3,-0.4s0.2,-0.5 0.4,-0.6c0.2,0 0.4,-0.3 0.4,-0.5 0,-0.3 0.2,-0.4 0.3,-0.4 0.2,0 0.3,-0.2 0.3,-0.5 0,-0.2 0.2,-0.5 0.4,-0.5 0.3,-0.2 0.5,-0.4 0.5,-0.6 0,-0.2 0,-0.4 0.2,-0.4s0.3,-0.2 0.3,-0.4 0.2,-0.6 0.5,-0.8l0.9,-1c0.8,-1.7 2,-2.6 3.3,-2.6 0.6,0 0.9,0.2 1.2,0.8a2.4,2.4 0,0 0,3 1.4l2.3,-0.4c1.2,-0.2 1.2,-0.2 1.2,0.7 0,0.5 -0.3,1 -0.6,1.4a114,114 0,0 0,-11.8 18c-7.3,13 -13,23.4 -13.4,23.4 -0.1,0 -2.2,-7 -2,-7.3 0.1,-0.3 2,-2.3 1.9,-2.6 -0.2,-0.6 -3,1.1 -2.4,0.4 0.2,-0.3 4,-7.2 4.2,-8 1.4,-3.7 3,-7.4 4.9,-11 1.1,-2.1 7.4,-4 7.4,-4.1 0,-0.2 0.1,-0.3 0.3,-0.3l0.2,-0.6c0,-0.3 0.1,-0.5 0.3,-0.5 1,-1.4 1.8,-3 2.3,-4.6 0,-0.3 0.1,-0.5 0.3,-0.5 0.1,0 0.2,-0.2 0,-0.6 0,-0.3 0,-0.5 0.2,-0.5s0.3,-0.3 0.3,-0.6c0,-1 2,0.5 2.5,0.7 0.4,0.2 0.3,9.8 -1.2,0.3 0,-0.5 -1.5,1.4 -1.6,1 -0.2,-0.4 3,0.3 1.5,2 -4.2,5.2 -12.2,7.3 -19.8,20.3 -5.7,10 -6.6,11.2 -7.3,11 -0.3,0 -0.5,0 -0.5,0.2s-0.1,0.2 -0.3,0.1l-0.3,0.1c0,0.3 -0.4,0.3 -2.2,0Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M82,94.7c-1.6,-1 -3,-2.3 -3.8,-3.9l-0.8,-1.8 3.3,0.7H84l-0.2,1.3 -0.2,2.8c0,0.8 -0.1,1.5 -0.2,1.5a9,9 0,0 1,-1.3 -0.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="80.7"
android:endX="81.5"
android:endY="93.8"
android:type="linear">
<item android:offset="0" android:color="#FF40FAFD"/>
<item android:offset="1" android:color="#FF00E0FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M74.2,127.6c0.5,-0.6 2.6,-3.8 4.5,-7.2 7.8,-13.5 14,-24 15.3,-26a55,55 0,0 1,9 -9.2l2.1,-1.3 -0.8,1.2c-0.2,0.9 -0.5,1.8 -1,2.6 -1.1,2 -1.7,4.2 -1.7,6.5 0.3,1.4 1.2,3 2.1,3.4 0.9,0.5 1,0.5 2.6,-0.3 2.2,-1 2.8,-1.5 3.3,-2 0.2,-0.4 0.7,-0.6 1.3,-0.6 1,0 1,0 1,1 0,0.4 -0.1,0.6 -0.2,0.3 0,-0.2 -0.2,-0.4 -0.4,-0.4 -1.1,0 -8.4,10.6 -15.9,23.2 -4.8,8 -5.7,9.6 -5.3,8.5 0.3,-0.7 -0.1,-1.2 -0.6,-0.8 -0.3,0.3 -1,0.2 -3,-0.1a79,79 0,0 0,-8.5 -1c-0.5,0 -1,0.3 -1.8,1.2l-1.4,1.2 -0.9,0.4c-0.5,0.2 -0.4,0.1 0.3,-0.6ZM106,117.2c0.1,-0.4 0.4,-0.8 0.7,-1.1 0,0 -0.1,0.5 -0.5,1.1 -0.1,0.4 -0.4,0.8 -0.7,1.1l0.5,-1ZM107.4,114.7 L108.1,113.6 107.7,114.6 107,115.8c-0.1,0 0,-0.5 0.4,-1.1ZM108.5,112.7a117.6,117.6 0,0 1,6.5 -10.2,5 5,0 0,0 1,-2c0,-0.2 0.2,-0.4 0.4,-0.3 0.2,0.2 0.4,-0.3 0.3,-1.2 0,-0.2 0.2,-0.3 0.3,-0.3 0.4,0 1,-0.8 0.9,-1 -0.3,-0.3 -0.7,-0.2 -0.5,0.1 0,0.2 -0.2,0.2 -0.8,0.1 -0.6,-0.1 -0.8,0 -0.7,0.1 0.1,0.2 0,0.3 -0.4,0.2 -0.7,-0.2 -0.7,-1 0,-1 0.3,0 0.6,0 0.6,-0.2s0.1,-0.3 0.3,-0.3l2,-0.7a56,56 0,0 0,4.3 -2.2c0.4,-0.5 4,-4 -2.3,2.7 -0.3,0.3 -2.8,3.4 -3.2,3.7 -1,1.2 0,-0.2 0,-0.2l-1.8,2.6a94.5,94.5 0,0 0,-7 10.7c-0.2,0 0,-0.3 0.1,-0.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="98.9"
android:endX="104"
android:endY="137.8"
android:type="linear">
<item android:offset="0" android:color="#FF0CF4FF"/>
<item android:offset="0.3" android:color="#FF04EEFE"/>
<item android:offset="1" android:color="#FF00B1F7"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M83.3,91c0.1,-0.5 -2.5,-0.6 -3,-0.2 -0.4,0.3 -0.5,0.2 -0.5,0 0,-0.4 0,-0.4 -0.2,-0.1 -0.2,0.3 -0.4,0.3 -1,0 -1,-0.4 -1.7,-2.4 -1.6,-4.7 0.2,-4 2.9,-6.2 4.6,-6.3 1.4,-0.1 2.5,0 3.3,0.9 0.9,1 1.1,1.3 1.1,2.6 0,1 -0.3,2 -0.8,3.2 -0.5,1.1 -0.9,2.2 -1.2,3.4 -0.2,0.8 -0.5,1.5 -0.6,1.5 -0.2,0 -0.2,-0.1 -0.1,-0.3Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="81.5"
android:startY="80.7"
android:endX="81.5"
android:endY="93.8"
android:type="linear">
<item android:offset="0" android:color="#FF40FAFD"/>
<item android:offset="1" android:color="#FF00E0FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M92.2,85.4A14,14 0,0 1,91 79a17.5,17.5 0,0 1,4.6 -12.7l0.2,1c0,0.8 0,1 -0.6,1 -0.5,0 -0.5,0 -0.3,0.3 0.2,0.2 0.4,0.6 0.4,0.9 0,1.2 5.6,3.9 9.4,4.4 2.1,0.3 2.2,0.3 3.4,-0.4a5,5 0,0 1,2 -0.7c0.9,0 1,-0.1 1,-1 0,-0.6 0,-1 0.3,-1 0.2,0 0.5,-0.4 0.6,-0.8 0.1,-0.7 0.3,-0.9 1,-0.9 0.5,0 0.2,-2.9 0.2,-2.7 1.2,-0.2 -0.7,5 -3.6,7 -0.3,0 1.5,-0.5 1.5,-0.2 -0.2,0.7 -3.3,2.7 -6,3.8 -5.7,2.4 -10,5.2 -11.5,7.7 -0.7,1.1 -1,1.2 -1.4,0.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="102.3"
android:startY="62.1"
android:endX="102.3"
android:endY="84.3"
android:type="linear">
<item android:offset="0" android:color="#FF8EF6FD"/>
<item android:offset="1" android:color="#FF2BE8FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M111.6,96c0,-0.5 -0.6,-0.6 -1,-0.1 -0.3,0.3 -0.4,0.1 -0.4,-0.6 0,-0.8 0,-0.9 1,-0.9 0.9,0 1,0 1,1 0,0.6 -0.2,1 -0.3,1 -0.2,0 -0.3,-0.2 -0.3,-0.4Z"
android:fillColor="#59e9fe"/>
<path
android:pathData="M104.4,74.8c-1.5,-0.2 -3,-0.6 -4.5,-1 -2.7,-1 -5.4,-2.8 -5.5,-3.6 0,-0.4 -0.2,-0.7 -0.4,-0.7s-0.5,0.6 -0.6,0.5c-0.1,-0.1 0,-0.8 0.2,-0.9l0.2,-0.2 0.5,-1 0.7,-1c0.2,-0.2 1,-1.2 1.5,-1.2 0.3,0 1,0.4 1.8,1 2,1.3 4.2,2.2 6.6,2.7 1.5,0.3 2.1,0.2 4.5,-0.4 1.2,-0.3 2.3,-0.6 3.5,-0.7 0.6,0 0.7,0 0.7,1 0,0.6 -0.1,1 -0.3,0.8h-0.3l-0.1,1c0,0.3 -0.8,1.3 -1.6,2 -0.8,0.9 -1.4,1.3 -1.3,1 0.2,-0.5 0.1,-0.5 -0.7,0 -1.6,1 -2.2,1.1 -4.9,0.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="102.3"
android:startY="62.1"
android:endX="102.3"
android:endY="84.3"
android:type="linear">
<item android:offset="0" android:color="#FF8EF6FD"/>
<item android:offset="1" android:color="#FF2BE8FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M123.8,67.2c-3,-1.6 -3.7,-6.1 -0.9,-8.2 1,-0.7 3.3,-1.5 4,-1 0.7,0.8 0.5,1.2 2.2,1 0,0 1.4,1 1.5,2a4.9,4.9 0,0 1,-6.8 6.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="125.9"
android:startY="58.7"
android:endX="125.9"
android:endY="66.3"
android:type="linear">
<item android:offset="0" android:color="#FF92EEFE"/>
<item android:offset="1" android:color="#FF59E5FE"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M103.6,70.3a20,20 0,0 1,-6.2 -2.9c-1.1,-0.7 -1.4,-0.8 -1.9,-0.6 -1,0.7 -0.4,-0.2 1.3,-1.8 2.3,-2 5.1,-3.5 8.2,-4 5,-0.4 8.2,2.6 8.8,6.9 0.1,1 -0.6,3.2 -1.1,3.5 -0.6,0.4 -0.5,-0.1 -0.5,-0.3l0.2,-0.5c-0.2,0.4 0.3,-0.1 0.3,-0.7v-0.7l-2.5,0.7c-2.1,0.6 -4.4,0.8 -6.6,0.3Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="102.3"
android:startY="62.1"
android:endX="102.3"
android:endY="84.3"
android:type="linear">
<item android:offset="0" android:color="#FF8EF6FD"/>
<item android:offset="1" android:color="#FF2BE8FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M130,61c-0.7,-0.2 -1.6,-0.2 -2.4,-0.2 -2,0 -2.2,0 -3,-0.7 -0.3,-0.5 -1,-0.8 -1.3,-0.8 -0.8,0 0,-0.7 1.2,-1.2 1.2,-0.4 2.5,-0.3 3.6,0.3 1.3,0.7 2,1.4 2.2,2.3 0.1,0.6 0,0.7 -0.3,0.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="125.9"
android:startY="58.7"
android:endX="125.9"
android:endY="66.3"
android:type="linear">
<item android:offset="0" android:color="#FF92EEFE"/>
<item android:offset="1" android:color="#FF59E5FE"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M112.5,97.3a4,4 0,0 1,-1 -1.4c-0.2,-0.6 -1.6,0.1 -1.9,0.4 -0.4,0.3 0.9,-0.5 0.9,-1.2 0,-0.6 0.5,-1.4 2.6,-3.6 3.5,-3.8 5,-5 6.4,-5 1,0 1,0.1 1.2,1.1 0.4,2.6 -0.1,6.2 -1,7.2 -0.3,0.2 -0.4,0.7 -0.3,1 0.1,0.7 0,0.9 -1.1,1.3 -0.7,0.3 -2,0.5 -3.2,0.6 -1.7,0.1 -2,0 -2.6,-0.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="111.6"
android:startY="80.9"
android:endX="120"
android:endY="95.3"
android:type="linear">
<item android:offset="0" android:color="#FFA6FEFF"/>
<item android:offset="0.5" android:color="#FFBFFDFE"/>
<item android:offset="1" android:color="#FF97EDFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M118.5,96.6c0.2,-0.2 0,-0.2 -0.2,-0.1 -0.3,0.1 -0.4,0 -0.4,-0.2l0.3,-1.1c0,-0.4 0.3,-1 0.5,-1.2 1,-1 1.7,-5 1,-5.4 -0.1,0 -0.2,-0.4 -0.1,-0.7l-0.1,-0.5c-0.5,0 -3.1,2.3 -5.6,5l-2.6,2.7v-1c0,-1.1 0.4,-1.6 1.3,-1.6 0.5,0 0.7,-0.2 0.7,-0.8 0,-0.6 0.4,-1.2 1.5,-2.3l1.6,-1.4 1.4,-1.2a18,18 0,0 1,10 -4.6c2,-0.2 2,-0.2 2.8,0.5a3,3 0,0 1,0.8 2.8c-0.6,1.1 -1.4,2 -2.4,2.8l-5.3,5a22,22 0,0 1,-4 3.2c-1.4,0.6 -1.4,0.6 -1.2,0.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="111.6"
android:startY="80.9"
android:endX="120"
android:endY="95.3"
android:type="linear">
<item android:offset="0" android:color="#FFA6FEFF"/>
<item android:offset="0.5" android:color="#FFBFFDFE"/>
<item android:offset="1" android:color="#FF97EDFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M103.5,98.7c-1.2,-0.3 -2.3,-2 -2.6,-3.8 -0.3,-3.6 0.8,-7.1 3,-10 1.4,-1.7 7.2,-4.5 11.4,-5.5 6,-1.4 11.5,-0.5 14.4,2.3 1.2,1.2 1.9,2.3 1.9,3.3 0,0.7 -0.7,1.6 -1.2,1.6 -0.2,0 -0.1,-0.3 0.3,-0.6 0.7,-0.6 0.7,-1.4 0,-2.3 -0.4,-0.5 -0.8,-0.6 -2,-0.6 -4.5,0 -10,3.5 -15.5,9.8 -2.7,3.2 -5,5 -7.2,5.6 -1.4,0.5 -1.5,0.5 -2.5,0.2Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="111.6"
android:startY="80.9"
android:endX="120"
android:endY="95.3"
android:type="linear">
<item android:offset="0" android:color="#FFA6FEFF"/>
<item android:offset="0.5" android:color="#FFBFFDFE"/>
<item android:offset="1" android:color="#FF97EDFF"/>
</gradient>
</aapt:attr>
</path>
</vector>

View File

@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.71"
android:scaleY="0.71"
android:translateX="15.66"
android:translateY="15.66">
<path
android:pathData="M34.42,62.63C33.17,62.63 32.11,62.15 31.5,61.3L22.61,41.39C21.85,39.67 21.8,37.76 22.47,36.01C23.14,34.26 24.45,32.87 26.16,32.11C27.07,31.71 28.03,31.5 29.02,31.5C31.79,31.5 34.31,33.13 35.44,35.66L42.09,50.55L38.14,59.35C37.04,61.8 36.11,62.63 34.42,62.63H34.42Z"
android:fillColor="#005320"/>
<path
android:pathData="M73.59,62.63C71.9,62.63 70.96,61.8 69.87,59.35L65.92,50.54L72.57,35.66C73.69,33.13 76.21,31.5 78.98,31.5C79.97,31.5 80.93,31.71 81.84,32.11C83.55,32.88 84.86,34.26 85.53,36.01C86.2,37.76 86.15,39.67 85.39,41.39L76.5,61.3C75.89,62.15 74.83,62.63 73.59,62.63Z"
android:fillColor="#005320"/>
<path
android:pathData="M69.36,72.38C67.68,72.38 66.74,71.55 65.64,69.1L58.45,53.04C57.88,51.77 56.7,49.11 54,49.11C51.31,49.11 50.08,51.87 49.55,53.04L42.36,69.09C41.27,71.55 40.33,72.38 38.65,72.38C37.43,72.38 36.26,71.85 35.64,71.04C35.58,70.92 35.53,70.81 35.47,70.68C34.25,68.08 33.09,65.25 32.31,63.29C32.94,63.57 33.65,63.72 34.42,63.72C36.89,63.72 38.05,62.22 39.13,59.79L47.55,41.01C48.68,38.48 51.2,36.85 53.97,36.85H54.03C56.8,36.85 59.32,38.48 60.45,41.01L68.88,59.8C69.96,62.22 71.13,63.72 73.59,63.72C74.36,63.72 75.07,63.57 75.7,63.29C74.92,65.25 73.76,68.08 72.54,70.69C72.48,70.81 72.43,70.92 72.37,71.04C71.75,71.86 70.58,72.38 69.36,72.38H69.36Z"
android:fillColor="#005320"/>
<path
android:pathData="M65.27,76.3C63.24,76.26 61.24,75.34 59.93,73.84C59.51,73.34 59.13,72.74 58.82,72.08C58.82,72.08 56.53,66.88 54.5,62.29L54.37,61.99L54.01,61.13L54,61.16L53.99,61.13L53.63,61.99L53.5,62.29C51.46,66.88 49.17,72.1 49.17,72.1C48.86,72.74 48.49,73.33 48.06,73.85C46.76,75.34 44.77,76.26 42.73,76.3H42.69C40.89,76.23 39.39,75.65 38.1,74.52C37.69,74.14 37.3,73.69 36.92,73.18C37.46,73.36 38.04,73.46 38.64,73.46C41.1,73.46 42.26,71.96 43.34,69.53L50.53,53.48C51.04,52.33 52,50.19 54,50.19C56,50.19 56.95,52.33 57.47,53.48L64.65,69.54C65.73,71.96 66.9,73.46 69.36,73.46C69.96,73.46 70.54,73.36 71.08,73.18C70.7,73.69 70.3,74.15 69.89,74.53C68.61,75.65 67.11,76.23 65.31,76.3H65.27V76.3Z"
android:fillColor="#005320"/>
</group>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More