From 3298e8c04cb598934f8d71f90d44bfcdc947ff5f Mon Sep 17 00:00:00 2001 From: angrezichatterbox Date: Thu, 29 Aug 2024 08:32:53 +0530 Subject: [PATCH 1/5] feat:Used Fragments for Navigation and Bottom Nav bar --- app/build.gradle | 10 + app/src/main/AndroidManifest.xml | 45 +-- app/src/main/java/be/scri/App.kt | 6 + .../java/be/scri/activities/AboutActivity.kt | 198 ------------ .../be/scri/activities/BaseSimpleActivity.kt | 3 +- .../be/scri/activities/LanguageSettings.kt | 81 ----- .../java/be/scri/activities/MainActivity.kt | 205 ++++-------- .../be/scri/activities/SettingsActivity.kt | 305 ------------------ .../java/be/scri/activities/SplashActivity.kt | 3 +- .../activities/WikimediaScribeActivity.kt | 50 --- .../java/be/scri/fragments/AboutFragment.kt | 115 +++++++ .../fragments/LanguageSettingsFragment.kt | 103 ++++++ .../java/be/scri/fragments/MainFragment.kt | 95 ++++++ .../be/scri/fragments/SettingsFragment.kt | 224 +++++++++++++ .../scri/fragments/WikimediaScribeFragment.kt | 66 ++++ .../java/be/scri/helpers/CustomAdapter.kt | 4 +- .../java/be/scri/helpers/ViewPagerAdapter.kt | 24 ++ app/src/main/java/be/scri/models/TextItem.kt | 4 +- .../main/java/be/scri/views/MyKeyboardView.kt | 4 +- .../drawable/button_background_rounded.xml | 2 +- app/src/main/res/layout/activity_main.xml | 31 +- .../res/layout/activity_wikimedia_scribe.xml | 30 +- ...{activity_about.xml => fragment_about.xml} | 27 +- ...ngs.xml => fragment_language_settings.xml} | 24 +- app/src/main/res/layout/fragment_main.xml | 24 ++ ...ity_settings.xml => fragment_settings.xml} | 31 +- app/src/main/res/values-land/dimens.xml | 3 + app/src/main/res/values-w1240dp/dimens.xml | 3 + app/src/main/res/values-w600dp/dimens.xml | 3 + app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/strings.xml | 42 ++- app/src/main/res/values/styles.xml | 2 +- 32 files changed, 836 insertions(+), 932 deletions(-) delete mode 100644 app/src/main/java/be/scri/activities/AboutActivity.kt delete mode 100644 app/src/main/java/be/scri/activities/LanguageSettings.kt delete mode 100644 app/src/main/java/be/scri/activities/SettingsActivity.kt delete mode 100644 app/src/main/java/be/scri/activities/WikimediaScribeActivity.kt create mode 100644 app/src/main/java/be/scri/fragments/AboutFragment.kt create mode 100644 app/src/main/java/be/scri/fragments/LanguageSettingsFragment.kt create mode 100644 app/src/main/java/be/scri/fragments/MainFragment.kt create mode 100644 app/src/main/java/be/scri/fragments/SettingsFragment.kt create mode 100644 app/src/main/java/be/scri/fragments/WikimediaScribeFragment.kt create mode 100644 app/src/main/java/be/scri/helpers/ViewPagerAdapter.kt rename app/src/main/res/layout/{activity_about.xml => fragment_about.xml} (71%) rename app/src/main/res/layout/{activity_language_settings.xml => fragment_language_settings.xml} (60%) create mode 100644 app/src/main/res/layout/fragment_main.xml rename app/src/main/res/layout/{activity_settings.xml => fragment_settings.xml} (69%) create mode 100644 app/src/main/res/values-land/dimens.xml create mode 100644 app/src/main/res/values-w1240dp/dimens.xml create mode 100644 app/src/main/res/values-w600dp/dimens.xml diff --git a/app/build.gradle b/app/build.gradle index fc8f17ce..e8550e27 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,11 +67,20 @@ android { } namespace 'be.scri' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } } dependencies { implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.activity:activity-ktx:1.9.1' + implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7' + implementation 'androidx.navigation:navigation-ui-ktx:2.7.7' kapt 'androidx.room:room-compiler:2.6.1' implementation 'androidx.room:room-runtime:2.6.1' annotationProcessor 'androidx.room:room-compiler:2.6.1' @@ -86,6 +95,7 @@ dependencies { implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.recyclerview:recyclerview:1.3.2' implementation 'androidx.cardview:cardview:1.0.0' + implementation "androidx.viewpager2:viewpager2:1.0.0" api 'joda-time:joda-time:2.10.13' api 'com.github.tibbi:RecyclerView-FastScroller:e7d3e150c4' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8fe4e0f4..5c3feb48 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,8 @@ + android:installLocation="auto" > + @@ -19,6 +20,14 @@ android:roundIcon="@mipmap/ic_launcher" android:supportsRtl="true" android:theme="@style/AppTheme"> + + + + + + + + android:targetActivity=".activities.SplashActivity" > @@ -39,14 +48,14 @@ + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -59,7 +68,7 @@ android:name=".services.GermanKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -72,7 +81,7 @@ android:name=".services.FrenchKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -85,7 +94,7 @@ android:name=".services.ItalianKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -98,7 +107,7 @@ android:name=".services.PortugueseKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -111,7 +120,7 @@ android:name=".services.RussianKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -124,7 +133,7 @@ android:name=".services.SpanishKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -137,7 +146,7 @@ android:name=".services.SwedishKeyboardIME" android:exported="true" android:label="Scribe" - android:permission="android.permission.BIND_INPUT_METHOD"> + android:permission="android.permission.BIND_INPUT_METHOD" > @@ -148,10 +157,10 @@ + android:parentActivityName=".fragments.MainFragment" > @@ -162,13 +171,13 @@ + android:parentActivityName=".fragments.MainFragment" /> + android:parentActivityName=".fragments.MainFragment" /> + android:parentActivityName=".fragments.MainFragment" /> diff --git a/app/src/main/java/be/scri/App.kt b/app/src/main/java/be/scri/App.kt index f99ba741..21423e2f 100644 --- a/app/src/main/java/be/scri/App.kt +++ b/app/src/main/java/be/scri/App.kt @@ -1,10 +1,16 @@ package be.scri import android.app.Application +import androidx.appcompat.app.AppCompatDelegate import be.scri.extensions.checkUseEnglish +import be.scri.extensions.config class App : Application() { override fun onCreate() { + AppCompatDelegate.setDefaultNightMode( + if (config.darkTheme) AppCompatDelegate.MODE_NIGHT_YES + else AppCompatDelegate.MODE_NIGHT_NO + ) super.onCreate() checkUseEnglish() } diff --git a/app/src/main/java/be/scri/activities/AboutActivity.kt b/app/src/main/java/be/scri/activities/AboutActivity.kt deleted file mode 100644 index 8247f312..00000000 --- a/app/src/main/java/be/scri/activities/AboutActivity.kt +++ /dev/null @@ -1,198 +0,0 @@ -package be.scri.activities - - -import android.content.Intent -import android.os.Bundle -import android.view.GestureDetector -import android.view.Menu -import android.view.MotionEvent -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.bottomnavigation.BottomNavigationView -import be.scri.R -import be.scri.databinding.ActivityAboutBinding -import be.scri.extensions.* -import be.scri.helpers.* -import be.scri.models.ItemsViewModel -import kotlin.math.abs - -class AboutActivity : BaseSimpleActivity(), GestureDetector.OnGestureListener{ - private var appName = "" - private var primaryColor = 0 - - private val recyclerView1 by lazy { findViewById(R.id.recycleView2) } - private val recyclerView2 by lazy { findViewById(R.id.recycleView) } - private val EASTER_EGG_TIME_LIMIT = 3000L - private val EASTER_EGG_REQUIRED_CLICKS = 7 - private val SWIPE_THRESHOLD = 100 - private val SWIPE_VELOCITY_THRESHOLD = 100 - - private lateinit var binding: ActivityAboutBinding - - private lateinit var gestureDetector: GestureDetector - private val swipeThreshold = 100 - private val swipeVelocityThreshold = 100 - - override fun getAppIconIDs() = intent.getIntegerArrayListExtra(APP_ICON_IDS) ?: ArrayList() - - override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: "" - - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityAboutBinding.inflate(layoutInflater) - val view = binding.root - setContentView(view) - gestureDetector = GestureDetector(this) - setupRecyclerViews() - appName = intent.getStringExtra(APP_NAME) ?: "" - val textColor = getProperTextColor() - val backgroundColor = getProperBackgroundColor() - primaryColor = getProperPrimaryColor() - supportActionBar?.setDisplayHomeAsUpEnabled(false) - val bottomNavigationView = findViewById(R.id.bottom_navigation) - - bottomNavigationView.selectedItemId = R.id.info - - bottomNavigationView.setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.settings -> { - startActivity(Intent(applicationContext, SettingsActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } - - R.id.info -> { - return@OnNavigationItemSelectedListener true } - R.id.installation -> { - startActivity(Intent(applicationContext, MainActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } - } - false - }) - bottomNavigationView.selectedItemId = R.id.info - } - - - private fun setupRecyclerViews() { - val recyclerView1 = findViewById(R.id.recycleView2) - recyclerView1.layoutManager = LinearLayoutManager(this) - recyclerView1.adapter = CustomAdapter(getFirstRecyclerViewData(), this) - recyclerView1.suppressLayout(true) - - val recyclerView2 = findViewById(R.id.recycleView) - recyclerView2.layoutManager = LinearLayoutManager(this) - recyclerView2.adapter = CustomAdapter(getSecondRecyclerViewData(), this) - recyclerView2.suppressLayout(true) - - val recyclerView3 = findViewById(R.id.recycleView3) - recyclerView3.layoutManager = LinearLayoutManager(this) - recyclerView3.adapter = CustomAdapter(getThirdRecyclerViewData(), this) - recyclerView3.suppressLayout(true) - } - - private fun getFirstRecyclerViewData(): List = listOf( - ItemsViewModel(image = R.drawable.github_logo, textResId = R.string.app_about_github, image2 = R.drawable.external_link, url = "https://github.com/scribe-org/Scribe-Android", activity = null, action = null), - ItemsViewModel(image = R.drawable.matrix_icon, textResId = R.string.app_about_matrix, image2 = R.drawable.external_link, url = "https://matrix.to/%23/%23scribe_community:matrix.org", activity = null, action = null), - ItemsViewModel(image = R.drawable.mastodon_svg_icon, textResId = R.string.app_about_mastodon, image2 = R.drawable.external_link, url = "https://wikis.world/@scribe", activity = null, action = null), - ItemsViewModel(image = R.drawable.share_icon, textResId = R.string.app_about_share, image2 = R.drawable.external_link, url = null, activity = null, action = ::shareScribe), - ItemsViewModel(image = R.drawable.scribe_icon, textResId = R.string.app_about_scribe, image2 = R.drawable.external_link, url = null, activity = null, action = null), - ItemsViewModel(image = R.drawable.wikimedia_logo_black, textResId = R.string.app_about_wikimedia, image2 = R.drawable.right_arrow, url = null, activity = WikimediaScribeActivity::class.java, action = null) - ) - - private fun getSecondRecyclerViewData(): List = listOf( - ItemsViewModel(image = R.drawable.star, textResId = R.string.app_about_rate, image2 = R.drawable.external_link, url = null, activity = null, action = null), - ItemsViewModel(image = R.drawable.bug_report_icon, textResId = R.string.app_about_bugReport, image2 = R.drawable.external_link, url = "https://github.com/scribe-org/Scribe-Android/issues", activity = null, action = null), - ItemsViewModel(image = R.drawable.mail_icon, textResId = R.string.app_about_email, image2 = R.drawable.external_link, url = null, activity = null, action = ::sendEmail), - ItemsViewModel(image = R.drawable.bookmark_icon, textResId = R.string.app_version, image2 = R.drawable.right_arrow, url = null, activity = null, action = null), - ItemsViewModel(image = R.drawable.light_bulb_icon, textResId = R.string.app_about_appHints, image2 = R.drawable.counter_clockwise_icon, url = null, activity = null, action = null) - ) - - private fun getThirdRecyclerViewData(): List = listOf( - ItemsViewModel(image = R.drawable.shield_lock, textResId = R.string.app_about_privacyPolicy, image2 = R.drawable.right_arrow, url = null, activity = PrivacyPolicyActivity::class.java, action = null), - ItemsViewModel(image = R.drawable.license_icon, textResId = R.string.app_about_thirdParty, image2 = R.drawable.right_arrow, url = null, activity = ThirdPartyActivity::class.java, action = null) - ) - - - override fun onTouchEvent(event: MotionEvent): Boolean { - return if (gestureDetector.onTouchEvent(event)) { - true - } - else { - super.onTouchEvent(event) - } - } - - fun shareScribe() { - val sharingIntent = Intent(Intent.ACTION_SEND).apply { - type = "text/plain" - putExtra(Intent.EXTRA_TEXT, "https://github.com/scribe-org/Scribe-Android") - } - startActivity(Intent.createChooser(sharingIntent, "Share via")) - } - - fun sendEmail() { - val intent = Intent(Intent.ACTION_SEND).apply { - putExtra(Intent.EXTRA_EMAIL, arrayOf("team@scri.be")) - putExtra(Intent.EXTRA_SUBJECT, "Hey Scribe!") - type = "message/rfc822" - } - startActivity(Intent.createChooser(intent, "Choose an Email client:")) - } - - override fun onResume() { - super.onResume() - updateTextColors(binding.aboutScrollview) - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - updateMenuItemColors(menu) - return super.onCreateOptionsMenu(menu) - } - - - override fun onDown(e: MotionEvent): Boolean { - return false - } - - override fun onShowPress(e: MotionEvent) { - return - } - - override fun onSingleTapUp(e: MotionEvent): Boolean { - return false - } - - override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { - return false - } - - override fun onLongPress(e: MotionEvent) { - return - } - - override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { - try { - val diffY = e2.y - e1!!.y - val diffX = e2.x - e1.x - if (abs(diffX) > abs(diffY)) { - if (abs(diffX) > swipeThreshold && abs(velocityX) > swipeVelocityThreshold) { - if (diffX > 0) { - startActivity(Intent(applicationContext, SettingsActivity::class.java)) - } - else { - return false - } - } - } - } - catch (exception: Exception) { - exception.printStackTrace() - } - return true - } -} - - diff --git a/app/src/main/java/be/scri/activities/BaseSimpleActivity.kt b/app/src/main/java/be/scri/activities/BaseSimpleActivity.kt index c01c8c7d..4c109367 100644 --- a/app/src/main/java/be/scri/activities/BaseSimpleActivity.kt +++ b/app/src/main/java/be/scri/activities/BaseSimpleActivity.kt @@ -31,6 +31,7 @@ import be.scri.dialogs.ConfirmationDialog import be.scri.dialogs.WritePermissionDialog import be.scri.dialogs.WritePermissionDialog.Mode import be.scri.extensions.* +import be.scri.fragments.AboutFragment import be.scri.helpers.* import java.util.regex.Pattern @@ -409,7 +410,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() { fun startAboutActivity(appNameId: Int, licenseMask: Int, versionName: String, showFAQBeforeMail: Boolean) { hideKeyboard() - Intent(applicationContext, AboutActivity::class.java).apply { + Intent(applicationContext, AboutFragment::class.java).apply { putExtra(APP_ICON_IDS, getAppIconIDs()) putExtra(APP_LAUNCHER_NAME, getAppLauncherName()) putExtra(APP_NAME, getString(appNameId)) diff --git a/app/src/main/java/be/scri/activities/LanguageSettings.kt b/app/src/main/java/be/scri/activities/LanguageSettings.kt deleted file mode 100644 index 34d9e938..00000000 --- a/app/src/main/java/be/scri/activities/LanguageSettings.kt +++ /dev/null @@ -1,81 +0,0 @@ -package be.scri.activities - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import androidx.activity.enableEdgeToEdge -import androidx.recyclerview.widget.LinearLayoutManager -import be.scri.R -import be.scri.databinding.ActivityLanguageSettingsBinding -import be.scri.extensions.config -import be.scri.helpers.CustomAdapter -import be.scri.models.SwitchItem -import com.google.android.material.bottomnavigation.BottomNavigationView - -class LanguageSettings : SimpleActivity() { - private lateinit var binding: ActivityLanguageSettingsBinding - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - binding = ActivityLanguageSettingsBinding.inflate(layoutInflater) - val view = binding.root - val language = intent.getStringExtra("LANGUAGE_EXTRA") - setContentView(view) - if (language != null) { - setupRecyclerView(language=language) - } - val bottomNavigationView = findViewById(R.id.bottom_navigation) - bottomNavigationView.setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.info -> { - startActivity(Intent(applicationContext, AboutActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } - - R.id.settings -> { - return@OnNavigationItemSelectedListener true } - R.id.installation -> { - startActivity(Intent(applicationContext, MainActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } - } - false - }) - bottomNavigationView.selectedItemId = R.id.settings - - } - private fun setupRecyclerView(language: String) { - val recyclerView1 = binding.recyclerView - recyclerView1.layoutManager = LinearLayoutManager(this) - recyclerView1.adapter = CustomAdapter(getRecyclerViewData(language), this) - recyclerView1.suppressLayout(true) - } - - private fun getRecyclerViewData(language: String): List { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - return listOf( - SwitchItem( - isChecked = sharedPref.getBoolean("period_on_double_tap_$language", false), - title = "Double space Periods", - action = { enablePeriodOnSpaceBarDoubleTap(language = language) }, - action2 = { disablePeriodOnSpaceBarDoubleTap(language = language) })) - } - private fun enablePeriodOnSpaceBarDoubleTap(language: String) { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("period_on_double_tap_$language", true) - editor.apply() - } - - private fun disablePeriodOnSpaceBarDoubleTap(language: String) { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("period_on_double_tap_$language", false) - editor.apply() - } - -} - - diff --git a/app/src/main/java/be/scri/activities/MainActivity.kt b/app/src/main/java/be/scri/activities/MainActivity.kt index 9e9301fa..a2e7bb97 100644 --- a/app/src/main/java/be/scri/activities/MainActivity.kt +++ b/app/src/main/java/be/scri/activities/MainActivity.kt @@ -1,177 +1,84 @@ package be.scri.activities -import android.content.Context -import android.content.Intent -import android.content.res.Configuration -import android.graphics.drawable.LayerDrawable -import android.graphics.drawable.RippleDrawable import android.os.Bundle -import android.provider.Settings -import android.view.GestureDetector -import android.view.MotionEvent -import android.view.inputmethod.InputMethodManager -import androidx.appcompat.app.AppCompatDelegate +import android.view.View +import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.bottomnavigation.BottomNavigationView -import be.scri.BuildConfig import be.scri.R +import be.scri.adapters.ViewPagerAdapter import be.scri.databinding.ActivityMainBinding -import be.scri.dialogs.ConfirmationAdvancedDialog -import be.scri.extensions.* -import be.scri.helpers.LICENSE_GSON -import kotlin.math.abs -class MainActivity : SimpleActivity(), GestureDetector.OnGestureListener { +class MainActivity : SimpleActivity() { - private lateinit var gestureDetector: GestureDetector - private val swipeThreshold = 100 - private val swipeVelocityThreshold = 100 + private lateinit var bottomNavigationView: BottomNavigationView + private lateinit var viewPager: ViewPager2 + private lateinit var adapter: ViewPagerAdapter private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { - binding = ActivityMainBinding.inflate(layoutInflater) - applyUserDarkModePreference() - val view = binding.root - setContentView(view) super.onCreate(savedInstanceState) - appLaunched(BuildConfig.APPLICATION_ID) - gestureDetector = GestureDetector(this) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) - val bottomNavigationView = findViewById(R.id.bottom_navigation) + viewPager = findViewById(R.id.view_pager) + bottomNavigationView = findViewById(R.id.bottom_navigation) - bottomNavigationView.selectedItemId = R.id.installation + adapter = ViewPagerAdapter(this) + viewPager.adapter = adapter - bottomNavigationView.setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.settings -> { - startActivity(Intent(applicationContext, SettingsActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } + if (savedInstanceState == null) { + viewPager.setCurrentItem(0, false) + } - R.id.installation -> { - return@OnNavigationItemSelectedListener true - } - R.id.info -> { - startActivity(Intent(applicationContext, AboutActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true + viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + bottomNavigationView.menu.getItem(position).isChecked = true + when(position) { + 0 -> { + supportActionBar?.title = getString(R.string.app_title_new) + binding.fragmentContainer.visibility = View.GONE + } + 1 -> { + supportActionBar?.title = getString(R.string.app_settings_title) + binding.fragmentContainer.visibility = View.GONE + } + 2 -> { + supportActionBar?.title = getString(R.string.app_about_title) + binding.fragmentContainer.visibility = View.GONE + } } } - false }) - binding.scribeKey.setOnClickListener { - (getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).showInputMethodPicker() - } - } - - private fun applyUserDarkModePreference() { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK - val isSystemDarkMode = currentNightMode == Configuration.UI_MODE_NIGHT_YES - val isUserDarkMode = sharedPref.getBoolean("dark_mode", isSystemDarkMode) - AppCompatDelegate.setDefaultNightMode( - if (isUserDarkMode) AppCompatDelegate.MODE_NIGHT_YES - else AppCompatDelegate.MODE_NIGHT_NO - ) - if (isUserDarkMode != (currentNightMode == Configuration.UI_MODE_NIGHT_YES)) { - recreate() - } - } - - override fun onTouchEvent(event: MotionEvent): Boolean { - return if (gestureDetector.onTouchEvent(event)) { - true - } else { - super.onTouchEvent(event) - } - } - - override fun onResume() { - super.onResume() - if (!isKeyboardEnabled()) { - ConfirmationAdvancedDialog(this, messageId = R.string.redirection_note, positive = R.string.ok, negative = 0) { success -> - if (success) { - Intent(Settings.ACTION_INPUT_METHOD_SETTINGS).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(this) - } - } else { - finish() + bottomNavigationView.setOnNavigationItemSelectedListener { menuItem -> + when (menuItem.itemId) { + R.id.installation -> { + viewPager.setCurrentItem(0, true) + supportActionBar?.title = getString(R.string.app_title_new) + binding.fragmentContainer.visibility = View.GONE + true + } + R.id.info -> { + viewPager.setCurrentItem(2, true) + binding.fragmentContainer.visibility = View.GONE + supportActionBar?.title = getString(R.string.app_about_title) + true + } + R.id.settings -> { + viewPager.setCurrentItem(1, true) + binding.fragmentContainer.visibility = View.GONE + supportActionBar?.title = getString(R.string.app_settings_title) + true + } + else -> { + false } } } - - updateTextColors(binding.mainHolder) - updateChangeKeyboardColor() - binding.mainHolder.setBackgroundColor(getProperBackgroundColor()) - } - - - - private fun launchSettings() { - hideKeyboard() - startActivity(Intent(applicationContext, SettingsActivity::class.java)) - } - - private fun launchAbout() { - val licenses = LICENSE_GSON - startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, true) } - - private fun updateChangeKeyboardColor() { - val applyBackground = resources.getDrawable(R.drawable.button_background_rounded, theme) as RippleDrawable - (applyBackground as LayerDrawable).findDrawableByLayerId(R.id.button_background_holder).applyColorFilter(getProperPrimaryColor()) - binding.changeKeyboard.background = applyBackground - binding.changeKeyboard.setTextColor(getProperPrimaryColor().getContrastColor()) - } - - private fun isKeyboardEnabled(): Boolean { - val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - val enabledKeyboards = inputMethodManager.enabledInputMethodList - return enabledKeyboards.any { - it.settingsActivity == SettingsActivity::class.java.canonicalName - } - } - - - override fun onDown(e: MotionEvent): Boolean { - return false + fun showFragmentContainer() { + binding.fragmentContainer.visibility = View.VISIBLE } - override fun onShowPress(e: MotionEvent) { - return - } - - override fun onSingleTapUp(e: MotionEvent): Boolean { - return false - } - - override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { - return false - } - - override fun onLongPress(e: MotionEvent) { - return - } - - override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { - try { - val diffY = e2?.y?.minus(e1?.y ?: 0f) ?: 0f - val diffX = e2?.x?.minus(e1?.x ?: 0f) ?: 0f - if (abs(diffX) > abs(diffY)) { - if (abs(diffX) > swipeThreshold && abs(velocityX) > swipeVelocityThreshold) { - if (diffX > 0) { - return false - } else { - startActivity(Intent(applicationContext, SettingsActivity::class.java)) - } - } - } - } catch (exception: Exception) { - exception.printStackTrace() - } - return true - } } diff --git a/app/src/main/java/be/scri/activities/SettingsActivity.kt b/app/src/main/java/be/scri/activities/SettingsActivity.kt deleted file mode 100644 index e3447b0a..00000000 --- a/app/src/main/java/be/scri/activities/SettingsActivity.kt +++ /dev/null @@ -1,305 +0,0 @@ -package be.scri.activities - -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.os.Build -import android.os.Bundle -import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS -import android.provider.Settings.ACTION_APP_LOCALE_SETTINGS -import android.provider.Settings.ACTION_INPUT_METHOD_SETTINGS -import android.view.GestureDetector -import android.view.Menu -import android.view.MotionEvent -import android.view.View -import android.view.inputmethod.InputMethodManager -import androidx.appcompat.app.AppCompatDelegate -import androidx.recyclerview.widget.LinearLayoutManager -import be.scri.R -import be.scri.databinding.ActivitySettingsBinding -import be.scri.extensions.config -import be.scri.extensions.updateTextColors -import be.scri.helpers.CustomAdapter -import be.scri.models.SwitchItem -import be.scri.models.TextItem -import com.google.android.material.bottomnavigation.BottomNavigationView -import kotlin.math.abs - - -class SettingsActivity : SimpleActivity(), GestureDetector.OnGestureListener { - - private lateinit var gestureDetector: GestureDetector - private val swipeThreshold = 100 - private val swipeVelocityThreshold = 100 - private lateinit var binding: ActivitySettingsBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivitySettingsBinding.inflate(layoutInflater) - setContentView(binding.root) - setupRecycleView() - setupRecyclerView2() - supportActionBar?.setDisplayHomeAsUpEnabled(false) - gestureDetector = GestureDetector(this) - - val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - val enabledInputMethods = imm.enabledInputMethodList - for(inputMethod in enabledInputMethods) { - if (inputMethod.packageName == "be.scri.debug") { - setupItemVisibility() - } - } - binding.btnInstall.setOnClickListener { - Intent(ACTION_INPUT_METHOD_SETTINGS).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(this) - } - } - - - val bottomNavigationView = findViewById(R.id.bottom_navigation) - if (bottomNavigationView != null) { - bottomNavigationView.selectedItemId = R.id.settings - - bottomNavigationView.setOnNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.installation -> { - startActivity(Intent(applicationContext, MainActivity::class.java)) - overridePendingTransition(0, 0) - true - } - R.id.settings -> true - R.id.info -> { - startActivity(Intent(applicationContext, AboutActivity::class.java)) - overridePendingTransition(0, 0) - true - } - else -> false - } - } - } - } - - private fun setupRecycleView(){ - val recyclerView = binding.recyclerViewSettings - recyclerView.adapter = CustomAdapter(getFirstRecyclerViewData(),this) - - recyclerView.layoutManager = LinearLayoutManager(this) - recyclerView.suppressLayout(true) - } - - private fun getFirstRecyclerViewData():List { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - return listOf( - TextItem(R.string.app_settings_appSettings_appLanguage, image = R.drawable.right_arrow, action = ::selectLanguage), - SwitchItem("Dark mode", isChecked = sharedPref.getBoolean("dark_mode", false), action = ::darkMode, action2 = ::lightMode), - SwitchItem("Vibrate on Keypress", isChecked = config.vibrateOnKeypress, action = ::enableVibrateOnKeypress, action2 = ::disableVibrateOnKeypress), - SwitchItem( - "Show a popup on keypress", - isChecked = config.showPopupOnKeypress, - action = ::enableShowPopupOnKeypress, - action2 = ::disableShowPopupOnKeypress - ), - ) - } - - - private fun selectLanguage() { - val intent: Intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - Intent(ACTION_APP_LOCALE_SETTINGS) - } else { - Intent(ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.fromParts("package", packageName, null) - putExtra("android.intent.extra.SHOW_FRAGMENT", "com.android.settings.localepicker.LocaleListEditor") - } - } - val uri = Uri.fromParts("package", packageName, null) - intent.setData(uri) - startActivity(intent) - - } - - private fun setupRecyclerView2() { - val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - val enabledInputMethods = imm.enabledInputMethodList - for(inputMethod in enabledInputMethods) { - if (inputMethod.packageName == "be.scri.debug") { - setupItemVisibility() - } - } - val recyclerView = binding.recyclerView2 - val adapter = CustomAdapter(getRecyclerViewElements(),this) - recyclerView.layoutManager = LinearLayoutManager(this) - recyclerView.adapter = adapter - recyclerView.suppressLayout(true) - } - - private fun getRecyclerViewElements(): MutableList { - val languages = setupKeyboardLanguage() - val list = mutableListOf() - for (language in languages) { - var localizeLanguage:Int = 0 - when(language) { - "English" -> localizeLanguage = R.string._global_english - "French" -> localizeLanguage = R.string._global_french - "German" -> localizeLanguage = R.string._global_german - "Russian" -> localizeLanguage = R.string._global_russian - "Spanish" -> localizeLanguage = R.string._global_spanish - "Italian" -> localizeLanguage = R.string._global_italian - "Portuguese" -> localizeLanguage = R.string._global_portuguese - } - list.add( - TextItem( - text = localizeLanguage, - image = R.drawable.right_arrow, - action = { loadLanguageSettings(language) }, - language = language - ) - ) - } - return list - } - private fun loadLanguageSettings(language: String) { - val intent = Intent(this, LanguageSettings::class.java) - intent.putExtra("LANGUAGE_EXTRA", language) - startActivity(intent) - } - - - private fun setupKeyboardLanguage(): MutableList { - val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - val enabledInputMethods = imm.enabledInputMethodList - val result = mutableListOf() - - for (inputMethod in enabledInputMethods) { - when (inputMethod.serviceName) { - "be.scri.services.EnglishKeyboardIME" -> result.add("English") - "be.scri.services.GermanKeyboardIME" -> result.add("German") - "be.scri.services.RussianKeyboardIME" -> result.add("Russian") - "be.scri.services.SpanishKeyboardIME" -> result.add("Spanish") - "be.scri.services.FrenchKeyboardIME" -> result.add("French") - "be.scri.services.ItalianKeyboardIME" -> result.add("Italian") - "be.scri.services.PortugueseKeyboardIME" -> result.add("Portuguese") - } - } - return result - } - - - private fun lightMode() { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("dark_mode", false) - editor.apply() - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) - recreate() - - } - private fun darkMode(){ - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("dark_mode", true) - editor.apply() - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) - recreate() - } - - private fun enableVibrateOnKeypress() { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("vibrate_on_keypress", true) - editor.apply() - config.vibrateOnKeypress = true - } - - private fun disableVibrateOnKeypress() { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("vibrate_on_keypress", false) - editor.apply() - config.vibrateOnKeypress = false - } - - private fun enableShowPopupOnKeypress() { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("show_popup_on_keypress", true) - editor.apply() - config.showPopupOnKeypress = true - } - - private fun disableShowPopupOnKeypress() { - val sharedPref = getSharedPreferences("app_preferences", Context.MODE_PRIVATE) - val editor = sharedPref.edit() - editor.putBoolean("show_popup_on_keypress", false) - editor.apply() - config.showPopupOnKeypress = false - } - - - private fun setupItemVisibility() { - binding.btnInstall.visibility = View.INVISIBLE - binding.selectLanguage.visibility = View.VISIBLE - } - override fun onResume() { - super.onResume() - setupRecyclerView2() - updateTextColors(binding.settingsScrollview) - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - updateMenuItemColors(menu) - return super.onCreateOptionsMenu(menu) - } - - - override fun onTouchEvent(event: MotionEvent): Boolean { - return if (gestureDetector.onTouchEvent(event)) { - true - } - else { - super.onTouchEvent(event) - } - } - - override fun onDown(e: MotionEvent): Boolean { - return false - } - - override fun onShowPress(e: MotionEvent) { - return - } - - override fun onSingleTapUp(e: MotionEvent): Boolean { - return false - } - - override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { - return false - } - - override fun onLongPress(e: MotionEvent) { - return - } - - override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { - try { - val diffY = e2.y - e1!!.y - val diffX = e2.x - e1.x - if (abs(diffX) > abs(diffY)) { - if (abs(diffX) > swipeThreshold && abs(velocityX) > swipeVelocityThreshold) { - if (diffX > 0) { - startActivity(Intent(applicationContext, MainActivity::class.java)) - } - else { - startActivity(Intent(applicationContext, AboutActivity::class.java)) - } - } - } - } - catch (exception: Exception) { - exception.printStackTrace() - } - return true - } -} diff --git a/app/src/main/java/be/scri/activities/SplashActivity.kt b/app/src/main/java/be/scri/activities/SplashActivity.kt index 81ee62c2..c2ca7af4 100644 --- a/app/src/main/java/be/scri/activities/SplashActivity.kt +++ b/app/src/main/java/be/scri/activities/SplashActivity.kt @@ -1,10 +1,11 @@ package be.scri.activities import android.content.Intent +import be.scri.fragments.MainFragment class SplashActivity : BaseSplashActivity() { override fun initActivity() { - startActivity(Intent(this, MainActivity::class.java)) + startActivity(Intent(this, MainFragment::class.java)) finish() } } diff --git a/app/src/main/java/be/scri/activities/WikimediaScribeActivity.kt b/app/src/main/java/be/scri/activities/WikimediaScribeActivity.kt deleted file mode 100644 index 141c78a6..00000000 --- a/app/src/main/java/be/scri/activities/WikimediaScribeActivity.kt +++ /dev/null @@ -1,50 +0,0 @@ -package be.scri.activities - - -import android.content.Intent -import android.os.Bundle -import androidx.activity.enableEdgeToEdge -import be.scri.R -import be.scri.helpers.APP_ICON_IDS -import be.scri.helpers.APP_LAUNCHER_NAME -import com.google.android.material.bottomnavigation.BottomNavigationView - - -class WikimediaScribeActivity : BaseSimpleActivity(){ - override fun getAppIconIDs() = intent.getIntegerArrayListExtra(APP_ICON_IDS) ?: ArrayList() - - override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: "" - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_wikimedia_scribe) - enableEdgeToEdge() - val bottomNavigationView = findViewById(R.id.bottom_navigation) - - bottomNavigationView.selectedItemId = R.id.info - - bottomNavigationView.setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.settings -> { - startActivity(Intent(applicationContext, SettingsActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } - - R.id.info -> { - return@OnNavigationItemSelectedListener true } - R.id.installation -> { - startActivity(Intent(applicationContext, MainActivity::class.java)) - overridePendingTransition(0, 0) - return@OnNavigationItemSelectedListener true - } - } - false - }) - bottomNavigationView.selectedItemId = R.id.info - } - - } - - - diff --git a/app/src/main/java/be/scri/fragments/AboutFragment.kt b/app/src/main/java/be/scri/fragments/AboutFragment.kt new file mode 100644 index 00000000..22abc51a --- /dev/null +++ b/app/src/main/java/be/scri/fragments/AboutFragment.kt @@ -0,0 +1,115 @@ +package be.scri.fragments + +import android.content.Intent +import android.os.Bundle +import android.view.GestureDetector +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import be.scri.R +import be.scri.activities.MainActivity +import be.scri.databinding.FragmentAboutBinding +import be.scri.helpers.CustomAdapter +import be.scri.models.ItemsViewModel + +class AboutFragment : Fragment() { + + private var appName = "" + private var primaryColor = 0 + + private val EASTER_EGG_TIME_LIMIT = 3000L + private val EASTER_EGG_REQUIRED_CLICKS = 7 + private val SWIPE_THRESHOLD = 100 + private val SWIPE_VELOCITY_THRESHOLD = 100 + + private lateinit var binding: FragmentAboutBinding + private lateinit var gestureDetector: GestureDetector + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentAboutBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + (requireActivity() as MainActivity).supportActionBar?.title = getString(R.string.app_settings_title) + setupRecyclerViews() + } + + private fun setupRecyclerViews() { + val recyclerView1 = binding.recycleView2 + recyclerView1.layoutManager = LinearLayoutManager(context) + recyclerView1.adapter = CustomAdapter(getFirstRecyclerViewData(), requireContext()) + recyclerView1.suppressLayout(true) + + val recyclerView2 = binding.recycleView + recyclerView2.layoutManager = LinearLayoutManager(context) + recyclerView2.adapter = CustomAdapter(getSecondRecyclerViewData(), requireContext()) + recyclerView2.suppressLayout(true) + + val recyclerView3 = binding.recycleView3 + recyclerView3.layoutManager = LinearLayoutManager(context) + recyclerView3.adapter = CustomAdapter(getThirdRecyclerViewData(), requireContext()) + recyclerView3.suppressLayout(true) + } + + private fun getFirstRecyclerViewData(): List = listOf( + ItemsViewModel(image = R.drawable.github_logo, textResId = R.string.app_about_github, image2 = R.drawable.external_link, url = "https://github.com/scribe-org/Scribe-Android", activity = null, action = null), + ItemsViewModel(image = R.drawable.matrix_icon, textResId = R.string.app_about_matrix, image2 = R.drawable.external_link, url = "https://matrix.to/%23/%23scribe_community:matrix.org", activity = null, action = null), + ItemsViewModel(image = R.drawable.mastodon_svg_icon, textResId = R.string.app_about_mastodon, image2 = R.drawable.external_link, url = "https://wikis.world/@scribe", activity = null, action = null), + ItemsViewModel(image = R.drawable.share_icon, textResId = R.string.app_about_share, image2 = R.drawable.external_link, url = null, activity = null, action = ::shareScribe), + ItemsViewModel(image = R.drawable.scribe_icon, textResId = R.string.app_about_scribe, image2 = R.drawable.external_link, url = null, activity = null, action = null), + ItemsViewModel(image = R.drawable.wikimedia_logo_black, textResId = R.string.app_about_wikimedia, image2 = R.drawable.right_arrow, url = null, activity = null, action = ::loadWikimediaScribeFragment ) + ) + + private fun getSecondRecyclerViewData(): List = listOf( + ItemsViewModel(image = R.drawable.star, textResId = R.string.app_about_rate, image2 = R.drawable.external_link, url = null, activity = null, action = null), + ItemsViewModel(image = R.drawable.bug_report_icon, textResId = R.string.app_about_bugReport, image2 = R.drawable.external_link, url = "https://github.com/scribe-org/Scribe-Android/issues", activity = null, action = null), + ItemsViewModel(image = R.drawable.mail_icon, textResId = R.string.app_about_email, image2 = R.drawable.external_link, url = null, activity = null, action = ::sendEmail), + ItemsViewModel(image = R.drawable.bookmark_icon, textResId = R.string.app_version, image2 = R.drawable.right_arrow, url = null, activity = null, action = null), + ItemsViewModel(image = R.drawable.light_bulb_icon, textResId = R.string.app_about_appHints, image2 = R.drawable.counter_clockwise_icon, url = null, activity = null, action = null) + ) + + private fun getThirdRecyclerViewData(): List { + return listOf( + ItemsViewModel(image = R.drawable.shield_lock, R.string.app_about_privacyPolicy, image2 = R.drawable.right_arrow, url = null, activity = null, action = null), + ItemsViewModel(image = R.drawable.license_icon, R.string.app_about_thirdParty, image2 = R.drawable.right_arrow, url = null, activity = null, action = null) + ) + } + + private fun shareScribe() { + val sharingIntent = Intent(Intent.ACTION_SEND).apply { + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, "https://github.com/scribe-org/Scribe-Android") + } + startActivity(Intent.createChooser(sharingIntent, "Share via")) + } + + private fun sendEmail() { + val intent = Intent(Intent.ACTION_SEND).apply { + putExtra(Intent.EXTRA_EMAIL, arrayOf("team@scri.be")) + putExtra(Intent.EXTRA_SUBJECT, "Hey Scribe!") + type = "message/rfc822" + } + startActivity(Intent.createChooser(intent, "Choose an Email client:")) + } + + override fun onResume() { + super.onResume() + } + + private fun loadWikimediaScribeFragment() { + val fragment = WikimediaScribeFragment() + val fragmentTransaction = requireActivity().supportFragmentManager.beginTransaction() + fragmentTransaction.replace(R.id.fragment_container, fragment, "WikimediaScribePage") + fragmentTransaction.addToBackStack("WikimediaScribePage") + fragmentTransaction.commit() + } + + +} diff --git a/app/src/main/java/be/scri/fragments/LanguageSettingsFragment.kt b/app/src/main/java/be/scri/fragments/LanguageSettingsFragment.kt new file mode 100644 index 00000000..21a2f323 --- /dev/null +++ b/app/src/main/java/be/scri/fragments/LanguageSettingsFragment.kt @@ -0,0 +1,103 @@ +package be.scri.fragments + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.activity.OnBackPressedCallback +import androidx.activity.addCallback +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.viewpager2.widget.ViewPager2 +import be.scri.R +import be.scri.activities.MainActivity +import be.scri.databinding.FragmentLanguageSettingsBinding +import be.scri.helpers.CustomAdapter +import be.scri.models.SwitchItem + +class LanguageSettingsFragment : Fragment() { + private var _binding: FragmentLanguageSettingsBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?, + ): View? { + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + val viewpager = requireActivity().findViewById(R.id.view_pager) + val frameLayout = requireActivity().findViewById(R.id.fragment_container) + if (viewpager.currentItem == 3) { + viewpager.setCurrentItem(3, true) + frameLayout.visibility = View.GONE + } else { + if (parentFragmentManager.backStackEntryCount > 0) { + parentFragmentManager.popBackStack() + } else { + isEnabled = false + requireActivity().onBackPressed() + } + } + + (requireActivity() as MainActivity).supportActionBar?.title = getString(R.string.app_about_title) + } + }) + _binding = FragmentLanguageSettingsBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val language = arguments?.getString("LANGUAGE_EXTRA") ?: return + (requireActivity() as MainActivity).supportActionBar?.title = language + (requireActivity() as MainActivity).showFragmentContainer() + + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { + parentFragmentManager.beginTransaction() + .replace(R.id.fragment_container, SettingsFragment()) + .addToBackStack(null) + .commit() + } + setupRecyclerView(language) + } + + private fun setupRecyclerView(language: String) { + binding.recyclerView.layoutManager = LinearLayoutManager(context) + binding.recyclerView.adapter = CustomAdapter(getRecyclerViewData(language), requireContext()) + } + + private fun getRecyclerViewData(language: String): List { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + return listOf( + SwitchItem( + isChecked = sharedPref.getBoolean("period_on_double_tap_$language", false), + title = "Double space Periods", + action = { enablePeriodOnSpaceBarDoubleTap(language) }, + action2 = { disablePeriodOnSpaceBarDoubleTap(language) } + ) + ) + } + + private fun enablePeriodOnSpaceBarDoubleTap(language: String) { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("period_on_double_tap_$language", true) + editor.apply() + } + + private fun disablePeriodOnSpaceBarDoubleTap(language: String) { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("period_on_double_tap_$language", false) + editor.apply() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + + +} diff --git a/app/src/main/java/be/scri/fragments/MainFragment.kt b/app/src/main/java/be/scri/fragments/MainFragment.kt new file mode 100644 index 00000000..68bbccda --- /dev/null +++ b/app/src/main/java/be/scri/fragments/MainFragment.kt @@ -0,0 +1,95 @@ +package be.scri.fragments + +import android.content.Context +import android.content.Context.INPUT_METHOD_SERVICE +import android.content.Intent +import android.content.res.Configuration +import android.os.Bundle +import android.provider.Settings +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager +import androidx.appcompat.app.AppCompatDelegate +import androidx.fragment.app.Fragment +import be.scri.R +import be.scri.databinding.FragmentMainBinding +import be.scri.dialogs.ConfirmationAdvancedDialog + +class MainFragment : Fragment() { + + private lateinit var binding: FragmentMainBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + binding = FragmentMainBinding.inflate(inflater, container, false) + binding.scribeKey.setOnClickListener { + (requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).showInputMethodPicker() + } + applyUserDarkModePreference() + if (!isKeyboardEnabled()) { + ConfirmationAdvancedDialog( + requireActivity(), + messageId = R.string.redirection_note, + positive = R.string.ok, + negative = 0 + ) { success -> + if (success) { + Intent(Settings.ACTION_INPUT_METHOD_SETTINGS).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(this) + } + } else { + requireActivity().finish() + } + } + } + return binding.root + } + + private fun applyUserDarkModePreference() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + val isSystemDarkMode = currentNightMode == Configuration.UI_MODE_NIGHT_YES + val isUserDarkMode = sharedPref.getBoolean("dark_mode", isSystemDarkMode) + + + + AppCompatDelegate.setDefaultNightMode( + if (isUserDarkMode) AppCompatDelegate.MODE_NIGHT_YES + else AppCompatDelegate.MODE_NIGHT_NO + ) + if (isUserDarkMode != (currentNightMode == Configuration.UI_MODE_NIGHT_YES)) { + requireActivity().recreate() + } + } + + override fun onResume() { + super.onResume() + if (!isKeyboardEnabled()) { + ConfirmationAdvancedDialog( + requireActivity(), + messageId = R.string.redirection_note, + positive = R.string.ok, + negative = 0 + ) { success -> + if (success) { + Intent(Settings.ACTION_INPUT_METHOD_SETTINGS).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(this) + } + } else { + requireActivity().finish() + } + } + } + + } + + private fun isKeyboardEnabled(): Boolean { + val inputMethodManager = requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager + val enabledKeyboards = inputMethodManager.enabledInputMethodList + return enabledKeyboards.any { + it.packageName == requireContext().packageName + } + } +} diff --git a/app/src/main/java/be/scri/fragments/SettingsFragment.kt b/app/src/main/java/be/scri/fragments/SettingsFragment.kt new file mode 100644 index 00000000..08f533c7 --- /dev/null +++ b/app/src/main/java/be/scri/fragments/SettingsFragment.kt @@ -0,0 +1,224 @@ +package be.scri.fragments + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS +import android.provider.Settings.ACTION_APP_LOCALE_SETTINGS +import android.provider.Settings.ACTION_INPUT_METHOD_SETTINGS +import android.view.* +import android.view.inputmethod.InputMethodManager +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import be.scri.R +import be.scri.activities.MainActivity +import be.scri.databinding.FragmentSettingsBinding +import be.scri.extensions.config +import be.scri.helpers.CustomAdapter +import be.scri.models.SwitchItem +import be.scri.models.TextItem + +class SettingsFragment : Fragment() { + + private lateinit var binding: FragmentSettingsBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + binding = FragmentSettingsBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupRecycleView() + setupRecyclerView2() + (requireActivity() as MainActivity).supportActionBar?.title = getString(R.string.app_settings_title) + + val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + val enabledInputMethods = imm.enabledInputMethodList + for (inputMethod in enabledInputMethods) { + if (inputMethod.packageName == "be.scri.debug") { + setupItemVisibility() + } + } + + binding.btnInstall.setOnClickListener { + Intent(ACTION_INPUT_METHOD_SETTINGS).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(this) + } + } + } + + private fun setupRecycleView() { + val recyclerView = binding.recyclerViewSettings + recyclerView.adapter = CustomAdapter(getFirstRecyclerViewData(), requireContext()) + + recyclerView.layoutManager = LinearLayoutManager(requireContext()) + recyclerView.suppressLayout(true) + } + + private fun getFirstRecyclerViewData(): List { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + return listOf( + TextItem(R.string.app_settings_appSettings_appLanguage, image = R.drawable.right_arrow, action = ::selectLanguage), + SwitchItem("Dark mode", isChecked = sharedPref.getBoolean("dark_mode", false), action = ::darkMode, action2 = ::lightMode), + SwitchItem("Vibrate on Keypress", isChecked = requireContext().config.vibrateOnKeypress, action = ::enableVibrateOnKeypress, action2 = ::disableVibrateOnKeypress), + SwitchItem("Show a popup on keypress", isChecked = requireContext().config.showPopupOnKeypress, action = ::enableShowPopupOnKeypress, action2 = ::disableShowPopupOnKeypress) + ) + } + + private fun selectLanguage() { + val packageName = requireActivity().packageName + val intent: Intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + Intent(ACTION_APP_LOCALE_SETTINGS) + } else { + Intent(ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", packageName, null) + putExtra("android.intent.extra.SHOW_FRAGMENT", "com.android.settings.localepicker.LocaleListEditor") + } + } + + val uri = Uri.fromParts("package", packageName, null) + intent.data = uri + startActivity(intent) + } + + private fun setupRecyclerView2() { + val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + val enabledInputMethods = imm.enabledInputMethodList + for (inputMethod in enabledInputMethods) { + if (inputMethod.packageName == "be.scri.debug") { + setupItemVisibility() + } + } + + val recyclerView = binding.recyclerView2 + val adapter = CustomAdapter(getRecyclerViewElements(), requireContext()) + recyclerView.layoutManager = LinearLayoutManager(requireContext()) + recyclerView.adapter = adapter + recyclerView.suppressLayout(true) + } + + private fun getRecyclerViewElements(): MutableList { + val languages = setupKeyboardLanguage() + val list = mutableListOf() + for (language in languages) { + val localizeLanguage: Int = when (language) { + "English" -> R.string._global_english + "French" -> R.string._global_french + "German" -> R.string._global_german + "Russian" -> R.string._global_russian + "Spanish" -> R.string._global_spanish + "Italian" -> R.string._global_italian + "Portuguese" -> R.string._global_portuguese + else -> 0 + } + list.add( + TextItem( + text = localizeLanguage, + image = R.drawable.right_arrow, + action = { loadLanguageSettingsFragment(language) }, + language = language + ) + ) + } + return list + } + + private fun loadLanguageSettingsFragment(language: String) { + val fragment = LanguageSettingsFragment().apply { + arguments = Bundle().apply { + putString("LANGUAGE_EXTRA", language) + } + } + val fragmentTransaction = requireActivity().supportFragmentManager.beginTransaction() + fragmentTransaction.replace(R.id.fragment_container, fragment) + fragmentTransaction.addToBackStack(null) + fragmentTransaction.commit() + (requireActivity() as AppCompatActivity).supportActionBar?.title = getString(R.string.app_about_wikimedia) + } + + + private fun setupKeyboardLanguage(): MutableList { + val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + val enabledInputMethods = imm.enabledInputMethodList + val result = mutableListOf() + + for (inputMethod in enabledInputMethods) { + when (inputMethod.serviceName) { + "be.scri.services.EnglishKeyboardIME" -> result.add("English") + "be.scri.services.GermanKeyboardIME" -> result.add("German") + "be.scri.services.RussianKeyboardIME" -> result.add("Russian") + "be.scri.services.SpanishKeyboardIME" -> result.add("Spanish") + "be.scri.services.FrenchKeyboardIME" -> result.add("French") + "be.scri.services.ItalianKeyboardIME" -> result.add("Italian") + "be.scri.services.PortugueseKeyboardIME" -> result.add("Portuguese") + } + } + return result + } + + private fun lightMode() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("dark_mode", false) + editor.apply() + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + requireActivity().recreate() + } + + private fun darkMode() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("dark_mode", true) + editor.apply() + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + requireActivity().recreate() + } + + private fun enableVibrateOnKeypress() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("vibrate_on_keypress", true) + editor.apply() + requireActivity().config.vibrateOnKeypress = true + } + + private fun disableVibrateOnKeypress() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("vibrate_on_keypress", false) + editor.apply() + requireActivity().config.vibrateOnKeypress = false + } + + private fun enableShowPopupOnKeypress() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("show_popup_on_keypress", true) + editor.apply() + requireActivity().config.showPopupOnKeypress = true + } + + private fun disableShowPopupOnKeypress() { + val sharedPref = requireActivity().getSharedPreferences("app_preferences", Context.MODE_PRIVATE) + val editor = sharedPref.edit() + editor.putBoolean("show_popup_on_keypress", false) + editor.apply() + requireActivity().config.showPopupOnKeypress = false + } + + private fun setupItemVisibility() { + binding.btnInstall.visibility = View.INVISIBLE + binding.selectLanguage.visibility = View.VISIBLE + } + + override fun onResume() { + super.onResume() + setupRecyclerView2() + } +} diff --git a/app/src/main/java/be/scri/fragments/WikimediaScribeFragment.kt b/app/src/main/java/be/scri/fragments/WikimediaScribeFragment.kt new file mode 100644 index 00000000..7bb4ed27 --- /dev/null +++ b/app/src/main/java/be/scri/fragments/WikimediaScribeFragment.kt @@ -0,0 +1,66 @@ +package be.scri.fragments + + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.activity.OnBackPressedCallback +import androidx.activity.addCallback +import androidx.fragment.app.Fragment +import androidx.viewpager2.widget.ViewPager2 +import be.scri.R +import be.scri.activities.MainActivity +import be.scri.databinding.ActivityWikimediaScribeBinding + + +class WikimediaScribeFragment : Fragment(){ + + private lateinit var binding: ActivityWikimediaScribeBinding + + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val viewpager = requireActivity().findViewById(R.id.view_pager) + val frameLayout = requireActivity().findViewById(R.id.fragment_container) + val callback = requireActivity().onBackPressedDispatcher.addCallback(this) { + viewpager.setCurrentItem(2, true); + } + callback.isEnabled = true + + + } + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = ActivityWikimediaScribeBinding.inflate(inflater, container, false) + (requireActivity() as MainActivity).supportActionBar?.title = getString(R.string.app_about_wikimedia) + (requireActivity() as MainActivity).showFragmentContainer() + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + val viewpager = requireActivity().findViewById(R.id.view_pager) + val frameLayout = requireActivity().findViewById(R.id.fragment_container) + if (viewpager.currentItem == 2) { + viewpager.setCurrentItem(2, true) + frameLayout.visibility = View.GONE + } else { + if (parentFragmentManager.backStackEntryCount > 0) { + parentFragmentManager.popBackStack() + } else { + isEnabled = false + requireActivity().onBackPressed() + } + } + + (requireActivity() as MainActivity).supportActionBar?.title = getString(R.string.app_about_title) + } + }) + return binding.root + } + + } + + + diff --git a/app/src/main/java/be/scri/helpers/CustomAdapter.kt b/app/src/main/java/be/scri/helpers/CustomAdapter.kt index 313cde68..f5c0b311 100644 --- a/app/src/main/java/be/scri/helpers/CustomAdapter.kt +++ b/app/src/main/java/be/scri/helpers/CustomAdapter.kt @@ -1,6 +1,6 @@ package be.scri.helpers -import android.app.Activity +import android.content.Context import android.content.Intent import android.net.Uri import android.view.LayoutInflater @@ -17,7 +17,7 @@ import be.scri.models.ItemsViewModel import be.scri.models.SwitchItem import be.scri.models.TextItem -class CustomAdapter(private val mList: List, private val context: Activity) : RecyclerView.Adapter() { +class CustomAdapter(private val mList: List, private val context: Context) : RecyclerView.Adapter() { companion object { private const val VIEW_TYPE_IMAGE = 0 diff --git a/app/src/main/java/be/scri/helpers/ViewPagerAdapter.kt b/app/src/main/java/be/scri/helpers/ViewPagerAdapter.kt new file mode 100644 index 00000000..d5d7cb5c --- /dev/null +++ b/app/src/main/java/be/scri/helpers/ViewPagerAdapter.kt @@ -0,0 +1,24 @@ +package be.scri.adapters + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter +import be.scri.activities.MainActivity +import be.scri.fragments.AboutFragment +import be.scri.fragments.MainFragment +import be.scri.fragments.SettingsFragment + +class ViewPagerAdapter(fragment: MainActivity) : FragmentStateAdapter(fragment) { + + override fun getItemCount(): Int { + return 3 + } + + override fun createFragment(position: Int): Fragment { + return when (position) { + 0 -> MainFragment() + 1 -> SettingsFragment() + 2 -> AboutFragment() + else -> throw IllegalArgumentException("Invalid position") + } + } +} diff --git a/app/src/main/java/be/scri/models/TextItem.kt b/app/src/main/java/be/scri/models/TextItem.kt index 586b0ff8..348173b5 100644 --- a/app/src/main/java/be/scri/models/TextItem.kt +++ b/app/src/main/java/be/scri/models/TextItem.kt @@ -1,4 +1,6 @@ package be.scri.models +import androidx.fragment.app.Fragment -data class TextItem(val text: Int, val image:Int, val action: (() -> Unit)? = null, val language: String? = null ):Item() + +data class TextItem(val text: Int, val image:Int, val action: (() -> Unit)? = null, val language: String? = null, val fragment: Fragment? = null , val fragmentTag:String? = null):Item() diff --git a/app/src/main/java/be/scri/views/MyKeyboardView.kt b/app/src/main/java/be/scri/views/MyKeyboardView.kt index 25f4b57d..2f693afd 100644 --- a/app/src/main/java/be/scri/views/MyKeyboardView.kt +++ b/app/src/main/java/be/scri/views/MyKeyboardView.kt @@ -20,7 +20,7 @@ import android.view.accessibility.AccessibilityManager import android.widget.PopupWindow import android.widget.TextView import be.scri.R -import be.scri.activities.SettingsActivity +import be.scri.fragments.SettingsFragment import be.scri.databinding.KeyboardPopupKeyboardBinding import be.scri.databinding.KeyboardViewKeyboardBinding import be.scri.extensions.* @@ -360,7 +360,7 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut setOnClickListener { context?.let { ctx -> vibrateIfNeeded() - Intent(ctx, SettingsActivity::class.java).apply { + Intent(ctx, SettingsFragment::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) ctx.startActivity(this) } diff --git a/app/src/main/res/drawable/button_background_rounded.xml b/app/src/main/res/drawable/button_background_rounded.xml index 83d0ae05..36f4690e 100644 --- a/app/src/main/res/drawable/button_background_rounded.xml +++ b/app/src/main/res/drawable/button_background_rounded.xml @@ -4,7 +4,7 @@ - + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 482b55d9..b21e1e1d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,35 +1,26 @@ + android:layout_height="match_parent"> - - - - - + - + diff --git a/app/src/main/res/layout/activity_wikimedia_scribe.xml b/app/src/main/res/layout/activity_wikimedia_scribe.xml index 389a3383..3fcc75e4 100644 --- a/app/src/main/res/layout/activity_wikimedia_scribe.xml +++ b/app/src/main/res/layout/activity_wikimedia_scribe.xml @@ -1,5 +1,5 @@ - - @@ -25,16 +15,12 @@ android:layout_height="wrap_content" android:orientation="vertical" android:padding="5dp"> - @@ -120,15 +106,3 @@ - - diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/fragment_about.xml similarity index 71% rename from app/src/main/res/layout/activity_about.xml rename to app/src/main/res/layout/fragment_about.xml index 638e5595..bd5539f0 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -1,5 +1,5 @@ - - - - - diff --git a/app/src/main/res/layout/activity_language_settings.xml b/app/src/main/res/layout/fragment_language_settings.xml similarity index 60% rename from app/src/main/res/layout/activity_language_settings.xml rename to app/src/main/res/layout/fragment_language_settings.xml index 5f785615..1513bcc7 100644 --- a/app/src/main/res/layout/activity_language_settings.xml +++ b/app/src/main/res/layout/fragment_language_settings.xml @@ -5,8 +5,7 @@ android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/you_background_color" - tools:context=".activities.LanguageSettings"> + android:background="@color/you_background_color"> - + app:layout_constraintVertical_bias="0.039" /> - - diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml new file mode 100644 index 00000000..d667b55a --- /dev/null +++ b/app/src/main/res/layout/fragment_main.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/fragment_settings.xml similarity index 69% rename from app/src/main/res/layout/activity_settings.xml rename to app/src/main/res/layout/fragment_settings.xml index ce212d0a..c34055f6 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -1,5 +1,5 @@ - - + android:padding="10dp" /> + android:padding="10dp" /> - - + diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml new file mode 100644 index 00000000..29b71220 --- /dev/null +++ b/app/src/main/res/values-land/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml new file mode 100644 index 00000000..dc9b7a7d --- /dev/null +++ b/app/src/main/res/values-w1240dp/dimens.xml @@ -0,0 +1,3 @@ + + 200dp + diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml new file mode 100644 index 00000000..29b71220 --- /dev/null +++ b/app/src/main/res/values-w600dp/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e3abbe42..0c89aebc 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -69,4 +69,5 @@ 168dp 85dp + 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ee770f0e..87bd25b6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - + Scribe Scribe - Language Keyboards Scribe Thanks for downloading Scribe! Please enable keyboards on the @@ -1587,5 +1587,45 @@ @string/saturday_short @string/sunday_short + + First Fragment + Second Fragment + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris + volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus + dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend + diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a, + ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n + Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus + egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed + neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada + fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae, + molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor + bibendum, vel congue leo egestas.\n\n + Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit + amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel, + molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer + interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at + lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula, + in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque + est.\n\n + Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh. + Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui + non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In + eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc, + quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra + ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a + placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus + convallis.\n\n + Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et + malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa + gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper, + libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper + sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus + libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus + vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim. + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 52cb51d4..09b20e89 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,6 +1,6 @@ -