diff --git a/app/build.gradle b/app/build.gradle index 1bd88f8..50a82e2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,6 +31,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt b/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt index 19198f7..5e8d7b4 100644 --- a/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt +++ b/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt @@ -17,6 +17,7 @@ class FirstStartupActivity : AppCompatActivity(){ private var menuNumber = 0 private var defaultApps = mutableListOf() + private var isFirstTime = false /** Activity Lifecycle functions */ @@ -36,7 +37,11 @@ class FirstStartupActivity : AppCompatActivity(){ loadMenu(this) val sharedPref = this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) - defaultApps = resetSettings(sharedPref, this) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN + + isFirstTime = !sharedPref.getBoolean("startedBefore", false) + + if (isFirstTime) + defaultApps = resetSettings(sharedPref, this) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN } /** Touch- and Key-related functions to navigate */ @@ -72,19 +77,23 @@ class FirstStartupActivity : AppCompatActivity(){ val entry = intro[menuNumber].split("|").toTypedArray() //heading|infoText|hintText|size heading.text = entry[0] - if (entry[4] == "1")infoText.text = String.format(entry[1], + if (entry[4] == "1" && isFirstTime)infoText.text = String.format(entry[1], defaultApps[0], defaultApps[1], defaultApps[2], defaultApps[3], defaultApps[4], defaultApps[5]) + else if (entry[4] == "1" && !isFirstTime)infoText.text = String.format(entry[1], + "-", "-", "-", "-", "-", "-") else infoText.text = entry[1] hintText.text = entry[2] infoText.setTextSize(TypedValue.COMPLEX_UNIT_SP, entry[3].toFloat()) } else { // End intro - val sharedPref = this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) + if (isFirstTime){ + val sharedPref = this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) - val editor: SharedPreferences.Editor = sharedPref.edit() - editor.putBoolean("startedBefore", true) // never run this again - editor.putLong("firstStartup", System.currentTimeMillis() / 1000L) // record first startup timestamp - editor.apply() + val editor: SharedPreferences.Editor = sharedPref.edit() + editor.putBoolean("startedBefore", true) // never auto run this again + editor.putLong("firstStartup", System.currentTimeMillis() / 1000L) // record first startup timestamp + editor.apply() + } finish() } diff --git a/app/src/main/java/com/finnmglas/launcher/MainActivity.kt b/app/src/main/java/com/finnmglas/launcher/MainActivity.kt index 15857bc..f388c06 100644 --- a/app/src/main/java/com/finnmglas/launcher/MainActivity.kt +++ b/app/src/main/java/com/finnmglas/launcher/MainActivity.kt @@ -137,7 +137,7 @@ class MainActivity : AppCompatActivity(), override fun onLongPress(event: MotionEvent) { openSettings() } // Tooltip - override fun onSingleTapUp(event: MotionEvent): Boolean { + override fun onSingleTapConfirmed(event: MotionEvent): Boolean { when(settingsIconShown) { true -> hideSettingsIcon() false -> showSettingsIcon() @@ -175,5 +175,5 @@ class MainActivity : AppCompatActivity(), override fun onDown(event: MotionEvent): Boolean { return true } override fun onScroll(e1: MotionEvent, e2: MotionEvent, dX: Float, dY: Float): Boolean { return true } override fun onShowPress(event: MotionEvent) {} - override fun onSingleTapConfirmed(event: MotionEvent): Boolean { return true } + override fun onSingleTapUp(event: MotionEvent): Boolean { return true } } diff --git a/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt b/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt index 0a2f984..df8e967 100644 --- a/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt +++ b/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt @@ -2,26 +2,34 @@ package com.finnmglas.launcher import android.app.AlertDialog import android.content.* +import android.net.Uri import android.os.Build import android.os.Bundle import android.provider.Settings import android.view.View import android.view.WindowManager import androidx.appcompat.app.AppCompatActivity +import androidx.viewpager.widget.ViewPager +import com.finnmglas.launcher.ui.main.SectionsPagerAdapter +import com.google.android.material.tabs.TabLayout -//TODO Make Settings scrollable as soon as more are added - class SettingsActivity : AppCompatActivity() { /** Activity Lifecycle functions */ + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setContentView(R.layout.activity_settings) window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - setContentView(R.layout.activity_settings) + val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager) + val viewPager: ViewPager = findViewById(R.id.view_pager) + viewPager.adapter = sectionsPagerAdapter + val tabs: TabLayout = findViewById(R.id.tabs) + tabs.setupWithViewPager(viewPager) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -74,6 +82,35 @@ class SettingsActivity : AppCompatActivity() { fun openFinnWebsite(view: View) { openNewTabWindow(getString(R.string.settings_footer_web), this) } fun openGithubRepo(view: View) { openNewTabWindow(getString(R.string.settings_footer_repo), this) } + + // Rate App + // Just copied code from https://stackoverflow.com/q/10816757/12787264 + // that is how we write good software ^ + fun rateApp(view: View) { + try { + val rateIntent = rateIntentForUrl("market://details") + startActivity(rateIntent) + } catch (e: ActivityNotFoundException) { + val rateIntent = rateIntentForUrl("https://play.google.com/store/apps/details") + startActivity(rateIntent) + } + } + + private fun rateIntentForUrl(url: String): Intent { + val intent = Intent( + Intent.ACTION_VIEW, + Uri.parse(String.format("%s?id=%s", url, packageName)) + ) + var flags = Intent.FLAG_ACTIVITY_NO_HISTORY or Intent.FLAG_ACTIVITY_MULTIPLE_TASK + flags = if (Build.VERSION.SDK_INT >= 21) { + flags or Intent.FLAG_ACTIVITY_NEW_DOCUMENT + } else { + flags or Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET + } + intent.addFlags(flags) + return intent + } + fun backHome(view: View) { finish() } fun setLauncher(view: View) { @@ -102,6 +139,10 @@ class SettingsActivity : AppCompatActivity() { } } + fun viewTutorial (view: View){ + startActivity(Intent(this, FirstStartupActivity::class.java)) + } + // Show a dialog prompting for confirmation fun resetSettingsClick(view: View) { AlertDialog.Builder(this) diff --git a/app/src/main/java/com/finnmglas/launcher/SettingsFragmentApps.kt b/app/src/main/java/com/finnmglas/launcher/SettingsFragmentApps.kt new file mode 100644 index 0000000..ad193fd --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/SettingsFragmentApps.kt @@ -0,0 +1,20 @@ +package com.finnmglas.launcher + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup + +/** The 'Apps' Tab associated Fragment in Settings */ + +class SettingsFragmentApps : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + + return inflater.inflate(R.layout.fragment_settings_apps, container, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/finnmglas/launcher/SettingsFragmentLauncher.kt b/app/src/main/java/com/finnmglas/launcher/SettingsFragmentLauncher.kt new file mode 100644 index 0000000..89cb44f --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/SettingsFragmentLauncher.kt @@ -0,0 +1,20 @@ +package com.finnmglas.launcher + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup + +/** The 'Launcher' Tab associated Fragment in Settings */ + +class SettingsFragmentLauncher : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + + return inflater.inflate(R.layout.fragment_settings_launcher, container, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/finnmglas/launcher/SettingsFragmentTheme.kt b/app/src/main/java/com/finnmglas/launcher/SettingsFragmentTheme.kt new file mode 100644 index 0000000..71d8d2f --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/SettingsFragmentTheme.kt @@ -0,0 +1,20 @@ +package com.finnmglas.launcher + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup + +/** The 'Theme' Tab associated Fragment in Settings */ + +class SettingsFragmentTheme : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + + return inflater.inflate(R.layout.fragment_settings_theme, container, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/finnmglas/launcher/ui/main/PageViewModel.kt b/app/src/main/java/com/finnmglas/launcher/ui/main/PageViewModel.kt new file mode 100644 index 0000000..584ab43 --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/ui/main/PageViewModel.kt @@ -0,0 +1,19 @@ +package com.finnmglas.launcher.ui.main + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Transformations +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider + +class PageViewModel : ViewModel() { + + private val _index = MutableLiveData() + val text: LiveData = Transformations.map(_index) { + "Tab $it" + } + + fun setIndex(index: Int) { + _index.value = index + } +} \ No newline at end of file diff --git a/app/src/main/java/com/finnmglas/launcher/ui/main/SectionsPagerAdapter.kt b/app/src/main/java/com/finnmglas/launcher/ui/main/SectionsPagerAdapter.kt new file mode 100644 index 0000000..f412ddd --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/ui/main/SectionsPagerAdapter.kt @@ -0,0 +1,35 @@ +package com.finnmglas.launcher.ui.main + +import android.content.Context +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentPagerAdapter +import com.finnmglas.launcher.* + +private val TAB_TITLES = arrayOf( + R.string.settings_tab_app, + R.string.settings_tab_theme, + R.string.settings_tab_launcher +) + +/** Returns the fragment corresponding to the selected tab.*/ +class SectionsPagerAdapter(private val context: Context, fm: FragmentManager) + : FragmentPagerAdapter(fm) { + + override fun getItem(position: Int): Fragment { + return when (position){ + 0 -> SettingsFragmentApps() + 1 -> SettingsFragmentTheme() + 2 -> SettingsFragmentLauncher() + else -> Fragment() + } + } + + override fun getPageTitle(position: Int): CharSequence? { + return context.resources.getString(TAB_TITLES[position]) + } + + override fun getCount(): Int { + return 3 + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index e2a5ee8..fc6ff88 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -1,320 +1,57 @@ - + - + android:background="@color/colorPrimaryDark" + android:theme="@style/AppTheme.AppBarOverlay"> - - - - - - - - -