Compare commits

..

11 commits

Author SHA1 Message Date
Too Late (bot)
3a16cd003e
Merge 3e632c9892 into c1511cd475 2025-03-15 03:40:08 +01:00
c1511cd475
merge #124 - improve tutorial
Some checks are pending
Android CI / build (push) Waiting to run
* Add new "app list" section
* Rename fragments
* Replace screenshots
* Replace ViewPager by ViewPager2
* Add navigation buttons

Co-authored-by: Luke Wass <wassupluke@gmail.com>
2025-03-15 03:26:37 +01:00
toolatebot
3e632c9892 Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/
2025-03-15 00:07:18 +00:00
toolatebot
268acedb2c Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/
2025-03-15 00:07:18 +00:00
anmoti
4b756d47ee Translated using Weblate (Japanese)
Currently translated at 78.4% (200 of 255 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ja/
2025-03-15 00:07:18 +00:00
anmoti
e323309cf9 Translated using Weblate (Japanese)
Currently translated at 17.6% (3 of 17 strings)

Translation: jrpie-Launcher/metadata
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/ja/
2025-03-15 00:07:18 +00:00
class0068
47a5476978 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.4% (251 of 255 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/
2025-03-15 00:07:18 +00:00
3597baee1f
fix problem which switching from grayscale icons back to normal
Some checks are pending
Android CI / build (push) Waiting to run
2025-03-14 22:33:08 +01:00
e02ca4091f
0.1.0 2025-03-14 16:35:41 +01:00
541e60356c
implement #98 - disable functionality because of Android bug: https://issuetracker.google.com/issues/352276244#comment5 2025-03-14 16:35:13 +01:00
492749a340
remove global variables from ListActivity 2025-03-14 16:03:59 +01:00
40 changed files with 365 additions and 163 deletions

View file

@ -23,8 +23,8 @@ android {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 35 targetSdkVersion 35
compileSdk 35 compileSdk 35
versionCode 39 versionCode 40
versionName "0.0.23" versionName "0.1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

View file

@ -194,7 +194,7 @@ fun getApps(
loadList.add(detailedAppInfo) loadList.add(detailedAppInfo)
} }
} }
loadList.sortBy { it.getCustomLabel(context).toString() } loadList.sortBy { it.getCustomLabel(context) }
var end = System.currentTimeMillis() var end = System.currentTimeMillis()
Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)") Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)")

View file

@ -91,6 +91,7 @@ fun isPrivateSpaceLocked(context: Context): Boolean {
val privateSpaceUser = getPrivateSpaceUser(context) ?: return false val privateSpaceUser = getPrivateSpaceUser(context) ?: return false
return userManager.isQuietModeEnabled(privateSpaceUser) return userManager.isQuietModeEnabled(privateSpaceUser)
} }
fun lockPrivateSpace(context: Context, lock: Boolean) { fun lockPrivateSpace(context: Context, lock: Boolean) {
if (!isPrivateSpaceSupported()) { if (!isPrivateSpaceSupported()) {
return return
@ -123,10 +124,16 @@ fun togglePrivateSpaceLock(context: Context) {
} }
fun hidePrivateSpaceWhenLocked(context: Context): Boolean { fun hidePrivateSpaceWhenLocked(context: Context): Boolean {
// TODO: perhaps this should be cached // Trying to access the setting as a 3rd party launcher raises a security exception.
// This is an Android bug: https://issuetracker.google.com/issues/352276244#comment5
// The logic for this is implemented.
// TODO: replace this once the Android bug is fixed
return false
// TODO: perhaps this should be cached
// https://cs.android.com/android/platform/superproject/main/+/main:packages/apps/Launcher3/src/com/android/launcher3/util/SettingsCache.java;l=61;drc=56bf7ad33bc9d5ed3c18e7abefeec5c177ec75d7 // https://cs.android.com/android/platform/superproject/main/+/main:packages/apps/Launcher3/src/com/android/launcher3/util/SettingsCache.java;l=61;drc=56bf7ad33bc9d5ed3c18e7abefeec5c177ec75d7
val key = "hide_privatespace_entry_point"
return Settings.Secure.getInt(context.contentResolver, key, 0) == 1 // val key = "hide_privatespace_entry_point"
// return Settings.Secure.getInt(context.contentResolver, key, 0) == 1
} }

View file

@ -27,10 +27,14 @@ fun View.blink(
} }
// Taken from: https://stackoverflow.com/a/30340794/12787264 // Taken from: https://stackoverflow.com/a/30340794/12787264
fun ImageView.transformGrayscale() { fun ImageView.transformGrayscale(grayscale: Boolean) {
this.colorFilter = ColorMatrixColorFilter(ColorMatrix().apply { this.colorFilter = if (grayscale) {
setSaturation(0f) ColorMatrixColorFilter(ColorMatrix().apply {
}) setSaturation(0f)
})
} else {
null
}
} }

View file

@ -1,7 +1,6 @@
package de.jrpie.android.launcher.ui.list package de.jrpie.android.launcher.ui.list
import android.app.Activity import android.app.Activity
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Rect import android.graphics.Rect
@ -33,16 +32,6 @@ import de.jrpie.android.launcher.ui.list.apps.ListFragmentApps
import de.jrpie.android.launcher.ui.list.other.ListFragmentOther import de.jrpie.android.launcher.ui.list.other.ListFragmentOther
// TODO: Better solution for this intercommunication functionality (used in list-fragments)
var intention = ListActivity.ListActivityIntention.VIEW
var favoritesVisibility: AppFilter.Companion.AppSetVisibility =
AppFilter.Companion.AppSetVisibility.VISIBLE
var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility =
AppFilter.Companion.AppSetVisibility.VISIBLE
var hiddenVisibility: AppFilter.Companion.AppSetVisibility =
AppFilter.Companion.AppSetVisibility.HIDDEN
var forGesture: String? = null
/** /**
* The [ListActivity] is the most general purpose activity in Launcher: * The [ListActivity] is the most general purpose activity in Launcher:
* - used to view all apps and edit their settings * - used to view all apps and edit their settings
@ -52,11 +41,19 @@ var forGesture: String? = null
*/ */
class ListActivity : AppCompatActivity(), UIObject { class ListActivity : AppCompatActivity(), UIObject {
private lateinit var binding: ListBinding private lateinit var binding: ListBinding
var intention = ListActivityIntention.VIEW
var favoritesVisibility: AppFilter.Companion.AppSetVisibility =
AppFilter.Companion.AppSetVisibility.VISIBLE
var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility =
AppFilter.Companion.AppSetVisibility.VISIBLE
var hiddenVisibility: AppFilter.Companion.AppSetVisibility =
AppFilter.Companion.AppSetVisibility.HIDDEN
var forGesture: String? = null
private fun updateLockIcon(locked: Boolean) { private fun updateLockIcon(locked: Boolean) {
if ( if (
// only show lock for VIEW intention // only show lock for VIEW intention
(intention != ListActivityIntention.VIEW) (intention != ListActivityIntention.VIEW)
// hide lock when private space does not exist // hide lock when private space does not exist
|| !isPrivateSpaceSetUp(this) || !isPrivateSpaceSetUp(this)
@ -261,7 +258,7 @@ private val TAB_TITLES = arrayOf(
* The [ListSectionsPagerAdapter] returns the fragment, * The [ListSectionsPagerAdapter] returns the fragment,
* which corresponds to the selected tab in [ListActivity]. * which corresponds to the selected tab in [ListActivity].
*/ */
class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager) : class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentManager) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment { override fun getItem(position: Int): Fragment {
@ -273,11 +270,11 @@ class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager
} }
override fun getPageTitle(position: Int): CharSequence { override fun getPageTitle(position: Int): CharSequence {
return context.resources.getString(TAB_TITLES[position]) return activity.resources.getString(TAB_TITLES[position])
} }
override fun getCount(): Int { override fun getCount(): Int {
return when (intention) { return when (activity.intention) {
ListActivity.ListActivityIntention.VIEW -> 1 ListActivity.ListActivityIntention.VIEW -> 1
else -> 2 else -> 2
} }

View file

@ -47,6 +47,7 @@ class AppsRecyclerAdapter(
private val apps = (activity.applicationContext as Application).apps private val apps = (activity.applicationContext as Application).apps
private val appsListDisplayed: MutableList<AbstractDetailedAppInfo> = mutableListOf() private val appsListDisplayed: MutableList<AbstractDetailedAppInfo> = mutableListOf()
private val grayscale = LauncherPreferences.theme().monochromeIcons()
// temporarily disable auto launch // temporarily disable auto launch
var disableAutoLaunch: Boolean = false var disableAutoLaunch: Boolean = false
@ -79,20 +80,19 @@ class AppsRecyclerAdapter(
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) { override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
var appLabel = appsListDisplayed[i].getCustomLabel(activity) var appLabel = appsListDisplayed[i].getCustomLabel(activity)
val appIcon = appsListDisplayed[i].getIcon(activity)
viewHolder.img.transformGrayscale(grayscale)
viewHolder.img.setImageDrawable(appIcon.constantState?.newDrawable() ?: appIcon)
if (layout.useBadgedText) { if (layout.useBadgedText) {
appLabel = activity.packageManager.getUserBadgedLabel( appLabel = activity.packageManager.getUserBadgedLabel(
appLabel, appLabel,
appsListDisplayed[i].getUser(activity) appsListDisplayed[i].getUser(activity)
).toString() ).toString()
} }
val appIcon = appsListDisplayed[i].getIcon(activity)
viewHolder.textView.text = appLabel viewHolder.textView.text = appLabel
viewHolder.img.setImageDrawable(appIcon)
if (LauncherPreferences.theme().monochromeIcons())
viewHolder.img.transformGrayscale()
// decide when to show the options popup menu about // decide when to show the options popup menu about
if (intention == ListActivity.ListActivityIntention.VIEW) { if (intention == ListActivity.ListActivityIntention.VIEW) {

View file

@ -17,11 +17,6 @@ import de.jrpie.android.launcher.databinding.ListAppsBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.list.ListActivity import de.jrpie.android.launcher.ui.list.ListActivity
import de.jrpie.android.launcher.ui.list.favoritesVisibility
import de.jrpie.android.launcher.ui.list.forGesture
import de.jrpie.android.launcher.ui.list.hiddenVisibility
import de.jrpie.android.launcher.ui.list.intention
import de.jrpie.android.launcher.ui.list.privateSpaceVisibility
import de.jrpie.android.launcher.ui.openSoftKeyboard import de.jrpie.android.launcher.ui.openSoftKeyboard
@ -54,7 +49,7 @@ class ListFragmentApps : Fragment(), UIObject {
.registerOnSharedPreferenceChangeListener(sharedPreferencesListener) .registerOnSharedPreferenceChangeListener(sharedPreferencesListener)
binding.listAppsCheckBoxFavorites.isChecked = binding.listAppsCheckBoxFavorites.isChecked =
(favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) ((activity as? ListActivity)?.favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE)
} }
override fun onStop() { override fun onStop() {
@ -67,16 +62,17 @@ class ListFragmentApps : Fragment(), UIObject {
override fun setOnClicks() {} override fun setOnClicks() {}
override fun adjustLayout() { override fun adjustLayout() {
val listActivity = activity as? ListActivity ?: return
appsRecyclerAdapter = appsRecyclerAdapter =
AppsRecyclerAdapter( AppsRecyclerAdapter(
requireActivity(), binding.root, intention, forGesture, listActivity, binding.root, listActivity.intention, listActivity.forGesture,
appFilter = AppFilter( appFilter = AppFilter(
requireContext(), requireContext(),
"", "",
favoritesVisibility = favoritesVisibility, favoritesVisibility = listActivity.favoritesVisibility,
privateSpaceVisibility = privateSpaceVisibility, privateSpaceVisibility = listActivity.privateSpaceVisibility,
hiddenVisibility = hiddenVisibility hiddenVisibility = listActivity.hiddenVisibility
), ),
layout = LauncherPreferences.list().layout() layout = LauncherPreferences.list().layout()
) )
@ -124,7 +120,8 @@ class ListFragmentApps : Fragment(), UIObject {
if (newText == " " && if (newText == " " &&
!appsRecyclerAdapter.disableAutoLaunch && !appsRecyclerAdapter.disableAutoLaunch &&
intention == ListActivity.ListActivityIntention.VIEW && (activity as? ListActivity)?.intention
== ListActivity.ListActivityIntention.VIEW &&
LauncherPreferences.functionality().searchAutoLaunch() LauncherPreferences.functionality().searchAutoLaunch()
) { ) {
appsRecyclerAdapter.disableAutoLaunch = true appsRecyclerAdapter.disableAutoLaunch = true
@ -141,17 +138,17 @@ class ListFragmentApps : Fragment(), UIObject {
}) })
binding.listAppsCheckBoxFavorites.setOnClickListener { binding.listAppsCheckBoxFavorites.setOnClickListener {
favoritesVisibility = listActivity.favoritesVisibility =
if (binding.listAppsCheckBoxFavorites.isChecked) { if (binding.listAppsCheckBoxFavorites.isChecked) {
AppFilter.Companion.AppSetVisibility.EXCLUSIVE AppFilter.Companion.AppSetVisibility.EXCLUSIVE
} else { } else {
AppFilter.Companion.AppSetVisibility.VISIBLE AppFilter.Companion.AppSetVisibility.VISIBLE
} }
appsRecyclerAdapter.setFavoritesVisibility(favoritesVisibility) appsRecyclerAdapter.setFavoritesVisibility(listActivity.favoritesVisibility)
(activity as? ListActivity)?.updateTitle() (activity as? ListActivity)?.updateTitle()
} }
if (intention == ListActivity.ListActivityIntention.VIEW if (listActivity.intention == ListActivity.ListActivityIntention.VIEW
&& LauncherPreferences.functionality().searchAutoOpenKeyboard() && LauncherPreferences.functionality().searchAutoOpenKeyboard()
) { ) {
binding.listAppsSearchview.openSoftKeyboard(requireContext()) binding.listAppsSearchview.openSoftKeyboard(requireContext())

View file

@ -11,7 +11,7 @@ import androidx.recyclerview.widget.RecyclerView
import de.jrpie.android.launcher.R import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.actions.LauncherAction
import de.jrpie.android.launcher.ui.list.forGesture import de.jrpie.android.launcher.ui.list.ListActivity
/** /**
* The [OtherRecyclerAdapter] will only be displayed in the ListActivity, * The [OtherRecyclerAdapter] will only be displayed in the ListActivity,
@ -36,7 +36,7 @@ class OtherRecyclerAdapter(val activity: Activity) :
val pos = bindingAdapterPosition val pos = bindingAdapterPosition
val content = othersList[pos] val content = othersList[pos]
forGesture?.let { returnChoiceIntent(it, content) } (activity as? ListActivity)?.forGesture?.let { returnChoiceIntent(it, content) }
} }
init { init {

View file

@ -143,9 +143,7 @@ class ActionsRecyclerAdapter(val activity: Activity) :
val description = gesture.getDescription(activity) val description = gesture.getDescription(activity)
viewHolder.descriptionTextView.text = description viewHolder.descriptionTextView.text = description
viewHolder.img.transformGrayscale(LauncherPreferences.theme().monochromeIcons())
if (LauncherPreferences.theme().monochromeIcons())
viewHolder.img.transformGrayscale()
updateViewHolder(gesture, viewHolder) updateViewHolder(gesture, viewHolder)
viewHolder.img.setOnClickListener { chooseApp(gesture) } viewHolder.img.setOnClickListener { chooseApp(gesture) }

View file

@ -4,23 +4,26 @@ import android.content.Intent
import android.content.res.Resources import android.content.res.Resources
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.View
import android.window.OnBackInvokedDispatcher import android.window.OnBackInvokedDispatcher
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentPagerAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager.widget.ViewPager import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.databinding.TutorialBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.saveListActivityChoice import de.jrpie.android.launcher.saveListActivityChoice
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentConcept import de.jrpie.android.launcher.ui.blink
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentFinish import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment0Start
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentSetup import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment1Concept
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentStart import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment2Usage
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentUsage import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment3AppList
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment4Setup
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment5Finish
/** /**
* The [TutorialActivity] is displayed automatically on new installations. * The [TutorialActivity] is displayed automatically on new installations.
@ -31,10 +34,16 @@ import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentUsage
*/ */
class TutorialActivity : AppCompatActivity(), UIObject { class TutorialActivity : AppCompatActivity(), UIObject {
private lateinit var binding: TutorialBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super<AppCompatActivity>.onCreate(savedInstanceState) super<AppCompatActivity>.onCreate(savedInstanceState)
super<UIObject>.onCreate() super<UIObject>.onCreate()
// Initialise layout
binding = TutorialBinding.inflate(layoutInflater)
setContentView(binding.root)
// Handle back key / gesture on Android 13+ // Handle back key / gesture on Android 13+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
onBackInvokedDispatcher.registerOnBackInvokedCallback( onBackInvokedDispatcher.registerOnBackInvokedCallback(
@ -48,15 +57,51 @@ class TutorialActivity : AppCompatActivity(), UIObject {
} }
} }
// Initialise layout
setContentView(R.layout.tutorial)
// set up tabs and swiping in settings // set up tabs and swiping in settings
val sectionsPagerAdapter = TutorialSectionsPagerAdapter(supportFragmentManager) val sectionsPagerAdapter = TutorialSectionsPagerAdapter(this)
val viewPager: ViewPager = findViewById(R.id.tutorial_viewpager) binding.tutorialViewpager.apply {
viewPager.adapter = sectionsPagerAdapter adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.tutorial_tabs) currentItem = 0
tabs.setupWithViewPager(viewPager) registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
binding.tutorialButtonNext.apply {
val lastItem = sectionsPagerAdapter.itemCount - 1
visibility = if (position == lastItem) {
View.INVISIBLE
} else {
View.VISIBLE
}
if (position == 0) {
blink()
} else {
clearAnimation()
}
}
binding.tutorialButtonBack.apply {
visibility = if (position == 0) {
View.INVISIBLE
} else {
View.VISIBLE
}
}
}
})
}
TabLayoutMediator(binding.tutorialTabs, binding.tutorialViewpager) { _, _ -> }.attach()
binding.tutorialButtonNext.setOnClickListener {
binding.tutorialViewpager.apply {
setCurrentItem(
(currentItem + 1).coerceAtMost(sectionsPagerAdapter.itemCount - 1),
true
)
}
}
binding.tutorialButtonBack.setOnClickListener {
binding.tutorialViewpager.apply {
setCurrentItem((currentItem - 1).coerceAtLeast(0), true)
}
}
} }
override fun getTheme(): Resources.Theme { override fun getTheme(): Resources.Theme {
@ -89,26 +134,22 @@ class TutorialActivity : AppCompatActivity(), UIObject {
* *
* Tabs: (Start | Concept | Usage | Setup | Finish) * Tabs: (Start | Concept | Usage | Setup | Finish)
*/ */
class TutorialSectionsPagerAdapter(fm: FragmentManager) : class TutorialSectionsPagerAdapter(activity: FragmentActivity) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { FragmentStateAdapter(activity) {
override fun getItem(position: Int): Fragment { override fun getItemCount(): Int {
return 6
}
override fun createFragment(position: Int): Fragment {
return when (position) { return when (position) {
0 -> TutorialFragmentStart() 0 -> TutorialFragment0Start()
1 -> TutorialFragmentConcept() 1 -> TutorialFragment1Concept()
2 -> TutorialFragmentUsage() 2 -> TutorialFragment2Usage()
3 -> TutorialFragmentSetup() 3 -> TutorialFragment3AppList()
4 -> TutorialFragmentFinish() 4 -> TutorialFragment4Setup()
5 -> TutorialFragment5Finish()
else -> Fragment() else -> Fragment()
} }
} }
/* We don't use titles here, as we have the dots */
override fun getPageTitle(position: Int): CharSequence {
return ""
}
override fun getCount(): Int {
return 5
}
} }

View file

@ -5,24 +5,22 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import de.jrpie.android.launcher.databinding.TutorialStartBinding import de.jrpie.android.launcher.databinding.Tutorial0StartBinding
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.blink
/** /**
* The [TutorialFragmentStart] is a used as a tab in the TutorialActivity. * The [TutorialFragment0Start] is a used as a tab in the TutorialActivity.
* *
* It displays info about the app and gets the user into the tutorial * It displays info about the app and gets the user into the tutorial
*/ */
class TutorialFragmentStart : Fragment(), UIObject { class TutorialFragment0Start : Fragment(), UIObject {
private lateinit var binding: TutorialStartBinding private lateinit var binding: Tutorial0StartBinding
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
binding = TutorialStartBinding.inflate(inflater, container, false) binding = Tutorial0StartBinding.inflate(inflater, container, false)
binding.tutorialStartIconRight.blink()
return binding.root return binding.root
} }

View file

@ -6,22 +6,22 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.BuildConfig
import de.jrpie.android.launcher.databinding.TutorialConceptBinding import de.jrpie.android.launcher.databinding.Tutorial1ConceptBinding
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
/** /**
* The [TutorialFragmentConcept] is a used as a tab in the TutorialActivity. * The [TutorialFragment1Concept] is a used as a tab in the TutorialActivity.
* *
* It is used to display info about Launchers concept (open source, efficiency ...) * It is used to display info about Launchers concept (open source, efficiency ...)
*/ */
class TutorialFragmentConcept : Fragment(), UIObject { class TutorialFragment1Concept : Fragment(), UIObject {
private lateinit var binding: TutorialConceptBinding private lateinit var binding: Tutorial1ConceptBinding
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
binding = TutorialConceptBinding.inflate(inflater, container, false) binding = Tutorial1ConceptBinding.inflate(inflater, container, false)
binding.tutorialConceptBadgeVersion.text = BuildConfig.VERSION_NAME binding.tutorialConceptBadgeVersion.text = BuildConfig.VERSION_NAME
return binding.root return binding.root
} }

View file

@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
/** /**
* The [TutorialFragmentUsage] is a used as a tab in the TutorialActivity. * The [TutorialFragment2Usage] is a used as a tab in the TutorialActivity.
* *
* Tells the user how his screen will look and how the app can be used * Tells the user how his screen will look and how the app can be used
*/ */
class TutorialFragmentUsage : Fragment(), UIObject { class TutorialFragment2Usage : Fragment(), UIObject {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
return inflater.inflate(R.layout.tutorial_usage, container, false) return inflater.inflate(R.layout.tutorial_2_usage, container, false)
} }
override fun onStart() { override fun onStart() {

View file

@ -0,0 +1,30 @@
package de.jrpie.android.launcher.ui.tutorial.tabs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.ui.UIObject
/**
* The [TutorialFragment3AppList] is a used as a tab in the TutorialActivity.
*
* Tells the user how his screen will look and how the app can be used
*/
class TutorialFragment3AppList : Fragment(), UIObject {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.tutorial_3_app_list, container, false)
}
override fun onStart() {
super<Fragment>.onStart()
super<UIObject>.onStart()
}
}

View file

@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
/** /**
* The [TutorialFragmentSetup] is a used as a tab in the TutorialActivity. * The [TutorialFragment4Setup] is a used as a tab in the TutorialActivity.
* *
* It is used to display info in the tutorial * It is used to display info in the tutorial
*/ */
class TutorialFragmentSetup : Fragment(), UIObject { class TutorialFragment4Setup : Fragment(), UIObject {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
return inflater.inflate(R.layout.tutorial_setup, container, false) return inflater.inflate(R.layout.tutorial_4_setup, container, false)
} }
override fun onStart() { override fun onStart() {

View file

@ -6,25 +6,25 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import de.jrpie.android.launcher.BuildConfig.VERSION_CODE import de.jrpie.android.launcher.BuildConfig.VERSION_CODE
import de.jrpie.android.launcher.databinding.TutorialFinishBinding import de.jrpie.android.launcher.databinding.Tutorial5FinishBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.setDefaultHomeScreen import de.jrpie.android.launcher.setDefaultHomeScreen
import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.UIObject
/** /**
* The [TutorialFragmentFinish] is a used as a tab in the TutorialActivity. * The [TutorialFragment5Finish] is a used as a tab in the TutorialActivity.
* *
* It is used to display further resources and let the user start Launcher * It is used to display further resources and let the user start Launcher
*/ */
class TutorialFragmentFinish : Fragment(), UIObject { class TutorialFragment5Finish : Fragment(), UIObject {
private lateinit var binding: TutorialFinishBinding private lateinit var binding: Tutorial5FinishBinding
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
binding = TutorialFinishBinding.inflate(inflater, container, false) binding = Tutorial5FinishBinding.inflate(inflater, container, false)
return binding.root return binding.root
} }

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:textColor"
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" />
</vector>

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:textColor"
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://stackoverflow.com/a/30692466 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -10,7 +10,7 @@
tools:context=".ui.tutorial.TutorialActivity"> tools:context=".ui.tutorial.TutorialActivity">
<androidx.viewpager.widget.ViewPager <androidx.viewpager2.widget.ViewPager2
android:id="@+id/tutorial_viewpager" android:id="@+id/tutorial_viewpager"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
@ -22,15 +22,37 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" /> app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="@+id/tutorial_button_back"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center"
android:alpha="0.5"
android:src="@drawable/baseline_navigate_before_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_viewpager" />
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/tutorial_tabs" android:id="@+id/tutorial_tabs"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tutorial_button_next"
app:layout_constraintStart_toEndOf="@+id/tutorial_button_back"
app:tabBackground="@drawable/tutorial_tab_selector" app:tabBackground="@drawable/tutorial_tab_selector"
app:tabGravity="center" app:tabGravity="center"
app:tabIndicatorHeight="0dp" app:tabIndicatorHeight="0dp" />
<ImageView
android:id="@+id/tutorial_button_next"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center"
android:src="@drawable/baseline_navigate_next_24"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintTop_toBottomOf="@+id/tutorial_viewpager" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -8,7 +8,7 @@
android:paddingRight="32sp" android:paddingRight="32sp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.tutorial.tabs.TutorialFragmentStart"> tools:context=".ui.tutorial.tabs.TutorialFragment0Start">
<TextView <TextView
android:id="@+id/tutorial_start_text" android:id="@+id/tutorial_start_text"
@ -21,16 +21,4 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tutorial_start_icon_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=">>>>>>"
android:textSize="64sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_start_text" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -8,7 +8,7 @@
android:paddingRight="32sp" android:paddingRight="32sp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.tutorial.tabs.TutorialFragmentConcept"> tools:context=".ui.tutorial.tabs.TutorialFragment1Concept">
<TextView <TextView
android:id="@+id/tutorial_concept_title" android:id="@+id/tutorial_concept_title"
@ -28,11 +28,10 @@
android:gravity="center" android:gravity="center"
android:text="@string/tutorial_concept_text" android:text="@string/tutorial_concept_text"
android:textSize="18sp" android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_title" app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_title"
app:layout_constraintVertical_bias="0.19999999" /> app:layout_constraintBottom_toTopOf="@id/tutorial_concept_badge_version_label"/>
<TextView <TextView
android:id="@+id/tutorial_concept_text_2" android:id="@+id/tutorial_concept_text_2"
@ -60,6 +59,22 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_text" app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_text"
tools:text="0.0.7"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tutorial_concept_badge_version_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:gravity="center"
android:textSize="18sp"
android:text="@string/tutorial_concept_label_version"
app:layout_constraintBottom_toTopOf="@+id/tutorial_concept_badge_version"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -7,7 +7,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingLeft="32sp" android:paddingLeft="32sp"
android:paddingRight="32sp" android:paddingRight="32sp"
tools:context=".ui.tutorial.tabs.TutorialFragmentUsage"> tools:context=".ui.tutorial.tabs.TutorialFragment2Usage">
<TextView <TextView
android:id="@+id/tutorial_usage_title" android:id="@+id/tutorial_usage_title"
@ -39,12 +39,12 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:scaleType="centerInside" android:scaleType="centerInside"
android:src="@drawable/home_round_screen" android:src="@drawable/tutorial_home_screen"
app:layout_constraintBottom_toTopOf="@id/tutorial_usage_text_2" app:layout_constraintBottom_toTopOf="@id/tutorial_usage_text_2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/tutorial_usage_text" app:layout_constraintStart_toStartOf="@+id/tutorial_usage_text"
app:layout_constraintTop_toBottomOf="@id/tutorial_usage_text" app:layout_constraintTop_toBottomOf="@id/tutorial_usage_text"
app:srcCompat="@drawable/home_round_screen" app:srcCompat="@drawable/tutorial_home_screen"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView <TextView

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tutorial_usage_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="32sp"
android:paddingRight="32sp"
tools:context=".ui.tutorial.tabs.TutorialFragment3AppList">
<TextView
android:id="@+id/tutorial_app_list_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/tutorial_app_list_title"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tutorial_app_list_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:text="@string/tutorial_app_list_text"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/tutorial_app_list_screen"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tutorial_app_list_title" />
<ImageView
android:id="@+id/tutorial_app_list_screen"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerInside"
android:src="@drawable/tutorial_app_list"
app:layout_constraintBottom_toTopOf="@id/tutorial_app_list_text_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/tutorial_app_list_text"
app:layout_constraintTop_toBottomOf="@id/tutorial_app_list_text"
app:srcCompat="@drawable/tutorial_app_list"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tutorial_app_list_text_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:text="@string/tutorial_app_list_text_2"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_app_list_screen" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -8,7 +8,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingLeft="32sp" android:paddingLeft="32sp"
android:paddingRight="32sp" android:paddingRight="32sp"
tools:context=".ui.tutorial.tabs.TutorialFragmentSetup"> tools:context=".ui.tutorial.tabs.TutorialFragment4Setup">
<TextView <TextView
android:id="@+id/tutorial_setup_title" android:id="@+id/tutorial_setup_title"

View file

@ -7,7 +7,7 @@
android:paddingRight="32sp" android:paddingRight="32sp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.tutorial.tabs.TutorialFragmentFinish"> tools:context=".ui.tutorial.tabs.TutorialFragment5Finish">
<TextView <TextView
android:id="@+id/tutorial_finish_title" android:id="@+id/tutorial_finish_title"
@ -24,6 +24,7 @@
android:id="@+id/tutorial_finish_text" android:id="@+id/tutorial_finish_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/tutorial_finish_text" android:text="@string/tutorial_finish_text"
android:textSize="18sp" android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@id/tutorial_finish_button_start" app:layout_constraintBottom_toTopOf="@id/tutorial_finish_button_start"

View file

@ -117,7 +117,6 @@
<string name="settings_list_layout_item_grid">Raster</string> <string name="settings_list_layout_item_grid">Raster</string>
<string name="settings_general_choose_home_screen">Launcher wählen</string> <string name="settings_general_choose_home_screen">Launcher wählen</string>
<string name="settings_meta_cant_select_launcher">App Info</string> <string name="settings_meta_cant_select_launcher">App Info</string>
<string name="settings_meta_cant_select_launcher_msg">Das Gerät unterstützt diese Funktion nicht. Stattdessen die App Details bearbeiten?</string>
<string name="settings_meta_show_tutorial">Zum Tutorial</string> <string name="settings_meta_show_tutorial">Zum Tutorial</string>
<string name="settings_meta_reset">Einstellungen zurücksetzen</string> <string name="settings_meta_reset">Einstellungen zurücksetzen</string>
<string name="settings_meta_reset_confirm">Alle Einstellungen gehen verloren. Weitermachen?</string> <string name="settings_meta_reset_confirm">Alle Einstellungen gehen verloren. Weitermachen?</string>

View file

@ -75,7 +75,6 @@
--> -->
<string name="settings_general_choose_home_screen">Seleccionar Launcher</string> <string name="settings_general_choose_home_screen">Seleccionar Launcher</string>
<string name="settings_meta_cant_select_launcher">Información de la aplicación</string> <string name="settings_meta_cant_select_launcher">Información de la aplicación</string>
<string name="settings_meta_cant_select_launcher_msg">Su dispositivo no posee esta caracrerística. Desea cambiar los detalles de la aplicación?</string>
<string name="settings_meta_show_tutorial">Ver tutorial de Launcher</string> <string name="settings_meta_show_tutorial">Ver tutorial de Launcher</string>
<string name="settings_meta_reset">Configuración por defecto</string> <string name="settings_meta_reset">Configuración por defecto</string>
<string name="settings_meta_reset_confirm">Todas sus preferencias se eliminarán. Desea continuar?</string> <string name="settings_meta_reset_confirm">Todas sus preferencias se eliminarán. Desea continuar?</string>

View file

@ -67,7 +67,6 @@
--> -->
<string name="settings_general_choose_home_screen">Choisir μLauncher comme application d\'écran d\'accueil par défaut</string> <string name="settings_general_choose_home_screen">Choisir μLauncher comme application d\'écran d\'accueil par défaut</string>
<string name="settings_meta_cant_select_launcher">Informations sur l\'application</string> <string name="settings_meta_cant_select_launcher">Informations sur l\'application</string>
<string name="settings_meta_cant_select_launcher_msg">Votre appareil ne prend pas en charge cette fonctionnalité. Souhaitez-vous plutôt accéder aux détails de l\'application ?</string>
<string name="settings_meta_show_tutorial">Regarder le tutoriel</string> <string name="settings_meta_show_tutorial">Regarder le tutoriel</string>
<string name="settings_meta_reset">Réinitialiser</string> <string name="settings_meta_reset">Réinitialiser</string>
<string name="settings_meta_reset_confirm">Vous allez réinitialiser tous vos paramètres. Souhaitez-vous poursuivre ?</string> <string name="settings_meta_reset_confirm">Vous allez réinitialiser tous vos paramètres. Souhaitez-vous poursuivre ?</string>

View file

@ -34,7 +34,6 @@
<br/><br/><br/><br/> <br/><br/><br/><br/>
Puoi cambiare le tue scelte in seguito nelle impostazioni. Puoi cambiare le tue scelte in seguito nelle impostazioni.
]]></string> ]]></string>
<string name="settings_meta_cant_select_launcher_msg">Il tuo dispositivo non supporta questa funzione. Vuoi aprire la pagina di dettaglio dell\'applicazione?</string>
<string name="alert_cant_open_title">Impossibile aprire l\'applicazione</string> <string name="alert_cant_open_title">Impossibile aprire l\'applicazione</string>
<string name="alert_cant_open_message">Desideri modificare le impostazioni?</string> <string name="alert_cant_open_message">Desideri modificare le impostazioni?</string>
<string name="toast_cant_open_message">Apri le impostazioni per abbinare un\'azione a questo gesto</string> <string name="toast_cant_open_message">Apri le impostazioni per abbinare un\'azione a questo gesto</string>

View file

@ -192,7 +192,6 @@
<string name="settings_functionality_auto_launch_summary">この機能を一時的に無効にするにはスペースキーを押します。</string> <string name="settings_functionality_auto_launch_summary">この機能を一時的に無効にするにはスペースキーを押します。</string>
<string name="list_other_list_private_space">プライベートスペース</string> <string name="list_other_list_private_space">プライベートスペース</string>
<string name="settings_apps_hide_private_space_apps">アプリ一覧からプライベートスペースを隠す</string> <string name="settings_apps_hide_private_space_apps">アプリ一覧からプライベートスペースを隠す</string>
<string name="settings_meta_cant_select_launcher_msg">この機能はあなたのデバイスでは動作しません。代わりにアプリケーションの詳細を管理しますか?</string>
<string name="settings_meta_report_bug">バグを報告</string> <string name="settings_meta_report_bug">バグを報告</string>
<string name="tutorial_start_text">このランチャーの使い方を学ぶのにほんの数秒しかかかりません</string> <string name="tutorial_start_text">このランチャーの使い方を学ぶのにほんの数秒しかかかりません</string>
<string name="tutorial_concept_text">Launcherは、最小限かつ効率的で、邪魔にならないように設計されています。支払い、広告、追跡サービスは一切ありません。</string> <string name="tutorial_concept_text">Launcherは、最小限かつ効率的で、邪魔にならないように設計されています。支払い、広告、追跡サービスは一切ありません。</string>

View file

@ -79,7 +79,6 @@
--> -->
<string name="settings_general_choose_home_screen">Definir o μLauncher como tela inicial</string> <string name="settings_general_choose_home_screen">Definir o μLauncher como tela inicial</string>
<string name="settings_meta_cant_select_launcher">Informações do aplicativo</string> <string name="settings_meta_cant_select_launcher">Informações do aplicativo</string>
<string name="settings_meta_cant_select_launcher_msg">Seu dispositivo não é compatível com esse recurso. Gerenciar detalhes do app em vez disso?</string>
<string name="settings_meta_show_tutorial">Ver tutorial do launcher</string> <string name="settings_meta_show_tutorial">Ver tutorial do launcher</string>
<string name="settings_meta_reset">Redefinir configuraçãos</string> <string name="settings_meta_reset">Redefinir configuraçãos</string>
<string name="settings_meta_reset_confirm">Você vai descartar todas as suas preferências. Continuar?</string> <string name="settings_meta_reset_confirm">Você vai descartar todas as suas preferências. Continuar?</string>

View file

@ -164,7 +164,6 @@
<string name="settings_list_layout_item_text">Metin</string> <string name="settings_list_layout_item_text">Metin</string>
<string name="settings_list_layout_item_grid">Izgara</string> <string name="settings_list_layout_item_grid">Izgara</string>
<string name="settings_meta_cant_select_launcher">Uygulama Detayı</string> <string name="settings_meta_cant_select_launcher">Uygulama Detayı</string>
<string name="settings_meta_cant_select_launcher_msg">Sizin cihazınız bu özelliği desteklemiyor. Onun yerine uygulama detaylarını düzenleyin?</string>
<string name="settings_meta_reset">Ayarları Sıfırlayın</string> <string name="settings_meta_reset">Ayarları Sıfırlayın</string>
<string name="settings_meta_reset_confirm">Tüm tercihlerinizi bir kenara bırakacaksınız. Devam mı?</string> <string name="settings_meta_reset_confirm">Tüm tercihlerinizi bir kenara bırakacaksınız. Devam mı?</string>
<string name="settings_theme_font_item_monospace">Tek uzay</string> <string name="settings_theme_font_item_monospace">Tek uzay</string>

View file

@ -50,7 +50,6 @@
<string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string> <string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string>
<string name="settings_launcher_sensitivity">灵敏度</string> <string name="settings_launcher_sensitivity">灵敏度</string>
<string name="settings_meta_cant_select_launcher">应用信息</string> <string name="settings_meta_cant_select_launcher">应用信息</string>
<string name="settings_meta_cant_select_launcher_msg">您的设备不支持此功能。要不打开应用程序详细?</string>
<string name="settings_meta_show_tutorial">查看启动器教程</string> <string name="settings_meta_show_tutorial">查看启动器教程</string>
<string name="settings_meta_reset">重置设置</string> <string name="settings_meta_reset">重置设置</string>
<string name="settings_meta_reset_confirm">你将放弃你所有的配置。继续吗?</string> <string name="settings_meta_reset_confirm">你将放弃你所有的配置。继续吗?</string>

View file

@ -176,7 +176,7 @@
<!-- Legal --> <!-- Legal -->
<string name="legal_info_text"><![CDATA[ <string name="legal_info_text"><![CDATA[
<h2>µLauncher</h2> <h2>μLauncher</h2>
Modifications to Launcher. Modifications to Launcher.
<p><a href=\"https://github.com/jrpie/launcher\">github.com/jrpie/launcher</a></p> <p><a href=\"https://github.com/jrpie/launcher\">github.com/jrpie/launcher</a></p>

View file

@ -179,7 +179,7 @@
<string name="settings_apps_hide_paused_apps">Hide paused apps</string> <string name="settings_apps_hide_paused_apps">Hide paused apps</string>
<string name="settings_apps_hide_private_space_apps">Hide private space from app list</string> <string name="settings_apps_hide_private_space_apps">Hide private space from app list</string>
<string name="settings_list_layout">Layout of app list</string> <string name="settings_list_layout">Layout of app list</string>
<string name="settings_list_reverse_layout">Reverse app list</string> <string name="settings_list_reverse_layout">Reverse the app list</string>
<string name="settings_list_layout_item_default">Default</string> <string name="settings_list_layout_item_default">Default</string>
<string name="settings_list_layout_item_text">Text</string> <string name="settings_list_layout_item_text">Text</string>
@ -193,7 +193,7 @@
<string name="settings_general_choose_home_screen">Set μLauncher as home screen</string> <string name="settings_general_choose_home_screen">Set μLauncher as home screen</string>
<string name="settings_meta_cant_select_launcher">App Info</string> <string name="settings_meta_cant_select_launcher">App Info</string>
<string name="settings_meta_show_tutorial">View Launcher Tutorial</string> <string name="settings_meta_show_tutorial">View µLauncher Tutorial</string>
<string name="settings_meta_reset">Reset Settings</string> <string name="settings_meta_reset">Reset Settings</string>
<string name="settings_meta_reset_confirm">You are going to discard all your preferences. Continue?</string> <string name="settings_meta_reset_confirm">You are going to discard all your preferences. Continue?</string>
@ -202,14 +202,14 @@
<string name="settings_meta_report_bug">Report a bug</string> <string name="settings_meta_report_bug">Report a bug</string>
<string name="dialog_report_bug_title">Report a bug</string> <string name="dialog_report_bug_title">Report a bug</string>
<string name="dialog_report_bug_info">Thank you for helping to improve µLauncher!\nPlease consider adding the following information to your bug report:</string> <string name="dialog_report_bug_info">Thank you for helping to improve μLauncher!\nPlease consider adding the following information to your bug report:</string>
<string name="dialog_report_bug_button_clipboard">Copy to clipboard</string> <string name="dialog_report_bug_button_clipboard">Copy to clipboard</string>
<string name="dialog_report_bug_security_info">Please do not report security vulnerabilities publicly on GitHub, but use the following instead:</string> <string name="dialog_report_bug_security_info">Please do not report security vulnerabilities publicly on GitHub, but use the following instead:</string>
<string name="dialog_report_bug_button_security">Report a security vulnerability</string> <string name="dialog_report_bug_button_security">Report a security vulnerability</string>
<string name="dialog_report_bug_create_report">Create report</string> <string name="dialog_report_bug_create_report">Create report</string>
<string name="settings_meta_fork_contact">Contact the developer of the fork</string> <string name="settings_meta_fork_contact">Contact the developer of the fork</string>
<string name="settings_meta_join_chat">Join µLauncher chat</string> <string name="settings_meta_join_chat">Join μLauncher chat</string>
<string name="settings_meta_donate">Donate</string> <string name="settings_meta_donate">Donate</string>
<string name="settings_meta_privacy">Privacy Policy</string> <string name="settings_meta_privacy">Privacy Policy</string>
@ -246,7 +246,7 @@
<string name="list_apps_search_hint">Search</string> <string name="list_apps_search_hint">Search</string>
<string name="list_apps_search_hint_no_auto_launch">Search (no auto launch)</string> <string name="list_apps_search_hint_no_auto_launch">Search (no auto launch)</string>
<string name="list_other_settings">µLauncher Settings</string> <string name="list_other_settings">μLauncher Settings</string>
<string name="list_other_list">All Applications</string> <string name="list_other_list">All Applications</string>
<string name="list_other_list_favorites">Favorite Applications</string> <string name="list_other_list_favorites">Favorite Applications</string>
<string name="list_other_list_private_space">Private Space</string> <string name="list_other_list_private_space">Private Space</string>
@ -274,22 +274,29 @@
- -
--> -->
<string name="tutorial_title">Tutorial</string> <string name="tutorial_title">Tutorial</string>
<string name="tutorial_start_text">Take a few seconds to learn how to use this Launcher!</string> <string name="tutorial_start_text">👋\n\nTake a few seconds to learn how to use this Launcher!</string>
<string name="tutorial_concept_title">Concept</string> <string name="tutorial_concept_title">Concept</string>
<string name="tutorial_concept_text">Launcher is designed to be minimal, efficient and free of distraction. It is free of payments, ads and tracking services.</string> <string name="tutorial_concept_text">μLauncher is designed to be minimal, efficient and free of distraction.
<string name="tutorial_concept_text_2">The app is open-source (MIT license) and available on GitHub! Make sure to check out the repository!</string> \n\nIt contains no ads and collects no data.</string>
<string name="tutorial_concept_text_2">It is free software (MIT license)!\nMake sure to check out the repository!</string>
<string name="tutorial_concept_label_version">Version</string>
<string name="tutorial_usage_title">Usage</string> <string name="tutorial_usage_title">Usage</string>
<string name="tutorial_usage_text">Your home screen contains the local date and time. No distraction.</string> <string name="tutorial_usage_text">Your home screen contains the local date and time. No distraction.</string>
<string name="tutorial_usage_text_2">You can launch your apps with a single swipe or button press. Choose some in the next slide.</string> <string name="tutorial_usage_text_2">You can launch your most important apps with touch gestures or button presses.</string>
<string name="tutorial_app_list_title">All Apps</string>
<string name="tutorial_app_list_text">You can quickly search through all apps in the app list.\n\nSwipe up to open it, or bind it to a different gesture.</string>
<string name="tutorial_app_list_text_2">Once only one app matches, it launches automatically.\nThis can be disabled by prefixing the query with a space.</string>
<string name="tutorial_setup_title">Setup</string> <string name="tutorial_setup_title">Setup</string>
<string name="tutorial_setup_text">We chose some default apps for you. You can change them now if you want to:</string> <string name="tutorial_setup_text">We chose some default apps for you. You can change them now if you want to:</string>
<string name="tutorial_setup_text_2">You can also change your selection later.</string> <string name="tutorial_setup_text_2">You can also change your selection later.</string>
<string name="tutorial_finish_title">Let\'s go!</string> <string name="tutorial_finish_title">Let\'s go!</string>
<string name="tutorial_finish_text">You are ready to get started! I hope this is of great value to you! - Finn (who made Launcher) \tand Josia (who made some improvements and maintains the fork μLauncher)</string> <string name="tutorial_finish_text">You are ready to get started!\n\nI hope this is of great value to you!\n\n- Finn (who made Launcher) and Josia (who made some improvements and maintains the fork μLauncher)</string>
<string name="tutorial_finish_button">Start</string> <string name="tutorial_finish_button">Start</string>
@ -301,7 +308,7 @@
<string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string> <string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string>
<string name="undo">Undo</string> <string name="undo">Undo</string>
<string name="list_other_expand_settings_panel">Quick Settings</string> <string name="list_other_expand_settings_panel">Quick Settings</string>
<string name="toast_device_admin_not_enabled">µLauncher needs to be a device admin in order to lock the screen.</string> <string name="toast_device_admin_not_enabled">μLauncher needs to be a device admin in order to lock the screen.</string>
<string name="device_admin_explanation">This is required for the lock screen action.</string> <string name="device_admin_explanation">This is required for the lock screen action.</string>
<string name="device_admin_description">Enable the lock screen action</string> <string name="device_admin_description">Enable the lock screen action</string>
<string name="alert_no_torch_found">No camera with torch detected.</string> <string name="alert_no_torch_found">No camera with torch detected.</string>
@ -311,18 +318,18 @@
<string name="toast_private_space_locked">Private space locked</string> <string name="toast_private_space_locked">Private space locked</string>
<string name="toast_private_space_unlocked">Private space unlocked</string> <string name="toast_private_space_unlocked">Private space unlocked</string>
<string name="toast_private_space_not_available">Private space is not available</string> <string name="toast_private_space_not_available">Private space is not available</string>
<string name="toast_private_space_default_home_screen">µLauncher needs to be the default home screen to access private space.</string> <string name="toast_private_space_default_home_screen">μLauncher needs to be the default home screen to access private space.</string>
<string name="tooltip_lock_private_space">Lock private space</string> <string name="tooltip_lock_private_space">Lock private space</string>
<string name="tooltip_unlock_private_space">Unlock private space</string> <string name="tooltip_unlock_private_space">Unlock private space</string>
<string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string> <string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string>
<string name="accessibility_service_name">µLauncher - lock screen</string> <string name="accessibility_service_name">μLauncher - lock screen</string>
<string name="accessibility_service_description"> <string name="accessibility_service_description">
Setting µLauncher as an accessibility service allows it to lock the screen. Setting μLauncher as an accessibility service allows it to lock the screen.
Note that excessive permissions are required. You should never grant such permissions lightly to any app. Note that excessive permissions are required. You should never grant such permissions lightly to any app.
µLauncher will use the accessibility service only for locking the screen. You can check the source code to make sure. μLauncher will use the accessibility service only for locking the screen. You can check the source code to make sure.
Note that locking the screen can also be accomplished by granting µLauncher device administrator permissions. However that method doesn\'t work with fingerprint and face unlock. Note that locking the screen can also be accomplished by granting μLauncher device administrator permissions. However that method doesn\'t work with fingerprint and face unlock.
</string> </string>
@ -340,7 +347,7 @@
<h3>Accessibility Service</h3> <h3>Accessibility Service</h3>
Requires excessive privileges. Requires excessive privileges.
µLauncher will use those privileges only for locking the screen. μLauncher will use those privileges only for locking the screen.
<br/> <br/>
(You really should not trust a random app you just downloaded with such a claim, but you can check the <a href=\"https://github.com/jrpie/Launcher\">source code</a>.) (You really should not trust a random app you just downloaded with such a claim, but you can check the <a href=\"https://github.com/jrpie/Launcher\">source code</a>.)
<br/> <br/>
@ -363,11 +370,11 @@
<string name="dialog_select_color_ok">Ok</string> <string name="dialog_select_color_ok">Ok</string>
<string name="dialog_select_color_color_hex">Color</string> <string name="dialog_select_color_color_hex">Color</string>
<string name="dialog_choose_color_title">Choose color</string> <string name="dialog_choose_color_title">Choose color</string>
<string name="dialog_consent_accessibility_privileges">I am aware that this will grant far-reaching privileges to µLauncher.</string> <string name="dialog_consent_accessibility_privileges">I am aware that this will grant far-reaching privileges to μLauncher.</string>
<string name="dialog_consent_accessibility_other_options">I am aware that other options exist (using device administrator privileges or the power button).</string> <string name="dialog_consent_accessibility_other_options">I am aware that other options exist (using device administrator privileges or the power button).</string>
<string name="dialog_consent_accessibility_consent">I consent to µLauncher using the accessibility service to provide functionality unrelated to accessibility.</string> <string name="dialog_consent_accessibility_consent">I consent to μLauncher using the accessibility service to provide functionality unrelated to accessibility.</string>
<string name="dialog_consent_accessibility_data_collection">I consent to µLauncher not collecting any data.</string> <string name="dialog_consent_accessibility_data_collection">I consent to μLauncher not collecting any data.</string>
<string name="dialog_consent_accessibility_text"><![CDATA[You are about to activate the accessibility service. This will grant <strong>far-reaching privileges</strong> to µLauncher.<br/>µLauncher will use these privileges <strong>only to lock the screen</strong>. µLauncher <strong>will never collect any data</strong>. In particular, µLauncher does not use the accessibility service to collect any data.]]></string> <string name="dialog_consent_accessibility_text"><![CDATA[You are about to activate the accessibility service. This will grant <strong>far-reaching privileges</strong> to μLauncher.<br/>μLauncher will use these privileges <strong>only to lock the screen</strong>. μLauncher <strong>will never collect any data</strong>. In particular, μLauncher does not use the accessibility service to collect any data.]]></string>
<string name="dialog_consent_accessibility_title">Activating the Accessibility Service</string> <string name="dialog_consent_accessibility_title">Activating the Accessibility Service</string>
<string name="dialog_consent_accessibility_ok">Activate Accessibility Service</string> <string name="dialog_consent_accessibility_ok">Activate Accessibility Service</string>
<string name="dialog_cancel">Cancel</string> <string name="dialog_cancel">Cancel</string>

View file

@ -0,0 +1,13 @@
* Pinned shortcuts can now be added to app list
* New action: adjust volume (thank you, zabrinu!)
* Added option to hide navigation bar (thank you, acanoe!)
* Added option to reverse the app list (thank you, spacefrogg!)
* Show question mark icon when an unknown app is bound to a gesture
* Improved German translation
* Improved Portuguese translation (thank you, "Vossa Excelencia"!)
* Fixed detection of long click gesture
* Fixed blurred text in dialogs
* Fixed a crash when private space is locked after app restarts (thank you, alexytomi!)
* Fixed some additional bugs