Compare commits

..

5 commits

Author SHA1 Message Date
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
26 changed files with 112 additions and 326 deletions

View file

@ -87,40 +87,24 @@ class TouchGestureDetector(
}
private var paths = HashMap<Int, PointerPath>()
/* Set when
* - the longPressHandler has detected this gesture as a long press
* - the gesture was cancelled by MotionEvent.ACTION_CANCEL
* In any case, the current gesture should be ignored by further detection logic.
*/
private var cancelled = false
private var gestureIsLongClick = false
private var lastTappedTime = 0L
private var lastTappedLocation: Vector? = null
fun onTouchEvent(event: MotionEvent) {
if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
synchronized(this@TouchGestureDetector) {
cancelled = true
}
}
val pointerIdToIndex =
(0..<event.pointerCount).associateBy { event.getPointerId(it) }
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
synchronized(this@TouchGestureDetector) {
paths = HashMap()
cancelled = false
gestureIsLongClick = false
}
longPressHandler.postDelayed({
synchronized(this@TouchGestureDetector) {
if (cancelled) {
return@postDelayed
}
if (paths.entries.size == 1 && paths.entries.firstOrNull()?.value?.isTap() == true) {
cancelled = true
gestureIsLongClick = true
Gesture.LONG_CLICK.invoke(context)
}
}
@ -158,7 +142,7 @@ class TouchGestureDetector(
// if the long press handler is still running, kill it
longPressHandler.removeCallbacksAndMessages(null)
// if the gesture was already detected as a long click, there is nothing to do
if (cancelled) {
if (gestureIsLongClick) {
return
}
}

View file

@ -4,26 +4,23 @@ import android.content.Intent
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.view.View
import android.window.OnBackInvokedDispatcher
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import de.jrpie.android.launcher.R
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.saveListActivityChoice
import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.blink
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment0Start
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment1Concept
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment2Usage
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
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentConcept
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentFinish
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentSetup
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentStart
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentUsage
/**
* The [TutorialActivity] is displayed automatically on new installations.
@ -34,16 +31,10 @@ import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment5Finish
*/
class TutorialActivity : AppCompatActivity(), UIObject {
private lateinit var binding: TutorialBinding
override fun onCreate(savedInstanceState: Bundle?) {
super<AppCompatActivity>.onCreate(savedInstanceState)
super<UIObject>.onCreate()
// Initialise layout
binding = TutorialBinding.inflate(layoutInflater)
setContentView(binding.root)
// Handle back key / gesture on Android 13+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
onBackInvokedDispatcher.registerOnBackInvokedCallback(
@ -57,51 +48,15 @@ class TutorialActivity : AppCompatActivity(), UIObject {
}
}
// Initialise layout
setContentView(R.layout.tutorial)
// set up tabs and swiping in settings
val sectionsPagerAdapter = TutorialSectionsPagerAdapter(this)
binding.tutorialViewpager.apply {
adapter = sectionsPagerAdapter
currentItem = 0
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)
}
}
val sectionsPagerAdapter = TutorialSectionsPagerAdapter(supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.tutorial_viewpager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.tutorial_tabs)
tabs.setupWithViewPager(viewPager)
}
override fun getTheme(): Resources.Theme {
@ -134,22 +89,26 @@ class TutorialActivity : AppCompatActivity(), UIObject {
*
* Tabs: (Start | Concept | Usage | Setup | Finish)
*/
class TutorialSectionsPagerAdapter(activity: FragmentActivity) :
FragmentStateAdapter(activity) {
class TutorialSectionsPagerAdapter(fm: FragmentManager) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItemCount(): Int {
return 6
}
override fun createFragment(position: Int): Fragment {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> TutorialFragment0Start()
1 -> TutorialFragment1Concept()
2 -> TutorialFragment2Usage()
3 -> TutorialFragment3AppList()
4 -> TutorialFragment4Setup()
5 -> TutorialFragment5Finish()
0 -> TutorialFragmentStart()
1 -> TutorialFragmentConcept()
2 -> TutorialFragmentUsage()
3 -> TutorialFragmentSetup()
4 -> TutorialFragmentFinish()
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

@ -1,30 +0,0 @@
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

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

View file

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

View file

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

View file

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

View file

@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.ui.UIObject
/**
* The [TutorialFragment2Usage] is a used as a tab in the TutorialActivity.
* The [TutorialFragmentUsage] 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 TutorialFragment2Usage : Fragment(), UIObject {
class TutorialFragmentUsage : Fragment(), UIObject {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.tutorial_2_usage, container, false)
return inflater.inflate(R.layout.tutorial_usage, container, false)
}
override fun onStart() {

View file

@ -1,11 +0,0 @@
<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

@ -1,11 +0,0 @@
<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.

After

Width:  |  Height:  |  Size: 159 KiB

View file

@ -1,6 +0,0 @@
<?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.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View file

@ -15,21 +15,18 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@mipmap/ic_launcher_round"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/list_apps_row_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20sp"
android:layout_marginStart="60sp"
android:gravity="start"
android:text=""
android:textSize="20sp"
tools:text="@string/app_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/list_apps_row_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -15,7 +15,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:src="@mipmap/ic_launcher_round"
tools:ignore="ContentDescription" />
<TextView
@ -26,7 +25,7 @@
android:paddingTop="5dp"
android:text=""
android:textSize="11sp"
tools:text="@string/app_name"
tools:text="some app"
app:layout_constraintTop_toBottomOf="@id/list_apps_row_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -32,6 +32,6 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/app_name" />
tools:text="some app" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -10,7 +10,7 @@
tools:context=".ui.tutorial.TutorialActivity">
<androidx.viewpager2.widget.ViewPager2
<androidx.viewpager.widget.ViewPager
android:id="@+id/tutorial_viewpager"
android:layout_width="0dp"
android:layout_height="0dp"
@ -22,37 +22,15 @@
app:layout_constraintTop_toTopOf="parent"
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
android:id="@+id/tutorial_tabs"
android:layout_width="0dp"
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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@drawable/tutorial_tab_selector"
app:tabGravity="center"
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:tabIndicatorHeight="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_viewpager" />
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,64 +0,0 @@
<?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:paddingRight="32sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.tutorial.tabs.TutorialFragment1Concept">
tools:context=".ui.tutorial.tabs.TutorialFragmentConcept">
<TextView
android:id="@+id/tutorial_concept_title"
@ -28,10 +28,11 @@
android:gravity="center"
android:text="@string/tutorial_concept_text"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_title"
app:layout_constraintBottom_toTopOf="@id/tutorial_concept_badge_version_label"/>
app:layout_constraintVertical_bias="0.19999999" />
<TextView
android:id="@+id/tutorial_concept_text_2"
@ -59,22 +60,6 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

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

View file

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

View file

@ -8,7 +8,7 @@
android:paddingRight="32sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.tutorial.tabs.TutorialFragment0Start">
tools:context=".ui.tutorial.tabs.TutorialFragmentStart">
<TextView
android:id="@+id/tutorial_start_text"
@ -21,4 +21,16 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="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>

View file

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

View file

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

View file

@ -193,7 +193,7 @@
<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_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_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="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_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_create_report">Create report</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_privacy">Privacy Policy</string>
@ -246,7 +246,7 @@
<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_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_favorites">Favorite Applications</string>
<string name="list_other_list_private_space">Private Space</string>
@ -274,29 +274,22 @@
-
-->
<string name="tutorial_title">Tutorial</string>
<string name="tutorial_start_text">👋\n\nTake a few seconds to learn how to use this Launcher!</string>
<string name="tutorial_start_text">Take a few seconds to learn how to use this Launcher!</string>
<string name="tutorial_concept_title">Concept</string>
<string name="tutorial_concept_text">μLauncher is designed to be minimal, efficient and free of distraction.
\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_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_2">The app is open-source (MIT license) and available on GitHub! Make sure to check out the repository!</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_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_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_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_2">You can also change your selection later.</string>
<string name="tutorial_finish_title">Let\'s go!</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_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_button">Start</string>
@ -308,7 +301,7 @@
<string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string>
<string name="undo">Undo</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_description">Enable the lock screen action</string>
<string name="alert_no_torch_found">No camera with torch detected.</string>
@ -318,18 +311,18 @@
<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_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_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="accessibility_service_name">μLauncher - lock screen</string>
<string name="accessibility_service_name">µLauncher - lock screen</string>
<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.
μ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>
@ -347,7 +340,7 @@
<h3>Accessibility Service</h3>
Requires excessive privileges.
μLauncher will use those privileges only for locking the screen.
µLauncher will use those privileges only for locking the screen.
<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>.)
<br/>
@ -370,11 +363,11 @@
<string name="dialog_select_color_ok">Ok</string>
<string name="dialog_select_color_color_hex">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_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_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_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_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_ok">Activate Accessibility Service</string>
<string name="dialog_cancel">Cancel</string>