├── .github
├── ISSUE_TEMPLATE
│ └── 01_bug_report.yml
└── workflows
│ └── android.yml
├── .gitignore
├── .kotlin
└── sessions
│ └── kotlin-compiler-13018979230585017163.salive
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── github
│ └── res
│ │ └── xml
│ │ └── accessibility_service.xml
│ ├── google
│ └── res
│ │ └── xml
│ │ └── placeholder_service.xml
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── com
│ │ └── eightbit
│ │ │ ├── app
│ │ │ └── CoverOptions.kt
│ │ │ ├── content
│ │ │ └── ScaledContext.kt
│ │ │ ├── io
│ │ │ └── Debug.kt
│ │ │ ├── material
│ │ │ └── IconifiedSnackbar.kt
│ │ │ ├── net
│ │ │ └── JSONExecutor.kt
│ │ │ ├── os
│ │ │ └── Version.kt
│ │ │ ├── pm
│ │ │ └── PackageRetriever.kt
│ │ │ ├── samsprung
│ │ │ ├── AccessibilityObserver.kt
│ │ │ ├── LayoutStateChangeCallback.kt
│ │ │ ├── NotificationReceiver.kt
│ │ │ ├── OnBroadcastService.kt
│ │ │ ├── SamSprung.kt
│ │ │ ├── SamSprungOverlay.kt
│ │ │ ├── drawer
│ │ │ │ ├── AppDisplayListener.kt
│ │ │ │ ├── AppDrawerFragment.kt
│ │ │ │ ├── CoverStateAdapter.kt
│ │ │ │ ├── DrawerAppAdapter.kt
│ │ │ │ ├── LauncherManager.kt
│ │ │ │ ├── NotificationAdapter.kt
│ │ │ │ ├── NotificationFragment.kt
│ │ │ │ ├── OrientationManager.kt
│ │ │ │ ├── PanelViewFragment.kt
│ │ │ │ ├── PanelWidgetManager.kt
│ │ │ │ └── panels
│ │ │ │ │ ├── DesktopBinder.kt
│ │ │ │ │ ├── PanelWidgetInfo.kt
│ │ │ │ │ ├── WidgetHost.kt
│ │ │ │ │ ├── WidgetHostView.kt
│ │ │ │ │ ├── WidgetInfo.kt
│ │ │ │ │ ├── WidgetModel.kt
│ │ │ │ │ ├── WidgetPreviews.kt
│ │ │ │ │ ├── WidgetProvider.java
│ │ │ │ │ └── WidgetSettings.kt
│ │ │ ├── settings
│ │ │ │ ├── CoverPreferences.kt
│ │ │ │ ├── DonationManager.kt
│ │ │ │ ├── FilteredAppsAdapter.kt
│ │ │ │ └── Preferences.kt
│ │ │ ├── speech
│ │ │ │ └── VoiceRecognizer.kt
│ │ │ └── update
│ │ │ │ ├── UpdateManager.kt
│ │ │ │ ├── UpdateReceiver.kt
│ │ │ │ └── UpdateShimActivity.kt
│ │ │ ├── view
│ │ │ ├── AnimatedLinearLayout.kt
│ │ │ └── OnSwipeTouchListener.kt
│ │ │ ├── viewpager
│ │ │ ├── CardFlipTransformer.kt
│ │ │ ├── ClockSpinTransformer.kt
│ │ │ ├── DepthTransformer.kt
│ │ │ ├── FidgetSpinTransformer.kt
│ │ │ ├── PopTransformer.kt
│ │ │ ├── SpinnerTransformer.kt
│ │ │ └── TossTransformer.kt
│ │ │ └── widget
│ │ │ ├── NestedScrollableHost.kt
│ │ │ └── RecyclerViewTouch.kt
│ └── eightbitlab
│ │ └── com
│ │ └── blurview
│ │ ├── BlurAlgorithm.kt
│ │ ├── BlurController.kt
│ │ ├── BlurView.kt
│ │ ├── BlurViewCanvas.kt
│ │ ├── BlurViewFacade.kt
│ │ ├── NoOpController.kt
│ │ ├── PreDrawBlurController.kt
│ │ ├── RenderEffectBlur.kt
│ │ ├── RenderScriptBlur.kt
│ │ └── SizeScaler.kt
│ └── res
│ ├── color
│ ├── primary_text_dark.xml
│ └── primary_text_light.xml
│ ├── drawable-night-v21
│ └── button_rippled.xml
│ ├── drawable-night
│ ├── ic_bluetooth_off_24dp.xml
│ ├── ic_bluetooth_on_24dp.xml
│ ├── ic_cancel_presentation_24dp.xml
│ ├── ic_delete_forever_24dp.xml
│ ├── ic_do_not_disturb_off_24dp.xml
│ ├── ic_do_not_disturb_on_24dp.xml
│ ├── ic_expand_20dp.xml
│ ├── ic_fingerprint_24dp.xml
│ ├── ic_flashlight_off_24dp.xml
│ ├── ic_flashlight_on_24dp.xml
│ ├── ic_github_octocat_24dp.xml
│ ├── ic_insert_page_break_24dp.xml
│ ├── ic_keyboard_24dp.xml
│ ├── ic_launch_24dp.xml
│ ├── ic_menu_24.xml
│ ├── ic_move_up_20dp.xml
│ ├── ic_nfc_off_24dp.xml
│ ├── ic_nfc_on_24dp.xml
│ ├── ic_record_voice_over_24dp.xml
│ ├── ic_samsprung_24dp.xml
│ ├── ic_screen_lock_rotation_24.xml
│ ├── ic_screen_rotation_24.xml
│ ├── ic_send_24dp.xml
│ ├── ic_software_update_24.xml
│ ├── ic_sound_off_24dp.xml
│ ├── ic_sound_on_24dp.xml
│ ├── ic_support_required_24dp.xml
│ ├── ic_swipe_down_24dp.xml
│ ├── ic_voice_over_off_24dp.xml
│ ├── ic_wallpaper_24dp.xml
│ ├── ic_widgets_24dp.xml
│ ├── ic_wifi_off_24dp.xml
│ ├── ic_wifi_on_24dp.xml
│ ├── rounded_layout.xml
│ └── rounded_layout_themed.xml
│ ├── drawable-v21
│ └── button_rippled.xml
│ ├── drawable
│ ├── bg_appwidget_error.9.png
│ ├── card_foreground.xml
│ ├── card_foreground_selector.xml
│ ├── ic_arrow_back_24dp.xml
│ ├── ic_bluetooth_off_24dp.xml
│ ├── ic_bluetooth_on_24dp.xml
│ ├── ic_cancel_presentation_24dp.xml
│ ├── ic_delete_forever_24dp.xml
│ ├── ic_do_not_disturb_off_24dp.xml
│ ├── ic_do_not_disturb_on_24dp.xml
│ ├── ic_expand_20dp.xml
│ ├── ic_fingerprint_24dp.xml
│ ├── ic_flashlight_off_24dp.xml
│ ├── ic_flashlight_on_24dp.xml
│ ├── ic_github_octocat_24dp.xml
│ ├── ic_github_sponsor_24dp.xml
│ ├── ic_google_play_24dp.xml
│ ├── ic_home_24dp.xml
│ ├── ic_insert_page_break_24dp.xml
│ ├── ic_keyboard_24dp.xml
│ ├── ic_launch_24dp.xml
│ ├── ic_launcher_background.png
│ ├── ic_launcher_foreground.png
│ ├── ic_menu_24.xml
│ ├── ic_move_up_20dp.xml
│ ├── ic_nfc_off_24dp.xml
│ ├── ic_nfc_on_24dp.xml
│ ├── ic_paypal_donation.xml
│ ├── ic_record_voice_over_24dp.xml
│ ├── ic_samsprung_24dp.xml
│ ├── ic_screen_lock_rotation_24.xml
│ ├── ic_screen_rotation_24.xml
│ ├── ic_send_24dp.xml
│ ├── ic_settings_24dp.xml
│ ├── ic_software_update_24.xml
│ ├── ic_sound_off_24dp.xml
│ ├── ic_sound_on_24dp.xml
│ ├── ic_support_required_24dp.xml
│ ├── ic_swipe_down_24dp.xml
│ ├── ic_voice_over_off_24dp.xml
│ ├── ic_wallpaper_24dp.xml
│ ├── ic_widget_preview.png
│ ├── ic_widgets_24dp.xml
│ ├── ic_wifi_off_24dp.xml
│ ├── ic_wifi_on_24dp.xml
│ ├── notification_badge.xml
│ ├── rounded_layout.xml
│ ├── rounded_layout_themed.xml
│ └── widget_preview_tile.png
│ ├── layout
│ ├── appwidget_error.xml
│ ├── button_cancel_sub.xml
│ ├── button_paypal.xml
│ ├── button_sponsor.xml
│ ├── color_panel.xml
│ ├── configure_switch.xml
│ ├── donation_layout.xml
│ ├── drawer_apps_card.xml
│ ├── drawer_apps_icon.xml
│ ├── dropdown_item_1.xml
│ ├── filtered_apps_item.xml
│ ├── fingerprint_auth.xml
│ ├── fragment_drawer.xml
│ ├── fragment_notices.xml
│ ├── fragment_panel.xml
│ ├── home_main_view.xml
│ ├── navigation_menu.xml
│ ├── notification_card.xml
│ ├── notification_reply.xml
│ ├── panel_picker_view.xml
│ ├── preferences_layout.xml
│ ├── prefs_drawer.xml
│ ├── prefs_general.xml
│ ├── prefs_permissions.xml
│ ├── social_menu_bar.xml
│ ├── system_menu.xml
│ ├── toggle_state_icon.xml
│ ├── toolbar_options.xml
│ └── widget_preview.xml
│ ├── menu
│ ├── cover_quick_toggles.xml
│ └── cover_settings_menu.xml
│ ├── mipmap-anydpi-v26
│ ├── sprung_icon.xml
│ └── sprung_icon_round.xml
│ ├── mipmap-hdpi
│ ├── sprung_icon.png
│ ├── sprung_icon_background.png
│ ├── sprung_icon_foreground.png
│ └── sprung_icon_round.png
│ ├── mipmap-mdpi
│ ├── sprung_icon.png
│ ├── sprung_icon_background.png
│ ├── sprung_icon_foreground.png
│ └── sprung_icon_round.png
│ ├── mipmap-xhdpi
│ ├── sprung_icon.png
│ ├── sprung_icon_background.png
│ ├── sprung_icon_foreground.png
│ └── sprung_icon_round.png
│ ├── mipmap-xxhdpi
│ ├── sprung_icon.png
│ ├── sprung_icon_background.png
│ ├── sprung_icon_foreground.png
│ └── sprung_icon_round.png
│ ├── mipmap-xxxhdpi
│ ├── sprung_icon.png
│ ├── sprung_icon_background.png
│ ├── sprung_icon_foreground.png
│ └── sprung_icon_round.png
│ ├── raw
│ └── display_settings.xml
│ ├── values-de
│ └── strings.xml
│ ├── values-es
│ └── strings.xml
│ ├── values-fr
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-ko
│ └── strings.xml
│ ├── values-night
│ ├── colors.xml
│ └── themes.xml
│ ├── values-pl
│ └── strings.xml
│ ├── values
│ ├── accessibility.xml
│ ├── arrays.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── donottranslate.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── themes.xml
│ └── xml
│ ├── extraction_content.xml
│ ├── file_provider_paths.xml
│ └── full_backup_content.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.github/ISSUE_TEMPLATE/01_bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Report a Problem
2 | description: File a bug report
3 | title: "[Issue]: "
4 | labels: ["Entomology"]
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Please provide as much detail as possible
10 | - type: textarea
11 | id: what-happened
12 | attributes:
13 | label: Issue Description
14 | description: Please describe the issue in your own words
15 | placeholder: This is how you would see the problem again
16 | validations:
17 | required: true
18 | - type: textarea
19 | id: logcat
20 | attributes:
21 | label: Logcat Output
22 | description: Long press inside this box and select "Paste"
23 | placeholder: This is a logcat, not a secondary description
24 | render: shell
25 | validations:
26 | required: true
27 | - type: checkboxes
28 | id: requirements
29 | attributes:
30 | label: Guide Confirmation
31 | description: By submitting this issue, you confirm checking the [guide](https://samsprung.github.io/launcher/index.html) for SamSprung TooUI
32 | options:
33 | - label: I have reviewed the guide and included valid logcat content
34 | required: true
35 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on:
4 | push:
5 | branches: [ launcher ]
6 |
7 | permissions:
8 | contents: read
9 | actions: write
10 |
11 | jobs:
12 | clean:
13 | runs-on: ubuntu-latest
14 | timeout-minutes: 2
15 |
16 | steps:
17 | - name: Remove artifacts
18 | continue-on-error: true
19 | uses: c-hive/gha-remove-artifacts@v1.3.0
20 | with:
21 | age: '2 days' # ' ', parsed by Moment.js
22 |
23 | - name: Purge cache
24 | continue-on-error: true
25 | uses: MyAlbum/purge-cache@v1
26 | with:
27 | max-age: 172800 # 2 days, default: 7 days since last use
28 |
29 | build:
30 | runs-on: ubuntu-latest
31 |
32 | steps:
33 | - uses: actions/checkout@v4
34 | with:
35 | submodules: recursive
36 | - name: set up JDK 17
37 | uses: actions/setup-java@v4
38 | with:
39 | java-version: '17'
40 | distribution: 'temurin'
41 | cache: gradle
42 |
43 | - name: Grant execute permission for gradlew
44 | run: chmod +x gradlew
45 | - name: Build with Gradle
46 | run: ./gradlew assembleGithubRelease
47 |
48 | - uses: r0adkll/sign-android-release@v1
49 | name: Sign app APK
50 | # ID used to access action output
51 | id: sign_app
52 | with:
53 | releaseDirectory: app/build/outputs/apk/github/release
54 | signingKeyBase64: ${{ secrets.KEYSTORE }}
55 | alias: ${{ secrets.KEY_ALIAS }}
56 | keyStorePassword: ${{ secrets.STOREPASS }}
57 | keyPassword: ${{ secrets.KEYPASS }}
58 | env:
59 | # override default build-tools version (29.0.3) -- optional
60 | BUILD_TOOLS_VERSION: "34.0.0"
61 |
62 | - name: Retrieve commit identification
63 | run: |
64 | GIT_BRANCH=$(git name-rev --name-only HEAD)
65 | echo "GIT_BRANCH=${GIT_BRANCH}" >> $GITHUB_ENV
66 | GIT_HASH=$(git rev-parse --short HEAD)
67 | echo "GIT_HASH=${GIT_HASH}" >> $GITHUB_ENV
68 |
69 | - uses: actions/upload-artifact@v4
70 | with:
71 | name: SamSprung-${{ env.GIT_HASH }}
72 | retention-days: 1
73 | path: ${{steps.sign_app.outputs.signedReleaseFile}}
74 |
75 | - uses: SamSprung/action-github-releases@v1.0.0
76 | if: ${{ github.event_name != 'pull_request' }}
77 | with:
78 | repo_token: "${{ secrets.GITHUB_TOKEN }}"
79 | automatic_release_tag: "sideload"
80 | prerelease: ${{ env.GIT_BRANCH != 'launcher' }}
81 | title: SamSprung-${{ env.GIT_HASH }}
82 | files: ${{steps.sign_app.outputs.signedReleaseFile}}
83 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.orig
3 |
4 | local.properties
5 | keystore.properties
6 | *.iml
7 |
8 | .cxx
9 | .externalNativeBuild
10 | .gradle
11 | .idea
12 |
13 | captures
14 | build
15 | release
16 |
--------------------------------------------------------------------------------
/.kotlin/sessions/kotlin-compiler-13018979230585017163.salive:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/.kotlin/sessions/kotlin-compiler-13018979230585017163.salive
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2012-2024 AbandonedCart. All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | *
9 | * For the purpose of this license, the phrase "GitHub labels" shall be
10 | * used to refer to "AbandonedCart", "TwistedUmbrella", "SamSprung",
11 | * and "TagMo" such that these entities are collectively considered the
12 | * equivalent of any usage of the aforementioned phrase.
13 | *
14 | * 1. Redistributions of source code must retain the above copyright
15 | * notice, this list of conditions and the following disclaimer.
16 | *
17 | * 2. Redistributions in binary form must reproduce the above copyright
18 | * notice, this list of conditions and the following disclaimer in
19 | * the documentation and/or other materials provided with the
20 | * distribution.
21 | *
22 | * 3. All materials mentioning features or use of this software and
23 | * redistributions of any form whatsoever must display the following
24 | * acknowledgment unless made available by tagged, public "commits":
25 | * "This product includes software developed by AbandonedCart"
26 | *
27 | * 4. The GitHub labels must not be used in any form to endorse or promote
28 | * products derived from this software without prior written permission.
29 | * For written permission, please contact enderinexiledc@gmail.com
30 | *
31 | * 5. Products derived from this software may not be called by the GitHub
32 | * labels nor may these labels appear in their names or product details
33 | * without prior written permission of AbandonedCart.
34 | *
35 | * THIS SOFTWARE IS PROVIDED BY AbandonedCart ``AS IS'' AND ANY
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 | * OF THE POSSIBILITY OF SUCH DAMAGE.
47 | * ====================================================================
48 | *
49 | * The license and distribution terms for any publicly available version or
50 | * derivative of this code cannot be changed. i.e. this code cannot simply be
51 | * copied and put under another distribution license
52 | * [including the GNU Public License.] Content not subject to these terms is
53 | * subject to to the terms and conditions of the Apache License, Version 2.0.
54 | */
55 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | -dontobfuscate
9 | -optimizations !code/allocation/variable
10 |
11 | # If your project uses WebView with JS, uncomment the following
12 | # and specify the fully qualified class name to the JavaScript interface
13 | # class:
14 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
15 | # public *;
16 | #}
17 |
18 | # Uncomment this to preserve the line number information for
19 | # debugging stack traces.
20 | -keepattributes *Annotation*,SourceFile,LineNumberTable
21 |
22 | # If you keep the line number information, uncomment this to
23 | # hide the original source file name.
24 | #-renamesourcefileattribute SourceFile
25 |
26 | -keep class com.google.android.material.R$drawable { *; }
--------------------------------------------------------------------------------
/app/src/github/res/xml/accessibility_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/google/res/xml/placeholder_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/app/CoverOptions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.app
16 |
17 | import android.app.ActivityOptions
18 | import android.content.Intent
19 | import android.graphics.Rect
20 | import android.view.View
21 | import androidx.core.app.ActivityOptionsCompat
22 |
23 | class CoverOptions(private var bounds: Rect?) {
24 |
25 | fun getActivityOptions(display: Int): ActivityOptions {
26 | return ActivityOptions.makeBasic().setLaunchDisplayId(display).setLaunchBounds(bounds)
27 | }
28 |
29 | fun getAnimatedOptions(display: Int, anchor: View?, intent: Intent?): ActivityOptions {
30 | return intent?.sourceBounds?.let { bounds ->
31 | ActivityOptions.makeScaleUpAnimation(
32 | anchor,
33 | bounds.left,
34 | bounds.top,
35 | bounds.width(),
36 | bounds.height()
37 | ).setLaunchDisplayId(display).setLaunchBounds(bounds)
38 | } ?: getActivityOptions(display)
39 | }
40 |
41 | fun getActivityOptionsCompat(display: Int): ActivityOptionsCompat {
42 | return ActivityOptionsCompat.makeBasic().setLaunchDisplayId(display).setLaunchBounds(bounds)
43 | }
44 |
45 | fun getAnimatedOptionsCompat(display: Int, anchor: View, intent: Intent?): ActivityOptionsCompat {
46 | return intent?.sourceBounds?.let { bounds ->
47 | ActivityOptionsCompat.makeScaleUpAnimation(
48 | anchor,
49 | bounds.left,
50 | bounds.top,
51 | bounds.width(),
52 | bounds.height()
53 | ).setLaunchDisplayId(display).setLaunchBounds(bounds)
54 | } ?: getActivityOptionsCompat(display)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/os/Version.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2023 AbandonedCart. All rights reserved.
4 | *
5 | * https://github.com/AbandonedCart/AbandonedCart/blob/main/LICENSE#L4
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.os
16 |
17 | import android.os.Build
18 |
19 | object Version {
20 |
21 | /**
22 | * Android 12, API 31
23 | */
24 | @JvmStatic
25 | val isSnowCone: Boolean get() {
26 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
27 | }
28 |
29 | /**
30 | * Android 13, API 33
31 | */
32 | @JvmStatic
33 | val isTiramisu: Boolean get() {
34 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
35 | }
36 |
37 | /**
38 | * Android 14, API 34
39 | */
40 | @JvmStatic
41 | val isUpsideDownCake: Boolean get() {
42 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/AccessibilityObserver.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung
16 |
17 | import android.accessibilityservice.AccessibilityService
18 | import android.accessibilityservice.AccessibilityServiceInfo
19 | import android.content.Context
20 | import android.content.Intent
21 | import android.provider.Settings
22 | import android.view.WindowManager
23 | import android.view.accessibility.AccessibilityEvent
24 | import java.io.File
25 |
26 | class AccessibilityObserver : AccessibilityService() {
27 |
28 | companion object {
29 | private lateinit var observerInstance: AccessibilityObserver
30 | private var isConnected: Boolean = false
31 | fun getInstance() : AccessibilityObserver? {
32 | return if (isConnected) observerInstance else null
33 | }
34 | fun hasEnabledService(context: Context): Boolean {
35 | if (BuildConfig.GOOGLE_PLAY) return false
36 | val serviceString = Settings.Secure.getString(context.contentResolver,
37 | Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
38 | )
39 | return serviceString?.contains(context.packageName
40 | + File.separator + AccessibilityObserver::class.java.name) == true
41 | }
42 | fun performBackAction() {
43 | getInstance()?.performGlobalAction(GLOBAL_ACTION_BACK)
44 | }
45 |
46 | fun getWindowManager() : WindowManager {
47 | return getInstance()?.getSystemService(WINDOW_SERVICE) as WindowManager
48 | }
49 | }
50 |
51 | init {
52 | observerInstance = this
53 | }
54 |
55 | override fun onServiceConnected() {
56 | val info = AccessibilityServiceInfo()
57 | info.packageNames = arrayOf(packageName)
58 | info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED
59 | info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
60 | info.notificationTimeout = 100
61 | serviceInfo = info
62 | isConnected = true
63 | }
64 |
65 | override fun onAccessibilityEvent(event: AccessibilityEvent) { }
66 |
67 | override fun onInterrupt() {
68 | if (null == getInstance()) observerInstance = this
69 | }
70 |
71 | override fun onUnbind(intent: Intent?): Boolean {
72 | isConnected = false
73 | return super.onUnbind(intent)
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/LayoutStateChangeCallback.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.samsprung
2 |
3 | import androidx.core.util.Consumer
4 | import androidx.window.layout.FoldingFeature
5 | import androidx.window.layout.WindowLayoutInfo
6 |
7 | class LayoutStateChangeCallback : Consumer {
8 |
9 | interface FoldingFeatureListener {
10 | fun onHalfOpened()
11 | fun onSeparating()
12 | fun onFlat()
13 | fun onNormal()
14 | }
15 |
16 | private var listener: FoldingFeatureListener? = null
17 |
18 | fun setListener(listener: FoldingFeatureListener) {
19 | this.listener = listener
20 | }
21 |
22 | override fun accept(newLayoutInfo: WindowLayoutInfo) {
23 | for (feature in newLayoutInfo.displayFeatures) {
24 | if (feature is FoldingFeature) {
25 | when (feature.state) {
26 | FoldingFeature.State.HALF_OPENED -> {
27 | listener?.onHalfOpened()
28 | }
29 | FoldingFeature.State.FLAT -> {
30 | if (feature.isSeparating) {
31 | listener?.onSeparating()
32 | } else {
33 | listener?.onFlat()
34 | }
35 | }
36 | else -> {
37 | listener?.onNormal()
38 | }
39 | }
40 | }
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/SamSprung.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung
16 |
17 | import android.app.Application
18 | import android.app.KeyguardManager
19 | import androidx.appcompat.app.AppCompatDelegate
20 | import com.eightbit.io.Debug
21 | import com.eightbit.samsprung.drawer.OrientationManager
22 | import com.eightbit.samsprung.settings.Preferences
23 | import java.io.PrintWriter
24 | import java.io.StringWriter
25 | import kotlin.system.exitProcess
26 |
27 | const val organization = "SamSprung"
28 |
29 | class SamSprung : Application() {
30 |
31 | fun setThemePreference() {
32 | when (getSharedPreferences(Preferences.prefsValue, MODE_PRIVATE).getInt(Preferences.prefThemes, 0)) {
33 | 0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
34 | 1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
35 | 2 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
36 | }
37 | }
38 |
39 | companion object {
40 | const val provider: String = "${BuildConfig.APPLICATION_ID}.provider"
41 | const val updating: String = "${BuildConfig.APPLICATION_ID}.UPDATING"
42 | const val services: String = "${BuildConfig.APPLICATION_ID}.SERVICES"
43 | const val launcher: String = "${BuildConfig.APPLICATION_ID}.LAUNCHER"
44 |
45 | const val request_code = 8675309
46 | const val notification = request_code.toString()
47 |
48 | var hasSubscription = false
49 |
50 | private const val commitHash = "#${BuildConfig.COMMIT}"
51 | val versionLabel = "$organization ${BuildConfig.VERSION_NAME} (${
52 | if (BuildConfig.GOOGLE_PLAY) "Play" else "GitHub"
53 | } ${
54 | if (BuildConfig.BUILD_TYPE == "release") "Release" else "Debug"
55 | }) $commitHash"
56 | }
57 |
58 | override fun onCreate() {
59 | super.onCreate()
60 | AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
61 |
62 | Thread.setDefaultUncaughtExceptionHandler { _: Thread?, error: Throwable ->
63 | val exception = StringWriter()
64 | error.printStackTrace(PrintWriter(exception))
65 | try {
66 | OrientationManager(this).removeOrientationLayout()
67 | } catch (_: Exception) { }
68 | try {
69 | Debug(this).processException(
70 | with (getSystemService(KEYGUARD_SERVICE) as KeyguardManager) { isDeviceSecure },
71 | exception.toString()
72 | )
73 | } catch (_: Exception) { }
74 | // Unrecoverable error encountered
75 | android.os.Process.killProcess(android.os.Process.myPid())
76 | exitProcess(-1)
77 | }
78 |
79 | setThemePreference()
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/CoverStateAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung.drawer
16 |
17 | import androidx.appcompat.app.AppCompatActivity
18 | import androidx.fragment.app.Fragment
19 | import androidx.viewpager2.adapter.FragmentStateAdapter
20 |
21 | class CoverStateAdapter(fragmentActivity: AppCompatActivity) : FragmentStateAdapter(fragmentActivity) {
22 | private val mFragments: ArrayList = arrayListOf()
23 | private val mFragmentIDs: ArrayList = arrayListOf()
24 | private val noticeList = NotificationFragment()
25 | private val appDrawer = AppDrawerFragment()
26 |
27 | fun addFragment() : Int {
28 | val fragment = PanelViewFragment()
29 | val position = mFragmentIDs.size + 2
30 | mFragments.add(fragment)
31 | notifyItemInserted(position)
32 | mFragmentIDs.add(position)
33 | return position
34 | }
35 |
36 | fun removeFragment(fragmentID: Int) {
37 | val position = fragmentID - 2
38 | mFragments.removeAt(position)
39 | mFragmentIDs.removeAt(position)
40 | mFragments.trimToSize()
41 | mFragmentIDs.trimToSize()
42 | notifyItemRemoved(fragmentID)
43 | }
44 |
45 | fun getFragment(fragmentID: Int) : PanelViewFragment {
46 | return mFragments[fragmentID - 2]
47 | }
48 |
49 | override fun createFragment(position: Int): Fragment {
50 | return when (position) {
51 | 0 -> noticeList
52 | 1 -> appDrawer
53 | else -> mFragments[position - 2]
54 | }
55 | }
56 |
57 | override fun getItemId(position: Int): Long {
58 | return if (position < 2) position.toLong() else mFragmentIDs[position - 2].toLong()
59 | }
60 |
61 | override fun getItemCount(): Int {
62 | return mFragmentIDs.size + 2
63 | }
64 |
65 | override fun containsItem(itemId: Long): Boolean {
66 | return mFragmentIDs.contains(itemId.toInt())
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/OrientationManager.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.samsprung.drawer
2 |
3 | import android.content.Context
4 | import android.content.pm.ActivityInfo
5 | import android.graphics.PixelFormat
6 | import android.view.View
7 | import android.view.WindowManager
8 | import android.widget.LinearLayout
9 | import java.lang.ref.SoftReference
10 |
11 | class OrientationManager(context: Context) {
12 |
13 | private val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
14 | private val orientationManager = LinearLayout(context)
15 |
16 | private val orientationLayout = WindowManager.LayoutParams(
17 | WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
18 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
19 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
20 | PixelFormat.TRANSPARENT
21 | )
22 |
23 | companion object {
24 | private var orientationView: SoftReference? = null
25 | }
26 |
27 | fun addOrientationLayout(orientation: Int) {
28 | orientationLayout.screenOrientation = orientation
29 | windowManager.addView(orientationManager, orientationLayout)
30 | orientationManager.visibility = View.VISIBLE
31 | orientationView = SoftReference(orientationManager)
32 | }
33 |
34 | fun removeOrientationLayout() {
35 | try {
36 | orientationView?.let {
37 | orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
38 | windowManager.updateViewLayout(it.get(), orientationLayout)
39 | try {
40 | windowManager.removeViewImmediate(it.get())
41 | } catch (_: Exception) {
42 | try { windowManager.removeView(it.get()) } catch (_: Exception) { }
43 | }
44 | } ?: windowManager.run {
45 | orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
46 | updateViewLayout(orientationManager, orientationLayout)
47 | try {
48 | removeViewImmediate(orientationManager)
49 | } catch (_: Exception) {
50 | try {
51 | removeView(orientationManager)
52 | } catch (_: Exception) { }
53 | }
54 | }
55 | } catch (_: Exception) { }
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/PanelViewFragment.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung.drawer
16 |
17 | import android.os.Bundle
18 | import android.view.LayoutInflater
19 | import android.view.View
20 | import android.view.ViewGroup
21 | import android.widget.LinearLayout
22 | import androidx.fragment.app.Fragment
23 | import com.eightbit.samsprung.R
24 |
25 | class PanelViewFragment : Fragment() {
26 |
27 | private var listener: ViewCreatedListener? = null
28 |
29 | fun setListener(listener: ViewCreatedListener) {
30 | this.listener = listener
31 | }
32 |
33 | fun getLayout() : LinearLayout {
34 | return requireView() as LinearLayout
35 | }
36 |
37 | override fun onCreateView(
38 | inflater: LayoutInflater, container: ViewGroup?,
39 | savedInstanceState: Bundle?
40 | ): View {
41 | return inflater.inflate(R.layout.fragment_panel, container, false)
42 | }
43 |
44 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
45 | super.onViewCreated(view, savedInstanceState)
46 | listener?.onViewCreated(view)
47 | }
48 |
49 | interface ViewCreatedListener {
50 | fun onViewCreated(view: View)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/panels/DesktopBinder.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.samsprung.drawer.panels
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 | import android.os.Message
6 | import android.os.MessageQueue
7 | import com.eightbit.samsprung.SamSprungOverlay
8 | import java.lang.ref.SoftReference
9 | import java.util.LinkedList
10 |
11 | class DesktopBinder(
12 | launcher: SamSprungOverlay, shortcuts: ArrayList?,
13 | appWidgets: ArrayList?
14 | ) : Handler(Looper.getMainLooper()), MessageQueue.IdleHandler {
15 | private val mShortcuts: ArrayList? = shortcuts
16 | private val mAppWidgets: LinkedList
17 | private val mLauncher: SoftReference = SoftReference(launcher)
18 | var mTerminate = false
19 | fun startBindingItems() {
20 | obtainMessage(MESSAGE_BIND_ITEMS, 0, mShortcuts!!.size).sendToTarget()
21 | }
22 |
23 | fun startBindingAppWidgetsWhenIdle() {
24 | // Ask for notification when message queue becomes idle
25 | val messageQueue = Looper.myQueue()
26 | messageQueue.addIdleHandler(this)
27 | }
28 |
29 | override fun queueIdle(): Boolean {
30 | // Queue is idle, so start binding items
31 | startBindingAppWidgets()
32 | return false
33 | }
34 |
35 | private fun startBindingAppWidgets() {
36 | obtainMessage(MESSAGE_BIND_APPWIDGETS).sendToTarget()
37 | }
38 |
39 | override fun handleMessage(msg: Message) {
40 | val launcher = mLauncher.get()
41 | if (launcher == null || mTerminate) {
42 | return
43 | }
44 | when (msg.what) {
45 | MESSAGE_BIND_ITEMS -> {
46 | launcher.bindItems(this, mShortcuts, msg.arg1, msg.arg2)
47 | }
48 | MESSAGE_BIND_APPWIDGETS -> {
49 | launcher.bindAppWidgets(this, mAppWidgets)
50 | }
51 | }
52 | }
53 |
54 | companion object {
55 | const val MESSAGE_BIND_ITEMS = 0x1
56 | const val MESSAGE_BIND_APPWIDGETS = 0x2
57 |
58 | // Number of items to bind in every pass
59 | const val ITEMS_COUNT = 6
60 | }
61 |
62 | init {
63 | // Sort widgets so active workspace is bound first
64 | val size = appWidgets!!.size
65 | mAppWidgets = LinkedList()
66 | for (i in 0 until size) {
67 | val appWidgetInfo = appWidgets[i]
68 | // if (appWidgetInfo.screen == 0) {
69 | // mAppWidgets.addFirst(appWidgetInfo)
70 | // } else {
71 | mAppWidgets.addLast(appWidgetInfo)
72 | // }
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/panels/PanelWidgetInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.eightbit.samsprung.drawer.panels
18 |
19 | import android.appwidget.AppWidgetHostView
20 | import android.content.ContentValues
21 | import com.eightbit.samsprung.drawer.panels.WidgetSettings.Favorites
22 |
23 | /**
24 | * Represents a widget, which just contains an identifier.
25 | */
26 | class PanelWidgetInfo(appWidgetId: Int) : WidgetInfo() {
27 | /**
28 | * Identifier for this widget when talking with [android.appwidget.AppWidgetManager] for updates.
29 | */
30 | var appWidgetId: Int
31 |
32 | /**
33 | * View that holds this widget after it's been created. This view isn't created
34 | * until Launcher knows it's needed.
35 | */
36 | var hostView: AppWidgetHostView? = null
37 | override fun onAddToDatabase(values: ContentValues) {
38 | super.onAddToDatabase(values)
39 | values.put(Favorites.APPWIDGET_ID, appWidgetId)
40 | }
41 |
42 | override fun toString(): String {
43 | return appWidgetId.toString()
44 | }
45 |
46 | init {
47 | itemType = Favorites.ITEM_TYPE_APPWIDGET
48 | this.appWidgetId = appWidgetId
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/panels/WidgetHost.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.eightbit.samsprung.drawer.panels
18 |
19 | import android.appwidget.AppWidgetHost
20 | import android.appwidget.AppWidgetHostView
21 | import android.appwidget.AppWidgetProviderInfo
22 | import android.content.Context
23 |
24 | /**
25 | * Specific [AppWidgetHost] that creates our [WidgetHostView]
26 | * which correctly captures all long-press events. This ensures that users can
27 | * always pick up and move widgets.
28 | */
29 | class WidgetHost(context: Context?, hostId: Int) : AppWidgetHost(context, hostId) {
30 | override fun onCreateView(
31 | context: Context, appWidgetId: Int, appWidget: AppWidgetProviderInfo?
32 | ): AppWidgetHostView {
33 | return WidgetHostView(context)
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/panels/WidgetHostView.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.eightbit.samsprung.drawer.panels
18 |
19 | import android.appwidget.AppWidgetHostView
20 | import android.content.Context
21 | import android.view.LayoutInflater
22 | import android.view.MotionEvent
23 | import android.view.View
24 | import com.eightbit.samsprung.R
25 |
26 | /**
27 | * {@inheritDoc}
28 | */
29 | class WidgetHostView(context: Context) : AppWidgetHostView(context) {
30 | override fun getErrorView(): View {
31 | with (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater) {
32 | return inflate(R.layout.appwidget_error, this@WidgetHostView, false)
33 | }
34 | }
35 | override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
36 | when (ev.action) {
37 | MotionEvent.ACTION_DOWN -> { }
38 | MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { }
39 | }
40 | return false
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/drawer/panels/WidgetInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.eightbit.samsprung.drawer.panels
18 |
19 | import android.content.ContentValues
20 | import com.eightbit.samsprung.drawer.panels.WidgetSettings.BaseLauncherColumns
21 | import com.eightbit.samsprung.drawer.panels.WidgetSettings.Favorites
22 |
23 | /**
24 | * Represents an item in the launcher.
25 | */
26 | open class WidgetInfo internal constructor() {
27 | /**
28 | * The id in the settings database for this item
29 | */
30 | var id = NO_ID.toLong()
31 |
32 | /**
33 | * [WidgetSettings.Favorites.ITEM_TYPE_APPWIDGET].
34 | */
35 | var itemType = 0
36 |
37 | /**
38 | * The id of the container that holds this item. For the desktop, this will be
39 | * [WidgetSettings.Favorites.CONTAINER_DESKTOP]. For the all applications folder it
40 | * will be [.NO_ID] (since it is not stored in the settings DB). For user folders
41 | * it will be the id of the folder.
42 | */
43 | var container = NO_ID.toLong()
44 |
45 | /**
46 | * Indicates the X cell span.
47 | */
48 | var spanX = 1
49 |
50 | /**
51 | * Indicates the Y cell span.
52 | */
53 | var spanY = 1
54 |
55 | /**
56 | * Indicates whether the item is a gesture.
57 | */
58 | private var isGesture = false
59 |
60 | /**
61 | * Write the fields of this item to the DB
62 | *
63 | * @param values
64 | */
65 | open fun onAddToDatabase(values: ContentValues) {
66 | values.put(BaseLauncherColumns.ITEM_TYPE, itemType)
67 | if (!isGesture) {
68 | values.put(Favorites.CONTAINER, container)
69 | values.put(Favorites.SPANX, spanX)
70 | values.put(Favorites.SPANY, spanY)
71 | }
72 | }
73 |
74 | companion object {
75 | const val NO_ID = -1
76 | }
77 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/settings/Preferences.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.samsprung.settings
2 |
3 | object Preferences {
4 | const val prefsValue: String = "samsprung.preferences"
5 | const val prefLayout: String = "prefLayout"
6 | const val prefHidden: String = "prefHidden"
7 | const val prefColors: String = "prefColors"
8 | const val prefAlphas: String = "prefAlphas"
9 | const val prefWarned: String = "prefWarned"
10 | const val prefViewer: String = "prefViewer"
11 | const val prefSlider: String = "prefSlider"
12 | const val prefShifts: String = "prefShifts"
13 | const val prefThemes: String = "prefThemes"
14 | const val prefDelays: String = "prefDelays"
15 | const val prefSnooze: String = "prefSnooze"
16 | const val prefTapper: String = "prefTapper"
17 | const val prefReacts: String = "prefReacts"
18 | const val prefSearch: String = "prefSearch"
19 | const val prefRadius: String = "prefRadius"
20 | const val prefLength: String = "prefLength"
21 | const val prefRotate: String = "prefRotate"
22 | const val prefPaging: String = "prefPaging"
23 | const val prefUpdate: String = "prefUpdate"
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/speech/VoiceRecognizer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2012-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung.speech
16 |
17 | import android.annotation.SuppressLint
18 | import android.content.Intent
19 | import android.os.Bundle
20 | import android.speech.RecognitionListener
21 | import android.speech.RecognizerIntent
22 | import android.speech.SpeechRecognizer
23 | import com.eightbit.samsprung.BuildConfig
24 |
25 | @SuppressLint("SetJavaScriptEnabled")
26 | class VoiceRecognizer(private val listener: SpeechResultsListener?) : RecognitionListener {
27 | override fun onReadyForSpeech(params: Bundle) {}
28 | override fun onBeginningOfSpeech() {}
29 | override fun onRmsChanged(rmsdB: Float) {}
30 | override fun onBufferReceived(buffer: ByteArray) {}
31 | override fun onEndOfSpeech() {}
32 | override fun onError(error: Int) {}
33 | override fun onResults(results: Bundle) {
34 | val data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
35 | val grammar = StringBuilder()
36 | data?.let { grammar.append(it[0]) }
37 | grammar.setCharAt(0, Character.toUpperCase(grammar[0]))
38 | val suggested = grammar.toString()
39 | grammar.setLength(0)
40 | listener?.onSpeechResults(suggested)
41 | }
42 |
43 | override fun onPartialResults(partialResults: Bundle) {}
44 | override fun onEvent(eventType: Int, params: Bundle) {}
45 | interface SpeechResultsListener {
46 | fun onSpeechResults(suggested: String)
47 | }
48 |
49 | fun getSpeechIntent(partial: Boolean): Intent {
50 | return Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
51 | putExtra(
52 | RecognizerIntent.EXTRA_LANGUAGE_MODEL,
53 | RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
54 | )
55 | putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, BuildConfig.APPLICATION_ID)
56 | if (partial) {
57 | putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
58 | } else {
59 | putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1)
60 | }
61 | putExtra(
62 | RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,
63 | java.lang.Long.valueOf(1000)
64 | )
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/update/UpdateReceiver.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung.update
16 |
17 | import android.content.BroadcastReceiver
18 | import android.content.Context
19 | import android.content.Intent
20 | import android.content.pm.PackageInstaller
21 | import android.os.Parcelable
22 | import android.widget.Toast
23 | import com.eightbit.os.Version
24 | import com.eightbit.samsprung.BuildConfig
25 | import com.eightbit.samsprung.OnBroadcastService
26 | import com.eightbit.samsprung.SamSprung
27 |
28 | class UpdateReceiver : BroadcastReceiver() {
29 |
30 | private inline fun Intent.parcelable(key: String): T? = when {
31 | Version.isTiramisu ->
32 | getParcelableExtra(key, T::class.java)
33 | else -> @Suppress("deprecation") getParcelableExtra(key) as? T
34 | }
35 |
36 | override fun onReceive(context: Context, intent: Intent) {
37 | val action = intent.action
38 | intent.setPackage(context.packageName)
39 | intent.flags = 0
40 | intent.data = null
41 | when {
42 | Intent.ACTION_BOOT_COMPLETED == action
43 | || Intent.ACTION_LOCKED_BOOT_COMPLETED == action
44 | || Intent.ACTION_REBOOT == action -> {
45 | startBroadcastService(context)
46 | }
47 | Intent.ACTION_MY_PACKAGE_REPLACED == action -> { startBroadcastService(context) }
48 | !BuildConfig.GOOGLE_PLAY && SamSprung.updating == action -> {
49 | when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)) {
50 | PackageInstaller.STATUS_PENDING_USER_ACTION -> {
51 | intent.parcelable(Intent.EXTRA_INTENT)?.let {
52 | startLauncherActivity(
53 | context, Intent.parseUri(
54 | it.toUri(0), Intent.URI_ALLOW_UNSAFE or Intent.URI_INTENT_SCHEME
55 | )
56 | )
57 | }
58 | }
59 | PackageInstaller.STATUS_SUCCESS -> { }
60 | else -> {
61 | val error = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
62 | if (error?.contains("Session was abandoned") != true)
63 | Toast.makeText(context, error, Toast.LENGTH_LONG).show()
64 | }
65 | }
66 | }
67 | }
68 | }
69 |
70 | private fun startBroadcastService(context: Context) {
71 | context.startForegroundService(Intent(context, OnBroadcastService::class.java))
72 | }
73 |
74 | private fun startLauncherActivity(context: Context, intent: Intent) {
75 | context.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/samsprung/update/UpdateShimActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.samsprung.update
16 |
17 | import android.content.Intent
18 | import android.os.Bundle
19 | import androidx.appcompat.app.AppCompatActivity
20 | import com.eightbit.content.ScaledContext
21 | import com.eightbit.samsprung.R
22 |
23 |
24 | class UpdateShimActivity : AppCompatActivity() {
25 |
26 | override fun onCreate(savedInstanceState: Bundle?) {
27 | setVisible(false)
28 | ScaledContext(this).internal(2f).setTheme(R.style.Theme_Launcher_NoActionBar)
29 | super.onCreate(savedInstanceState)
30 | onNewIntent(intent)
31 | }
32 |
33 | override fun onNewIntent(intent: Intent) {
34 | super.onNewIntent(intent)
35 | intent.action?.let {
36 | UpdateManager(this).requestDownload(it)
37 | }
38 | finish()
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/view/AnimatedLinearLayout.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.view
16 |
17 | import android.content.Context
18 | import android.util.AttributeSet
19 | import android.widget.LinearLayout
20 |
21 | class AnimatedLinearLayout : LinearLayout {
22 | constructor(context: Context?) : super(context) {}
23 | constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
24 | constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
25 | context, attrs, defStyle) { }
26 |
27 | interface AnimationListener {
28 | fun onAnimationStart(layout: AnimatedLinearLayout)
29 | fun onAnimationEnd(layout: AnimatedLinearLayout)
30 | }
31 |
32 | private var mAnimationListener: AnimationListener? = null
33 | fun setAnimationListener(listener: AnimationListener?) {
34 | mAnimationListener = listener
35 | }
36 |
37 | override fun onAnimationStart() {
38 | super.onAnimationStart()
39 | if (null != mAnimationListener) {
40 | mAnimationListener!!.onAnimationStart(this)
41 | }
42 | }
43 |
44 | override fun onAnimationEnd() {
45 | super.onAnimationEnd()
46 | if (null != mAnimationListener) {
47 | mAnimationListener!!.onAnimationEnd(this)
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/CardFlipTransformer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2020 Wajahat Karim
3 | Copyright 2022 AbandonedCart
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | package com.eightbit.viewpager
19 |
20 | import android.view.View
21 | import androidx.recyclerview.widget.RecyclerView
22 | import androidx.viewpager2.widget.ViewPager2
23 | import kotlin.math.abs
24 |
25 | class CardFlipTransformer : ViewPager2.PageTransformer {
26 | var isScalable = false
27 |
28 | override fun transformPage(page: View, position: Float) {
29 | val percentage = 1 - abs(position)
30 | page.cameraDistance = 30000f
31 | setVisibility(page, position)
32 | setTranslation(page)
33 | setSize(page, position, percentage)
34 | setRotation(page, position, percentage)
35 | }
36 |
37 | private fun setVisibility(page: View, position: Float) {
38 | if (position < 0.5 && position > -0.5) {
39 | page.visibility = View.VISIBLE
40 | } else {
41 | page.visibility = View.INVISIBLE
42 | }
43 | }
44 |
45 | private fun setTranslation(page: View) {
46 | val viewPager: ViewPager2 = requireViewPager(page)
47 | if (viewPager.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
48 | val scroll = viewPager.scrollX - page.left
49 | page.translationX = scroll.toFloat()
50 | } else {
51 | val scroll = viewPager.scrollY - page.top
52 | page.translationY = scroll.toFloat()
53 | }
54 | }
55 |
56 | private fun setSize(page: View, position: Float, percentage: Float) {
57 | // Do nothing, if its not scalable
58 | if (!isScalable) return
59 | val scale: Float = if (position != 0f && position != 1f) percentage else 1f
60 | page.scaleX = scale
61 | page.scaleY = scale
62 | }
63 |
64 | private fun setRotation(page: View, position: Float, percentage: Float) {
65 | val viewPager: ViewPager2 = requireViewPager(page)
66 | if (viewPager.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
67 | if (position > 0) {
68 | page.rotationY = -180 * (percentage + 1)
69 | } else {
70 | page.rotationY = 180 * (percentage + 1)
71 | }
72 | } else {
73 | if (position > 0) {
74 | page.rotationX = -180 * (percentage + 1)
75 | } else {
76 | page.rotationX = 180 * (percentage + 1)
77 | }
78 | }
79 | }
80 |
81 | private fun requireViewPager(page: View): ViewPager2 {
82 | val parent = page.parent
83 | val parentParent = parent.parent
84 | if (parent is RecyclerView && parentParent is ViewPager2) {
85 | return parentParent
86 | }
87 | throw IllegalStateException("Expected page view to be managed by a ViewPager2 instance.")
88 | }
89 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/ClockSpinTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.viewpager
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | class ClockSpinTransformer : ViewPager2.PageTransformer {
8 | override fun transformPage(page: View, position: Float) {
9 | page.translationX = -position * page.width
10 | if (abs(position) <= 0.5) {
11 | page.visibility = View.VISIBLE
12 | page.scaleX = 1 - abs(position)
13 | page.scaleY = 1 - abs(position)
14 | } else if (abs(position) > 0.5) {
15 | page.visibility = View.GONE
16 | }
17 | if (position < -1) { // [-Infinity,-1)
18 | // This page is way off-screen to the left.
19 | page.alpha = 0f
20 | } else if (position <= 0) { // [-1,0]
21 | page.alpha = 1f
22 | page.rotation = 360 * abs(position)
23 | } else if (position <= 1) { // (0,1]
24 | page.alpha = 1f
25 | page.rotation = -360 * abs(position)
26 | } else { // (1,+Infinity]
27 | // This page is way off-screen to the right.
28 | page.alpha = 0f
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/DepthTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.viewpager
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | class DepthTransformer : ViewPager2.PageTransformer {
8 | override fun transformPage(page: View, position: Float) {
9 | if (position < -1) { // [-Infinity,-1)
10 | // This page is way off-screen to the left.
11 | page.alpha = 0f
12 | } else if (position <= 0) { // [-1,0]
13 | page.alpha = 1f
14 | page.translationX = 0f
15 | page.scaleX = 1f
16 | page.scaleY = 1f
17 | } else if (position <= 1) { // (0,1]
18 | page.translationX = -position * page.width
19 | page.alpha = 1 - abs(position)
20 | page.scaleX = 1 - abs(position)
21 | page.scaleY = 1 - abs(position)
22 | } else { // (1,+Infinity]
23 | // This page is way off-screen to the right.
24 | page.alpha = 0f
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/FidgetSpinTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.viewpager
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | class FidgetSpinTransformer : ViewPager2.PageTransformer {
8 | override fun transformPage(page: View, position: Float) {
9 | page.translationX = -position * page.width
10 | if (abs(position) < 0.5) {
11 | page.visibility = View.VISIBLE
12 | page.scaleX = 1 - abs(position)
13 | page.scaleY = 1 - abs(position)
14 | } else if (abs(position) > 0.5) {
15 | page.visibility = View.GONE
16 | }
17 | if (position < -1) { // [-Infinity,-1)
18 | // This page is way off-screen to the left.
19 | page.alpha = 0f
20 | } else if (position <= 0) { // [-1,0]
21 | page.alpha = 1f
22 | page.rotation =
23 | 36000 * (abs(position) * abs(position) * Math.abs(
24 | position
25 | ) * abs(position) * abs(position) * abs(
26 | position
27 | ) * abs(position))
28 | } else if (position <= 1) { // (0,1]
29 | page.alpha = 1f
30 | page.rotation =
31 | -36000 * (abs(position) * abs(position) * abs(
32 | position
33 | ) * abs(position) * abs(position) * abs(
34 | position
35 | ) * abs(position))
36 | } else { // (1,+Infinity]
37 | // This page is way off-screen to the right.
38 | page.alpha = 0f
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/PopTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.viewpager
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | class PopTransformer : ViewPager2.PageTransformer {
8 | override fun transformPage(page: View, position: Float) {
9 | page.translationX = -position * page.width
10 | if (Math.abs(position) < 0.5) {
11 | page.visibility = View.VISIBLE
12 | page.scaleX = 1 - abs(position)
13 | page.scaleY = 1 - abs(position)
14 | } else if (abs(position) > 0.5) {
15 | page.visibility = View.GONE
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/SpinnerTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.viewpager
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | class SpinnerTransformer : ViewPager2.PageTransformer {
8 | override fun transformPage(page: View, position: Float) {
9 | page.translationX = -position * page.width
10 | page.cameraDistance = 12000f
11 | if (position < 0.5 && position > -0.5) {
12 | page.visibility = View.VISIBLE
13 | } else {
14 | page.visibility = View.INVISIBLE
15 | }
16 | if (position < -1) { // [-Infinity,-1)
17 | // This page is way off-screen to the left.
18 | page.alpha = 0f
19 | } else if (position <= 0) { // [-1,0]
20 | page.alpha = 1f
21 | page.rotationY = 900 * (1 - abs(position) + 1)
22 | } else if (position <= 1) { // (0,1]
23 | page.alpha = 1f
24 | page.rotationY = -900 * (1 - abs(position) + 1)
25 | } else { // (1,+Infinity]
26 | // This page is way off-screen to the right.
27 | page.alpha = 0f
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/viewpager/TossTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.eightbit.viewpager
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | class TossTransformer : ViewPager2.PageTransformer {
8 | override fun transformPage(page: View, position: Float) {
9 | page.translationX = -position * page.width
10 | page.cameraDistance = 20000f
11 | if (position < 0.5 && position > -0.5) {
12 | page.visibility = View.VISIBLE
13 | } else {
14 | page.visibility = View.INVISIBLE
15 | }
16 | if (position < -1) { // [-Infinity,-1)
17 | // This page is way off-screen to the left.
18 | page.alpha = 0f
19 | } else if (position <= 0) { // [-1,0]
20 | page.alpha = 1f
21 | page.scaleX = 0.4f.coerceAtLeast(1 - abs(position))
22 | page.scaleY = 0.4f.coerceAtLeast(1 - abs(position))
23 | page.rotationX = 1080 * (1 - abs(position) + 1)
24 | page.translationY = -1000 * abs(position)
25 | } else if (position <= 1) { // (0,1]
26 | page.alpha = 1f
27 | page.scaleX = 0.4f.coerceAtLeast(1 - abs(position))
28 | page.scaleY = 0.4f.coerceAtLeast(1 - abs(position))
29 | page.rotationX = -1080 * (1 - abs(position) + 1)
30 | page.translationY = -1000 * abs(position)
31 | } else { // (1,+Infinity]
32 | // This page is way off-screen to the right.
33 | page.alpha = 0f
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eightbit/widget/RecyclerViewTouch.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Copyright (c) 2021-2023 AbandonedCart. All rights reserved.
4 | *
5 | * See https://github.com/SamSprung/.github/blob/main/LICENSE#L5
6 | * ====================================================================
7 | *
8 | * The license and distribution terms for any publicly available version or
9 | * derivative of this code cannot be changed. i.e. this code cannot simply be
10 | * copied and put under another distribution license
11 | * [including the GNU Public License.] Content not subject to these terms is
12 | * subject to to the terms and conditions of the Apache License, Version 2.0.
13 | */
14 |
15 | package com.eightbit.widget
16 |
17 | import android.graphics.Canvas
18 | import androidx.recyclerview.widget.ItemTouchHelper
19 | import androidx.recyclerview.widget.RecyclerView
20 |
21 | class RecyclerViewTouch(var recyclerView: RecyclerView) {
22 |
23 | var swipeCallback: SwipeCallback? = null
24 | var swipeDirections: Int? = null
25 |
26 | private val drawerTouchCallback: ItemTouchHelper.SimpleCallback =
27 | object : ItemTouchHelper.SimpleCallback(
28 | 0, swipeDirections ?: (ItemTouchHelper.START or ItemTouchHelper.END)
29 | ) {
30 | override fun onMove(
31 | recyclerView: RecyclerView,
32 | viewHolder: RecyclerView.ViewHolder,
33 | target: RecyclerView.ViewHolder
34 | ): Boolean {
35 | return false
36 | }
37 |
38 | override fun onChildDraw(
39 | c: Canvas,
40 | recyclerView: RecyclerView,
41 | viewHolder: RecyclerView.ViewHolder,
42 | dX: Float,
43 | dY: Float,
44 | actionState: Int,
45 | isCurrentlyActive: Boolean
46 | ) { }
47 |
48 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
49 | swipeCallback?.onSwiped(viewHolder, direction)
50 | }
51 | }
52 |
53 | fun setSwipeCallback(directions: Int, callback: SwipeCallback) {
54 | swipeDirections = directions
55 | swipeCallback = callback
56 | ItemTouchHelper(drawerTouchCallback).attachToRecyclerView(recyclerView)
57 | }
58 |
59 | interface SwipeCallback {
60 | fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/BlurAlgorithm.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.graphics.Bitmap
4 | import android.graphics.Canvas
5 |
6 | interface BlurAlgorithm {
7 | /**
8 | * @param bitmap bitmap to be blurred
9 | * @param blurRadius blur radius
10 | * @return blurred bitmap
11 | */
12 | fun blur(bitmap: Bitmap?, blurRadius: Float): Bitmap?
13 |
14 | /**
15 | * Frees allocated resources
16 | */
17 | fun destroy()
18 |
19 | /**
20 | * @return true if this algorithm returns the same instance of bitmap as it accepted
21 | * false if it creates a new instance.
22 | *
23 | *
24 | * If you return false from this method, you'll be responsible to swap bitmaps in your
25 | * [BlurAlgorithm.blur] implementation
26 | * (assign input bitmap to your field and return the instance algorithm just blurred).
27 | */
28 | fun canModifyBitmap(): Boolean
29 |
30 | /**
31 | * Retrieve the [android.graphics.Bitmap.Config] on which the [BlurAlgorithm]
32 | * can actually work.
33 | *
34 | * @return bitmap config supported by the given blur algorithm.
35 | */
36 | val supportedBitmapConfig: Bitmap.Config
37 | fun scaleFactor(): Float
38 | fun render(canvas: Canvas, bitmap: Bitmap)
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/BlurController.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.graphics.Canvas
4 |
5 | interface BlurController : BlurViewFacade {
6 | /**
7 | * Draws blurred content on given canvas
8 | *
9 | * @return true if BlurView should proceed with drawing itself and its children
10 | */
11 | fun draw(canvas: Canvas): Boolean
12 |
13 | /**
14 | * Must be used to notify Controller when BlurView's size has changed
15 | */
16 | fun updateBlurViewSize()
17 |
18 | /**
19 | * Frees allocated resources
20 | */
21 | fun destroy()
22 |
23 | companion object {
24 | const val DEFAULT_SCALE_FACTOR = 6f
25 | const val DEFAULT_BLUR_RADIUS = 16f
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/BlurViewCanvas.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.graphics.Bitmap
4 | import android.graphics.Canvas
5 |
6 | // Serves purely as a marker of a Canvas used in BlurView
7 | // to skip drawing itself and other BlurViews on the View hierarchy snapshot
8 | class BlurViewCanvas(bitmap: Bitmap) : Canvas(bitmap)
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/BlurViewFacade.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.graphics.drawable.Drawable
4 | import androidx.annotation.ColorInt
5 |
6 | interface BlurViewFacade {
7 | /**
8 | * Enables/disables the blur. Enabled by default
9 | *
10 | * @param enabled true to enable, false otherwise
11 | * @return [BlurViewFacade]
12 | */
13 | fun setBlurEnabled(enabled: Boolean): BlurViewFacade
14 |
15 | /**
16 | * Can be used to stop blur auto update or resume if it was stopped before.
17 | * Enabled by default.
18 | *
19 | * @return [BlurViewFacade]
20 | */
21 | fun setBlurAutoUpdate(enabled: Boolean): BlurViewFacade
22 |
23 | /**
24 | * @param frameClearDrawable sets the drawable to draw before view hierarchy.
25 | * Can be used to draw Activity's window background if your root layout doesn't provide any background
26 | * Optional, by default frame is cleared with a transparent color.
27 | * @return [BlurViewFacade]
28 | */
29 | fun setFrameClearDrawable(frameClearDrawable: Drawable?): BlurViewFacade
30 |
31 | /**
32 | * @param radius sets the blur radius
33 | * Default value is [BlurController.DEFAULT_BLUR_RADIUS]
34 | * @return [BlurViewFacade]
35 | */
36 | fun setBlurRadius(radius: Float): BlurViewFacade
37 |
38 | /**
39 | * Sets the color overlay to be drawn on top of blurred content
40 | *
41 | * @param overlayColor int color
42 | * @return [BlurViewFacade]
43 | */
44 | fun setOverlayColor(@ColorInt overlayColor: Int): BlurViewFacade
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/NoOpController.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.graphics.Canvas
4 | import android.graphics.drawable.Drawable
5 |
6 | //Used in edit mode and in case if no BlurController was set
7 | internal class NoOpController : BlurController {
8 | override fun draw(canvas: Canvas): Boolean {
9 | return true
10 | }
11 |
12 | override fun updateBlurViewSize() {}
13 | override fun destroy() {}
14 | override fun setBlurRadius(radius: Float): BlurViewFacade {
15 | return this
16 | }
17 |
18 | override fun setOverlayColor(overlayColor: Int): BlurViewFacade {
19 | return this
20 | }
21 |
22 | override fun setFrameClearDrawable(frameClearDrawable: Drawable?): BlurViewFacade {
23 | return this
24 | }
25 |
26 | override fun setBlurEnabled(enabled: Boolean): BlurViewFacade {
27 | return this
28 | }
29 |
30 | override fun setBlurAutoUpdate(enabled: Boolean): BlurViewFacade {
31 | return this
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/RenderEffectBlur.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.graphics.Canvas
6 | import android.graphics.RenderEffect
7 | import android.graphics.RenderNode
8 | import android.graphics.Shader
9 | import android.os.Build
10 | import androidx.annotation.RequiresApi
11 |
12 | /**
13 | * Leverages the new RenderEffect.createBlurEffect API to perform blur.
14 | * Hardware accelerated.
15 | * Blur is performed on a separate thread - native RenderThread.
16 | * It doesn't block the Main thread, however it can still cause an FPS drop,
17 | * because it's just in a different part of the rendering pipeline.
18 | */
19 | @RequiresApi(Build.VERSION_CODES.S)
20 | class RenderEffectBlur : BlurAlgorithm {
21 | private val node = RenderNode("BlurViewNode")
22 | private var height = 0
23 | private var width = 0
24 | private var lastBlurRadius = 1f
25 | var fallbackAlgorithm: BlurAlgorithm? = null
26 | private var context: Context? = null
27 | override fun blur(bitmap: Bitmap?, blurRadius: Float): Bitmap {
28 | lastBlurRadius = blurRadius
29 | if (bitmap!!.height != height || bitmap.width != width) {
30 | height = bitmap.height
31 | width = bitmap.width
32 | node.setPosition(0, 0, width, height)
33 | }
34 | val canvas: Canvas = node.beginRecording()
35 | canvas.drawBitmap(bitmap, 0f, 0f, null)
36 | node.endRecording()
37 | node.setRenderEffect(
38 | RenderEffect.createBlurEffect(
39 | blurRadius,
40 | blurRadius,
41 | Shader.TileMode.MIRROR
42 | )
43 | )
44 | // returning not blurred bitmap, because the rendering relies on the RenderNode
45 | return bitmap
46 | }
47 |
48 | override fun destroy() {
49 | node.discardDisplayList()
50 | fallbackAlgorithm?.destroy()
51 | }
52 |
53 | override fun canModifyBitmap(): Boolean {
54 | return true
55 | }
56 |
57 | override val supportedBitmapConfig: Bitmap.Config
58 | get() = Bitmap.Config.ARGB_8888
59 |
60 | override fun scaleFactor(): Float {
61 | return BlurController.DEFAULT_SCALE_FACTOR
62 | }
63 |
64 | override fun render(canvas: Canvas, bitmap: Bitmap) {
65 | if (canvas.isHardwareAccelerated) {
66 | canvas.drawRenderNode(node)
67 | } else {
68 | if (fallbackAlgorithm == null) {
69 | fallbackAlgorithm = RenderScriptBlur(context!!)
70 | }
71 | fallbackAlgorithm!!.blur(bitmap, lastBlurRadius)
72 | fallbackAlgorithm!!.render(canvas, bitmap)
73 | }
74 | }
75 |
76 | fun setContext(context: Context) {
77 | this.context = context
78 | }
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/RenderScriptBlur.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.graphics.Canvas
6 | import android.graphics.Paint
7 | import android.os.Build
8 | import android.renderscript.Allocation
9 | import android.renderscript.Element
10 | import android.renderscript.RenderScript
11 | import android.renderscript.ScriptIntrinsicBlur
12 | import androidx.annotation.RequiresApi
13 |
14 | /**
15 | * Blur using RenderScript, processed on GPU when device drivers support it.
16 | * Requires API 17+
17 | *
18 | */
19 | @Deprecated(
20 | """because RenderScript is deprecated and its hardware acceleration is not guaranteed.
21 | RenderEffectBlur is the best alternative at the moment."""
22 | )
23 | class RenderScriptBlur constructor(context: Context) : BlurAlgorithm {
24 | private val paint = Paint(Paint.FILTER_BITMAP_FLAG)
25 | private val renderScript: RenderScript
26 | private val blurScript: ScriptIntrinsicBlur
27 | private var outAllocation: Allocation? = null
28 | private var lastBitmapWidth = -1
29 | private var lastBitmapHeight = -1
30 |
31 | /**
32 | * @param context Context to create the [RenderScript]
33 | */
34 | init {
35 | renderScript = RenderScript.create(context)
36 | blurScript = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
37 | }
38 |
39 | private fun canReuseAllocation(bitmap: Bitmap): Boolean {
40 | return bitmap.height == lastBitmapHeight && bitmap.width == lastBitmapWidth
41 | }
42 |
43 | /**
44 | * @param bitmap bitmap to blur
45 | * @param blurRadius blur radius (1..25)
46 | * @return blurred bitmap
47 | */
48 | override fun blur(bitmap: Bitmap?, blurRadius: Float): Bitmap {
49 | //Allocation will use the same backing array of pixels as bitmap if created with USAGE_SHARED flag
50 | val inAllocation = Allocation.createFromBitmap(renderScript, bitmap)
51 | if (!canReuseAllocation(bitmap!!)) {
52 | outAllocation?.destroy()
53 | outAllocation = Allocation.createTyped(renderScript, inAllocation.type)
54 | lastBitmapWidth = bitmap.width
55 | lastBitmapHeight = bitmap.height
56 | }
57 | blurScript.setRadius(blurRadius)
58 | blurScript.setInput(inAllocation)
59 | //do not use inAllocation in forEach. it will cause visual artifacts on blurred Bitmap
60 | blurScript.forEach(outAllocation)
61 | outAllocation!!.copyTo(bitmap)
62 | inAllocation.destroy()
63 | return bitmap
64 | }
65 |
66 | override fun destroy() {
67 | blurScript.destroy()
68 | renderScript.destroy()
69 | outAllocation?.destroy()
70 | }
71 |
72 | override fun canModifyBitmap(): Boolean {
73 | return true
74 | }
75 |
76 | override val supportedBitmapConfig: Bitmap.Config
77 | get() = Bitmap.Config.ARGB_8888
78 |
79 | override fun scaleFactor(): Float {
80 | return BlurController.DEFAULT_SCALE_FACTOR
81 | }
82 |
83 | override fun render(canvas: Canvas, bitmap: Bitmap) {
84 | canvas.drawBitmap(bitmap, 0f, 0f, paint)
85 | }
86 | }
--------------------------------------------------------------------------------
/app/src/main/java/eightbitlab/com/blurview/SizeScaler.kt:
--------------------------------------------------------------------------------
1 | package eightbitlab.com.blurview
2 |
3 | import eightbitlab.com.blurview.SizeScaler.Companion.ROUNDING_VALUE
4 | import kotlin.math.ceil
5 |
6 | /**
7 | * Scales width and height by [scaleFactor],
8 | * and then rounds the size proportionally so the width is divisible by [ROUNDING_VALUE]
9 | */
10 | class SizeScaler(private val scaleFactor: Float) {
11 | fun scale(width: Int, height: Int): Size {
12 | val nonRoundedScaledWidth = downscaleSize(width.toFloat())
13 | val scaledWidth = roundSize(nonRoundedScaledWidth)
14 | //Only width has to be aligned to ROUNDING_VALUE
15 | val roundingScaleFactor = width.toFloat() / scaledWidth
16 | //Ceiling because rounding or flooring might leave empty space on the View's bottom
17 | val scaledHeight = ceil((height / roundingScaleFactor).toDouble()).toInt()
18 | return Size(scaledWidth, scaledHeight, roundingScaleFactor)
19 | }
20 |
21 | fun isZeroSized(measuredWidth: Int, measuredHeight: Int): Boolean {
22 | return downscaleSize(measuredHeight.toFloat()) == 0 || downscaleSize(measuredWidth.toFloat()) == 0
23 | }
24 |
25 | /**
26 | * Rounds a value to the nearest divisible by [.ROUNDING_VALUE] to meet stride requirement
27 | */
28 | private fun roundSize(value: Int): Int {
29 | return if (value % ROUNDING_VALUE == 0) {
30 | value
31 | } else value - value % ROUNDING_VALUE + ROUNDING_VALUE
32 | }
33 |
34 | private fun downscaleSize(value: Float): Int {
35 | return ceil((value / scaleFactor).toDouble()).toInt()
36 | }
37 |
38 | class Size(
39 | val width: Int, val height: Int, // TODO this is probably not needed anymore
40 | private val scaleFactor: Float
41 | ) {
42 | override fun equals(other: Any?): Boolean {
43 | if (this === other) return true
44 | if (other == null || javaClass != other.javaClass) return false
45 | val size = other as Size
46 | if (width != size.width) return false
47 | return if (height != size.height) false else size.scaleFactor.compareTo(scaleFactor) == 0
48 | }
49 |
50 | override fun hashCode(): Int {
51 | var result = width
52 | result = 31 * result + height
53 | result = 31 * result + if (scaleFactor != 0.0f) java.lang.Float.floatToIntBits(
54 | scaleFactor
55 | ) else 0
56 | return result
57 | }
58 |
59 | override fun toString(): String {
60 | return "Size{" +
61 | "width=" + width +
62 | ", height=" + height +
63 | ", scaleFactor=" + scaleFactor +
64 | '}'
65 | }
66 | }
67 |
68 | companion object {
69 | // Bitmap size should be divisible by ROUNDING_VALUE to meet stride requirement.
70 | // This will help avoiding an extra bitmap allocation when passing the bitmap to RenderScript for blur.
71 | // Usually it's 16, but on Samsung devices it's 64 for some reason.
72 | private const val ROUNDING_VALUE = 64
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/res/color/primary_text_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/color/primary_text_light.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night-v21/button_rippled.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
8 |
9 |
10 |
11 |
12 |
13 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_bluetooth_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_bluetooth_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_cancel_presentation_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_delete_forever_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_do_not_disturb_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_do_not_disturb_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_expand_20dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_fingerprint_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_flashlight_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_flashlight_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_github_octocat_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
13 |
16 |
19 |
22 |
25 |
28 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_insert_page_break_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_keyboard_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_launch_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_menu_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_move_up_20dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_nfc_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_nfc_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_record_voice_over_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_samsprung_24dp.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_screen_lock_rotation_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_screen_rotation_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_send_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_sound_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_sound_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_swipe_down_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_voice_over_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_wallpaper_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_widgets_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_wifi_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_wifi_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/rounded_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/rounded_layout_themed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/button_rippled.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
8 |
9 |
10 |
11 |
12 |
13 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_appwidget_error.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/drawable/bg_appwidget_error.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/card_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/card_foreground_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_back_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bluetooth_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bluetooth_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_cancel_presentation_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delete_forever_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_do_not_disturb_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_do_not_disturb_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expand_20dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fingerprint_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_flashlight_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_flashlight_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_github_octocat_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
13 |
16 |
19 |
22 |
25 |
28 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_google_play_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_home_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_insert_page_break_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launch_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/drawable/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/drawable/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_move_up_20dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_nfc_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_nfc_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_paypal_donation.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_record_voice_over_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_samsprung_24dp.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_screen_lock_rotation_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_screen_rotation_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_send_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sound_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sound_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_swipe_down_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_voice_over_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wallpaper_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_widget_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/drawable/ic_widget_preview.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_widgets_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wifi_off_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wifi_on_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/notification_badge.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_layout_themed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_preview_tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/drawable/widget_preview_tile.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/appwidget_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/button_cancel_sub.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
17 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/button_paypal.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
17 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/button_sponsor.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
17 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/color_panel.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
19 |
20 |
26 |
27 |
36 |
37 |
43 |
44 |
53 |
54 |
60 |
61 |
70 |
71 |
78 |
79 |
86 |
87 |
88 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/configure_switch.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/donation_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
25 |
33 |
34 |
35 |
40 |
41 |
48 |
49 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/drawer_apps_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
24 |
25 |
33 |
34 |
35 |
36 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/drawer_apps_icon.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dropdown_item_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/filtered_apps_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
21 |
22 |
33 |
34 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fingerprint_auth.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_notices.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_panel.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/navigation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
24 |
25 |
28 |
29 |
30 |
39 |
40 |
48 |
49 |
57 |
58 |
66 |
67 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/notification_reply.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
28 |
29 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/panel_picker_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
18 |
19 |
27 |
28 |
33 |
34 |
42 |
43 |
44 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/system_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
24 |
25 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toggle_state_icon.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_options.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
22 |
23 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_preview.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/cover_quick_toggles.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/cover_settings_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/sprung_icon.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/sprung_icon_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/sprung_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-hdpi/sprung_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/sprung_icon_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-hdpi/sprung_icon_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/sprung_icon_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-hdpi/sprung_icon_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/sprung_icon_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-hdpi/sprung_icon_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/sprung_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-mdpi/sprung_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/sprung_icon_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-mdpi/sprung_icon_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/sprung_icon_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-mdpi/sprung_icon_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/sprung_icon_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-mdpi/sprung_icon_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/sprung_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xhdpi/sprung_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/sprung_icon_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xhdpi/sprung_icon_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/sprung_icon_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xhdpi/sprung_icon_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/sprung_icon_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xhdpi/sprung_icon_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/sprung_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxhdpi/sprung_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/sprung_icon_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxhdpi/sprung_icon_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/sprung_icon_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxhdpi/sprung_icon_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/sprung_icon_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxhdpi/sprung_icon_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/sprung_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxxhdpi/sprung_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/sprung_icon_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxxhdpi/sprung_icon_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/sprung_icon_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxxhdpi/sprung_icon_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/sprung_icon_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/app/src/main/res/mipmap-xxxhdpi/sprung_icon_round.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/display_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF02D896
4 | #FF10C3CB
5 | #FF10C3CB
6 | #FF1DAEFC
7 |
8 | #FCCC
9 |
10 | #A9333333
11 | #66000000
12 | #BB000000
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/accessibility.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Icon
4 | Badge
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - Card Flip
5 | - Clock Spin
6 | - Depth
7 | - Fidget Spin
8 | - Pop
9 | - Spinner
10 | - Toss
11 | - None
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF02D896
4 | #FF10C3CB
5 | #FF10C3CB
6 | #FF1DAEFC
7 |
8 | #FCCC
9 |
10 | #BABBBBBB
11 | #44FFFFFF
12 | #BBFFFFFF
13 |
14 | #222
15 |
16 | #ff000000
17 |
18 | #ffffffff
19 | @color/background_light
20 | @color/background_dark
21 | #80ffffff
22 | #80000000
23 | @color/bright_foreground_light
24 | @color/bright_foreground_dark
25 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8dp
4 | 36dp
5 | 48dp
6 | 12dp
7 | 84dp
8 |
9 | 48dp
10 |
11 | 24dp
12 | 4dp
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/donottranslate.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | SamSprung TooUI
4 |
5 | #%1$s
6 | [Logcat]: SamSprung #%1$s
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
11 |
12 |
16 |
17 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
23 |
27 |
28 |
35 |
36 |
40 |
41 |
49 |
50 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/extraction_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/full_backup_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | maven { url "https://jitpack.io" }
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:8.6.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20"
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | tasks.register('clean', Delete) {
18 | delete getLayout().getBuildDirectory()
19 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xms256m -XX:+UseParallelGC -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 | # Speed up build by forcing incremental annotation processors
23 | kapt.incremental.apt=true
24 | # Caches results of configuration phase for subsequent builds
25 | org.gradle.unsafe.configuration-cache=true
26 | org.gradle.configuration-cache=true
27 | # Gradle wil run parallel compilation tasks within subprojects
28 | kotlin.parallel.tasks.in.project=true
29 | android.defaults.buildfeatures.buildconfig=true
30 | android.nonTransitiveRClass=false
31 | android.nonFinalResIds=false
32 |
33 | # Android Gradle plugin 8.0.2
34 | android.suppressUnsupportedCompileSdk=34
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamSprung/SamSprung-TooUI/905868baae1f6b57ac5a54d3f70d412ba7f170af/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Aug 27 09:21:47 BST 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | google()
5 | mavenCentral()
6 | maven {
7 | url "https://jitpack.io"
8 | }
9 | }
10 | }
11 | rootProject.name = "SamSprung"
12 | include ':app'
13 |
--------------------------------------------------------------------------------