Skip to content

Commit

Permalink
Merge branch 'master' into enable_search_all_switch
Browse files Browse the repository at this point in the history
# Conflicts:
#	app/src/main/java/com/sduduzog/slimlauncher/ui/options/CustomizeSearchFieldFragment.kt
  • Loading branch information
jkuester committed Jan 25, 2024
2 parents e27af5d + ae7b43a commit ebd5238
Show file tree
Hide file tree
Showing 102 changed files with 1,507 additions and 882 deletions.
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[*.{kt,kts}]
ktlint_code_style = android_studio
2 changes: 2 additions & 0 deletions .github/workflows/android_master_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "34.0.0"
- name: Upload APK
uses: actions/upload-artifact@v1
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/android_release_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "34.0.0"
- name: Create Release
id: create_release
uses: actions/create-release@v1
Expand Down
18 changes: 17 additions & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Developing Unlauncher

## Kotlin Linting/Formatting

This project uses [ktlint](https://pinterest.github.io/ktlint/latest/) to format/lint the Kotlin code to ensure consistency of style across the codebase.

Developers using Android Studio are encouraged to install the [Ktlint plugin](https://plugins.jetbrains.com/plugin/15057-ktlint) for a tighter feedback loop and more automation.

## Adding a new configuration preference

Currently user preferences in the Unlauncher code base are stored in one of three different ways:

1. In the [SharedPreferences](https://developer.android.com/training/data-storage/shared-preferences). This is an older style of storing basic preferences that was inherited from Slim Launcher.
1. In an [SQLite database](https://developer.android.com/training/data-storage/sqlite). This format is more appropriate for storing large amounts of data and was inherited from Slim Launcher as the method for storing data about the apps installed on the device.
1. In a [Proto DataStore](https://developer.android.com/topic/libraries/architecture/datastore#proto-datastore). This data format is suitable for both simple user preference values as well as storing larger data sets.

The plan is to eventually migrate away from SharedPreferences and SQLite so that all the data is centralized in Proto DataStores. This will maximize consistency and simplicity in the codebase. All new data values should be added to Proto DataStores.

## Building a release

Building an Unlauncher release is straightforward.
Expand All @@ -21,7 +37,7 @@ So, creating a beta release for Unlauncher requires the following steps:

1. Push a beta tag to GitHub (e.g. `2.0.0-beta.1`)
1. Make sure that the `versionName` in the [build.gradle.kts](./app/build.gradle.kts) matches the tag that you are pushing
1. Delete the draft Release on GitHub for the beta tag that was created by the CI
1. Add release notes to the draft Release on GitHub that was created by the CI and publish it as a pre-release
1. Raise a MR to [fdroid/fdroiddata](https://gitlab.com/fdroid/fdroiddata) to add a new `Builds` entry for the beta release
1. _Do not_ update the configured `CurrenVersion`/`CurrentVersionCode` since that will trigger a normal release
1. Prepare for the next release by incrementing the `versionCode` and `versionName` in the [build.gradle.kts](./app/build.gradle.kts) file
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Features:

## What people are saying

<!-- 2023 -->
Jake Ginesin - [dumb-phone](https://jakegines.in/blog/2023/dumb-phone)

<!-- 2022-12-05 -->
Side Of Burritos - [A minimalist dumb phone you should actually use](https://www.youtube.com/watch?v=OrZacTUhH0c) (VIDEO)

<!-- 2020-11-13 -->
zymotux - [Bare-bones smartphone “Unlauncher”](https://write.as/zymotux/bare-bones-smartphone-unlauncher)

Expand All @@ -46,12 +52,10 @@ Linux Lounge - [A Quick Look At Unlauncher - Can This Launcher Help With Smartph

## Project History

This project is a downstream fork of the great [Slim Launcher](https://github.com/sduduzog/slim-launcher) by [sduduzog](https://github.com/sduduzog). The contributors to that project deserve all the credit for the beautiful layout of this app and most of its functionality.
This project is a fork of the great [Slim Launcher](https://github.com/sduduzog/slim-launcher) by [sduduzog](https://github.com/sduduzog). The contributors to that project deserve all the credit for the beautiful layout of this app!

The main differentiator between Unlauncher and Slim Launcher lies in the number of apps the launcher gives you access too. Slim Launcher takes the Spartan approach of only allowing access to seven apps. Unlauncher, on the other hand, allows you to pin up to six apps on the home screen and then gives you access to all the rest of your apps by swiping up into a searchable app drawer.

The goal of this project is continue to remain synchronized, where possible, with Slim Launcher and to submit any new contributions back upstream (if they align with the design philosophy and goals of Slim Launcher).

## Communication

If you have any issues or questions, please log a [Github issue](https://github.com/jkuester/unlauncher/issues) for this repository.
Expand Down
73 changes: 44 additions & 29 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import com.google.protobuf.gradle.*
import com.google.protobuf.gradle.id

plugins {
id("com.android.application")
id("dagger.hilt.android.plugin")
id("com.google.protobuf") version "0.9.0"
id("com.google.devtools.ksp")
id("com.google.protobuf")
id("org.jlleitschuh.gradle.ktlint")
kotlin("android")
kotlin("android.extensions")
kotlin("kapt")
}

android {
compileSdkVersion(33)
compileSdk = 34
defaultConfig {
applicationId = "com.jkuester.unlauncher"
minSdkVersion(21)
targetSdkVersion(33)
versionName = "2.1.0"
versionCode = 19
minSdk = 21
targetSdk = 34
versionName = "2.2.0-beta.1"
versionCode = 22
vectorDrawables { useSupportLibrary = true }
// signingConfigs {
// if (project.extra.has("RELEASE_STORE_FILE")) {
Expand All @@ -29,7 +29,10 @@ android {
// }
// }
}

buildFeatures {
viewBinding = true
buildConfig = true
}
buildTypes {
named("release").configure {
isMinifyEnabled = true
Expand Down Expand Up @@ -58,47 +61,55 @@ android {
testOptions {
unitTests.isIncludeAndroidResources = true
}
lint {
warningsAsErrors = true
disable += "Typos" // Too many false positives
disable += "VectorPath" // Not planning to change "large" graphics for now
disable += "GradleDependency" // Do not fail linting due to new dependencies
checkDependencies = false
}
namespace = "com.sduduzog.slimlauncher"
applicationVariants.all{
applicationVariants.all {
outputs.all {
(this as com.android.build.gradle.internal.api.BaseVariantOutputImpl).outputFileName = "${applicationId}.apk"
(this as com.android.build.gradle.internal.api.BaseVariantOutputImpl).outputFileName =
"$applicationId.apk"
}
assembleProvider.get().dependsOn.add("ktlintCheck")
}
}

dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))

// Kotlin Libraries
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.7.22")
// This needs to match ksp and kotlin-gradle-plugin
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.22")

// Support Libraries
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.recyclerview:recyclerview:1.3.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.datastore:datastore:1.0.0")
implementation("androidx.datastore:datastore-core:1.0.0")
implementation("com.google.protobuf:protobuf-javalite:3.23.3")
implementation("com.google.protobuf:protobuf-javalite:3.25.1")

// Arch Components
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.fragment:fragment-ktx:1.5.7")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.fragment:fragment-ktx:1.6.2")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
implementation("androidx.room:room-runtime:2.5.1")
kapt("androidx.room:room-compiler:2.5.1")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.6")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.room:room-runtime:2.6.1")
ksp("androidx.room:room-compiler:2.6.1")

//3rd party libs
// 3rd party libs
implementation("com.intuit.sdp:sdp-android:1.0.6")
implementation("com.intuit.ssp:ssp-android:1.0.6")
implementation("com.google.dagger:hilt-android:2.44.2")
kapt("androidx.hilt:hilt-compiler:1.0.0")
kapt("com.google.dagger:hilt-android-compiler:2.44")
implementation("com.google.dagger:hilt-android:2.50")
ksp("androidx.hilt:hilt-compiler:1.1.0")
ksp("com.google.dagger:hilt-android-compiler:2.50")
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.17.3"
artifact = "com.google.protobuf:protoc:3.25.1"
}
generateProtoTasks {
all().forEach { task ->
Expand All @@ -109,4 +120,8 @@ protobuf {
}
}
}
}
}
ktlint {
android = true
ignoreFailures = false
}
4 changes: 1 addition & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@

<application
android:name=".App"
android:allowBackup="false"
android:configChanges="orientation|keyboardHidden|screenSize"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"
tools:replace="android:allowBackup">
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/sduduzog/slimlauncher/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class App : Application()
class App : Application()
100 changes: 62 additions & 38 deletions app/src/main/java/com/sduduzog/slimlauncher/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,25 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.navigation.NavController
import androidx.navigation.Navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.RecyclerView
import com.sduduzog.slimlauncher.utils.*
import com.sduduzog.slimlauncher.utils.BaseFragment
import com.sduduzog.slimlauncher.utils.HomeWatcher
import com.sduduzog.slimlauncher.utils.IPublisher
import com.sduduzog.slimlauncher.utils.ISubscriber
import com.sduduzog.slimlauncher.utils.SystemUiManager
import com.sduduzog.slimlauncher.utils.WallpaperManager
import dagger.hilt.android.AndroidEntryPoint
import java.lang.reflect.Method
import javax.inject.Inject
import kotlin.math.absoluteValue


@AndroidEntryPoint
class MainActivity : AppCompatActivity(),
class MainActivity :
AppCompatActivity(),
SharedPreferences.OnSharedPreferenceChangeListener,
HomeWatcher.OnHomePressedListener, IPublisher {
HomeWatcher.OnHomePressedListener,
IPublisher {

private val wallpaperManager = WallpaperManager(this)

Expand Down Expand Up @@ -65,8 +72,11 @@ class MainActivity : AppCompatActivity(),
setContentView(R.layout.main_activity)
settings = getSharedPreferences(getString(R.string.prefs_settings), MODE_PRIVATE)
settings.registerOnSharedPreferenceChangeListener(this)
navigator = findNavController(this, R.id.nav_host_fragment)
homeWatcher = HomeWatcher(this)
val navHostFragment = supportFragmentManager.findFragmentById(
R.id.nav_host_fragment
) as NavHostFragment
navigator = navHostFragment.navController
homeWatcher = HomeWatcher.createInstance(this)
homeWatcher.setOnHomePressedListener(this)
}

Expand Down Expand Up @@ -105,7 +115,11 @@ class MainActivity : AppCompatActivity(),
}
}

override fun onApplyThemeResource(theme: Resources.Theme?, @StyleRes resid: Int, first: Boolean) {
override fun onApplyThemeResource(
theme: Resources.Theme?,
@StyleRes resid: Int,
first: Boolean
) {
super.onApplyThemeResource(theme, resid, first)
wallpaperManager.onApplyThemeResource(theme, resid)
}
Expand Down Expand Up @@ -158,46 +172,56 @@ class MainActivity : AppCompatActivity(),

val actualPosition = Rect()
view.getGlobalVisibleRect(actualPosition)
val screen = Rect(0, 0, Resources.getSystem().displayMetrics.widthPixels, Resources.getSystem().displayMetrics.heightPixels)
val screen = Rect(
0,
0,
Resources.getSystem().displayMetrics.widthPixels,
Resources.getSystem().displayMetrics.heightPixels
)
return actualPosition.intersect(screen)
}

private val gestureDetector = GestureDetector(baseContext, object : SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) {
// Open Options
val recyclerView = findViewById<RecyclerView>(R.id.app_drawer_fragment_list)
val homeView = findViewById<View>(R.id.home_fragment)

if(homeView != null && recyclerView != null)
{
if(isVisible(recyclerView))
recyclerView.performLongClick()
else // we are in the homeFragment
findNavController(homeView).navigate(R.id.action_homeFragment_to_optionsFragment, null)

private val gestureDetector = GestureDetector(
baseContext,
object : SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) {
// Open Options
val recyclerView = findViewById<RecyclerView>(R.id.app_drawer_fragment_list)
val homeView = findViewById<View>(R.id.home_fragment)

if (homeView != null && recyclerView != null) {
if (isVisible(recyclerView)) {
recyclerView.performLongClick()
} else {
// we are in the homeFragment
findNavController(
homeView
).navigate(R.id.action_homeFragment_to_optionsFragment, null)
}
}
}
}

override fun onFling(
e1: MotionEvent,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
val homeView = findViewById<MotionLayout>(R.id.home_fragment)
if (homeView != null) {
val homeScreen = homeView.constraintSetIds[0]
val isFlingFromHomeScreen = homeView.currentState == homeScreen
val isFlingDown = velocityY > 0 && velocityY > velocityX.absoluteValue
if (isFlingDown && isFlingFromHomeScreen) {
expandStatusBar()
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
val homeView = findViewById<MotionLayout>(R.id.home_fragment)
if (homeView != null) {
val homeScreen = homeView.constraintSetIds[0]
val isFlingFromHomeScreen = homeView.currentState == homeScreen
val isFlingDown = velocityY > 0 && velocityY > velocityX.absoluteValue
if (isFlingDown && isFlingFromHomeScreen) {
expandStatusBar()
}
}
return super.onFling(e1, e2, velocityX, velocityY)
}
return super.onFling(e1, e2, velocityX, velocityY)
}
})
)

@SuppressLint("WrongConstant") // statusbar is an internal API
@SuppressLint("WrongConstant") // statusbar is an internal API
private fun expandStatusBar() {
try {
getSystemService("statusbar")?.let { service ->
Expand Down
Loading

0 comments on commit ebd5238

Please sign in to comment.