Initial support for third-party dispensers
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -4,9 +4,11 @@ import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.aurora.Constants
|
||||
import com.aurora.extensions.isSAndAbove
|
||||
import com.aurora.store.data.work.CacheWorker
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_INTRO
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_MIGRATION_VERSION
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_THEME_ACCENT
|
||||
@@ -43,6 +45,7 @@ class MigrationReceiver: BroadcastReceiver() {
|
||||
if (currentVersion == 0) {
|
||||
CacheWorker.scheduleAutomatedCacheCleanup(context)
|
||||
if (isSAndAbove()) context.save(PREFERENCE_THEME_ACCENT, 0)
|
||||
context.save(PREFERENCE_DISPENSER_URLS, setOf(Constants.URL_DISPENSER))
|
||||
currentVersion++
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@ object CertUtil {
|
||||
return isInstalledByFDroid(context, packageName) || isSignedByFDroid(context, packageName)
|
||||
}
|
||||
|
||||
fun isAppGalleryApp(context: Context, packageName: String): Boolean {
|
||||
val appGalleryPackageName = "com.huawei.appmarket"
|
||||
return context.packageManager.getInstallerPackageNameCompat(packageName) == appGalleryPackageName
|
||||
}
|
||||
|
||||
fun getEncodedCertificateHashes(context: Context, packageName: String): List<String> {
|
||||
return try {
|
||||
val certificates = getX509Certificates(context, packageName)
|
||||
|
||||
@@ -53,6 +53,7 @@ object Preferences {
|
||||
const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO"
|
||||
const val PREFERENCE_PROXY_ENABLED = "PREFERENCE_PROXY_ENABLED"
|
||||
|
||||
const val PREFERENCE_DISPENSER_URLS = "PREFERENCE_DISPENSER_URLS"
|
||||
const val PREFERENCE_VENDING_VERSION = "PREFERENCE_VENDING_VERSION"
|
||||
|
||||
const val PREFERENCE_UPDATES_EXTENDED = "PREFERENCE_UPDATES_EXTENDED"
|
||||
@@ -74,6 +75,10 @@ object Preferences {
|
||||
getPrefs(context).edit().putString(key, value).apply()
|
||||
}
|
||||
|
||||
fun putStringSet(context: Context, key: String, value: Set<String>) {
|
||||
getPrefs(context).edit().putStringSet(key, value).apply()
|
||||
}
|
||||
|
||||
fun putInteger(context: Context, key: String, value: Int) {
|
||||
getPrefs(context).edit().putInt(key, value).apply()
|
||||
}
|
||||
@@ -94,6 +99,10 @@ object Preferences {
|
||||
return getPrefs(context).getString(key, default).toString()
|
||||
}
|
||||
|
||||
fun getStringSet(context: Context, key: String, default: Set<String> = emptySet()): Set<String> {
|
||||
return getPrefs(context).getStringSet(key, default) ?: emptySet()
|
||||
}
|
||||
|
||||
fun getInteger(context: Context, key: String, default: Int = 0): Int {
|
||||
return getPrefs(context).getInt(key, default)
|
||||
}
|
||||
@@ -119,9 +128,13 @@ fun Context.save(key: String, value: Boolean) = Preferences.putBoolean(this, key
|
||||
|
||||
fun Context.save(key: String, value: String) = Preferences.putString(this, key, value)
|
||||
|
||||
fun Context.save(key: String, value: Set<String>) = Preferences.putStringSet(this, key, value)
|
||||
|
||||
|
||||
fun Fragment.save(key: String, value: Int) = requireContext().save(key, value)
|
||||
|
||||
fun Fragment.save(key: String, value: Boolean) = requireContext().save(key, value)
|
||||
|
||||
fun Fragment.save(key: String, value: String) = requireContext().save(key, value)
|
||||
|
||||
fun Fragment.save(key: String, value: Set<String>) = requireContext().save(key, value)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.aurora.store.view.epoxy.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.RelativeLayout
|
||||
import com.airbnb.epoxy.CallbackProp
|
||||
import com.airbnb.epoxy.ModelProp
|
||||
import com.airbnb.epoxy.ModelView
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.databinding.ViewDispenserBinding
|
||||
|
||||
@ModelView(
|
||||
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
|
||||
baseModelClass = BaseView::class
|
||||
)
|
||||
class DispenserView : RelativeLayout {
|
||||
|
||||
private lateinit var binding: ViewDispenserBinding
|
||||
|
||||
constructor(context: Context?) : super(context) {
|
||||
init(context)
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
init(context)
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
) {
|
||||
init(context)
|
||||
}
|
||||
|
||||
private fun init(context: Context?) {
|
||||
val view = inflate(context, R.layout.view_dispenser, this)
|
||||
binding = ViewDispenserBinding.bind(view)
|
||||
}
|
||||
|
||||
@ModelProp
|
||||
fun url(url: String) {
|
||||
binding.url.text = url
|
||||
}
|
||||
|
||||
@CallbackProp
|
||||
fun copy(onClickListener: OnClickListener?) {
|
||||
binding.url.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
@CallbackProp
|
||||
fun clear(onClickListener: OnClickListener?) {
|
||||
binding.btnAction.setOnClickListener(onClickListener)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.aurora.store.view.ui.dispenser
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.aurora.extensions.copyToClipBoard
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.databinding.FragmentDispenserBinding
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS
|
||||
import com.aurora.store.view.epoxy.views.DispenserViewModel_
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DispenserFragment : Fragment(R.layout.fragment_dispenser),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private var _binding: FragmentDispenserBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val dispensers: Set<String>
|
||||
get() = Preferences.getStringSet(requireContext(), PREFERENCE_DISPENSER_URLS)
|
||||
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentDispenserBinding.bind(view)
|
||||
|
||||
sharedPreferences = Preferences.getPrefs(view.context)
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
binding.addFab.setOnClickListener {
|
||||
findNavController().navigate(R.id.inputDispenserDialog)
|
||||
}
|
||||
|
||||
setupRecyclerView()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == PREFERENCE_DISPENSER_URLS) setupRecyclerView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
binding.epoxyRecycler.withModels {
|
||||
setFilterDuplicates(true)
|
||||
dispensers.forEachIndexed { index, url ->
|
||||
add(
|
||||
DispenserViewModel_()
|
||||
.id(index)
|
||||
.url(url)
|
||||
.copy { _ -> requireContext().copyToClipBoard(url) }
|
||||
.clear { _ ->
|
||||
findNavController().navigate(
|
||||
DispenserFragmentDirections
|
||||
.actionDispenserFragmentToRemoveDispenserDialog(url)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.aurora.store.view.ui.dispenser
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.util.Patterns
|
||||
import android.view.WindowManager
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.aurora.extensions.showKeyboard
|
||||
import com.aurora.extensions.toast
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS
|
||||
import com.aurora.store.util.save
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
class InputDispenserDialog: DialogFragment() {
|
||||
|
||||
private val textInputLayout: TextInputLayout?
|
||||
get() = dialog?.findViewById(R.id.textInputLayout)
|
||||
|
||||
private val dispensers: Set<String>
|
||||
get() = Preferences.getStringSet(requireContext(), PREFERENCE_DISPENSER_URLS)
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_dispenser_input, null)
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.add_dispenser_title)
|
||||
.setMessage(R.string.add_dispenser_summary)
|
||||
.setView(view)
|
||||
.setPositiveButton(getString(R.string.add)) { _, _ -> saveDispenserUrl() }
|
||||
.setNegativeButton(getString(android.R.string.cancel)) { _, _ -> dialog?.dismiss()}
|
||||
.create()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
textInputLayout?.editText?.showKeyboard()
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
||||
}
|
||||
|
||||
private fun saveDispenserUrl() {
|
||||
val url = textInputLayout?.editText?.text?.toString()
|
||||
if (!url.isNullOrEmpty() && Patterns.WEB_URL.matcher(url).matches()) {
|
||||
val newSet = dispensers.toMutableSet().apply {
|
||||
add(url)
|
||||
}
|
||||
save(PREFERENCE_DISPENSER_URLS, newSet)
|
||||
} else {
|
||||
toast(R.string.add_dispenser_error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.aurora.store.view.ui.dispenser
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS
|
||||
import com.aurora.store.util.save
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
||||
class RemoveDispenserDialog : DialogFragment() {
|
||||
|
||||
private val args: RemoveDispenserDialogArgs by navArgs()
|
||||
|
||||
private val dispensers: Set<String>
|
||||
get() = Preferences.getStringSet(requireContext(), PREFERENCE_DISPENSER_URLS)
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.remove_dispenser_title)
|
||||
.setMessage(getString(R.string.remove_dispenser_summary, args.url))
|
||||
.setPositiveButton(getString(R.string.remove)) { _, _ -> removeDispenserUrl() }
|
||||
.setNegativeButton(getString(android.R.string.cancel)) { _, _ -> dialog?.dismiss() }
|
||||
.create()
|
||||
}
|
||||
|
||||
private fun removeDispenserUrl() {
|
||||
val newSet = dispensers.toMutableSet().apply {
|
||||
remove(args.url)
|
||||
}
|
||||
save(PREFERENCE_DISPENSER_URLS, newSet)
|
||||
}
|
||||
}
|
||||
@@ -27,17 +27,20 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
import com.aurora.Constants
|
||||
import com.aurora.extensions.isIgnoringBatteryOptimizations
|
||||
import com.aurora.extensions.isSAndAbove
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.work.CacheWorker
|
||||
import com.aurora.store.data.work.UpdateWorker
|
||||
import com.aurora.store.databinding.FragmentOnboardingBinding
|
||||
import com.aurora.store.util.CertUtil
|
||||
import com.aurora.store.util.PackageUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT_SELECTED_TAB
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_AURORA_ONLY
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_FDROID
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_GOOGLE
|
||||
@@ -162,6 +165,10 @@ class OnboardingFragment : Fragment(R.layout.fragment_onboarding) {
|
||||
save(PREFERENCE_FILTER_SEARCH, true)
|
||||
|
||||
/*Network*/
|
||||
// TODO: Gather feedback and drop setting default dispenser for all builds
|
||||
if (!CertUtil.isAppGalleryApp(requireContext(), requireContext().packageName)) {
|
||||
save(PREFERENCE_DISPENSER_URLS, setOf(Constants.URL_DISPENSER))
|
||||
}
|
||||
save(PREFERENCE_INSECURE_ANONYMOUS, false)
|
||||
save(PREFERENCE_VENDING_VERSION, 0)
|
||||
|
||||
|
||||
@@ -46,6 +46,13 @@ class NetworkPreference : BasePreferenceFragment() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.preferences_network, rootKey)
|
||||
|
||||
findPreference<Preference>(Preferences.PREFERENCE_DISPENSER_URLS)?.apply {
|
||||
setOnPreferenceClickListener {
|
||||
findNavController().navigate(R.id.dispenserFragment)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
findPreference<EditTextPreference>(Preferences.PREFERENCE_PROXY_URL)?.let {
|
||||
it.summary =
|
||||
Preferences.getString(requireContext(), Preferences.PREFERENCE_PROXY_URL, "")
|
||||
|
||||
@@ -86,6 +86,12 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
|
||||
|
||||
attachActions()
|
||||
|
||||
// Show anonymous logins if we have dispenser URL
|
||||
if (!viewModel.dispenserURL.isNullOrBlank()) {
|
||||
binding.btnAnonymous.visibility = View.VISIBLE
|
||||
binding.btnAnonymousInsecure.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
//Initial status
|
||||
updateStatus(getString(R.string.session_init))
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.aurora.store.data.providers.SpoofProvider
|
||||
import com.aurora.store.util.AC2DMTask
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_AUTH_DATA
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS
|
||||
import com.google.gson.Gson
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
@@ -66,6 +67,12 @@ class AuthViewModel @Inject constructor(
|
||||
|
||||
private val spoofProvider = SpoofProvider(context)
|
||||
|
||||
val dispenserURL: String?
|
||||
get() {
|
||||
val dispensers = Preferences.getStringSet(context, PREFERENCE_DISPENSER_URLS)
|
||||
return if (dispensers.isNotEmpty()) dispensers.random() else null
|
||||
}
|
||||
|
||||
val liveData: MutableLiveData<AuthState> = MutableLiveData()
|
||||
|
||||
fun observe() {
|
||||
@@ -119,7 +126,7 @@ class AuthViewModel @Inject constructor(
|
||||
val playResponse = HttpClient
|
||||
.getPreferredClient(context)
|
||||
.postAuth(
|
||||
Constants.URL_DISPENSER,
|
||||
dispenserURL!!,
|
||||
gson.toJson(properties).toByteArray()
|
||||
)
|
||||
|
||||
@@ -154,7 +161,7 @@ class AuthViewModel @Inject constructor(
|
||||
|
||||
val playResponse = HttpClient
|
||||
.getPreferredClient(context)
|
||||
.getAuth(Constants.URL_DISPENSER)
|
||||
.getAuth(dispenserURL!!)
|
||||
|
||||
if (playResponse.isSuccessful) {
|
||||
val insecureAuth = gson.fromJson(
|
||||
|
||||
12
app/src/main/res/drawable/ic_add.xml
Normal file
12
app/src/main/res/drawable/ic_add.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
|
||||
|
||||
</vector>
|
||||
11
app/src/main/res/drawable/ic_server.xml
Normal file
11
app/src/main/res/drawable/ic_server.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M300,240Q275,240 257.5,257.5Q240,275 240,300Q240,325 257.5,342.5Q275,360 300,360Q325,360 342.5,342.5Q360,325 360,300Q360,275 342.5,257.5Q325,240 300,240ZM300,640Q275,640 257.5,657.5Q240,675 240,700Q240,725 257.5,742.5Q275,760 300,760Q325,760 342.5,742.5Q360,725 360,700Q360,675 342.5,657.5Q325,640 300,640ZM160,120L800,120Q817,120 828.5,131.5Q840,143 840,160L840,440Q840,457 828.5,468.5Q817,480 800,480L160,480Q143,480 131.5,468.5Q120,457 120,440L120,160Q120,143 131.5,131.5Q143,120 160,120ZM200,200L200,400L760,400L760,200L200,200ZM160,520L800,520Q817,520 828.5,531.5Q840,543 840,560L840,840Q840,857 828.5,868.5Q817,880 800,880L160,880Q143,880 131.5,868.5Q120,857 120,840L120,560Q120,543 131.5,531.5Q143,520 160,520ZM200,600L200,800L760,800L760,600L200,600ZM200,200L200,200L200,400L200,400L200,200ZM200,600L200,600L200,800L200,800L200,600Z"/>
|
||||
</vector>
|
||||
@@ -76,11 +76,12 @@
|
||||
tools:text="Sign in first" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_action"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_large"
|
||||
android:visibility="invisible"
|
||||
@@ -91,36 +92,29 @@
|
||||
style="@style/AuroraTextStyle.Line1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/btn_google"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/margin_normal"
|
||||
android:text="@string/account_login_using"
|
||||
android:textAlignment="center" />
|
||||
android:text="@string/account_login_using" />
|
||||
|
||||
<com.aurora.store.view.custom.layouts.button.StateButton
|
||||
android:id="@+id/btn_google"
|
||||
android:layout_width="@dimen/width_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/btn_anonymous"
|
||||
android:layout_centerHorizontal="true"
|
||||
app:btnStateIcon="@drawable/ic_google"
|
||||
app:btnStateText="@string/account_google" />
|
||||
|
||||
<com.aurora.store.view.custom.layouts.button.StateButton
|
||||
android:id="@+id/btn_anonymous"
|
||||
android:visibility="gone"
|
||||
android:layout_width="@dimen/width_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
app:btnStateIcon="@drawable/ic_anonymous"
|
||||
app:btnStateText="@string/account_anonymous" />
|
||||
|
||||
<com.aurora.store.view.custom.layouts.button.StateButton
|
||||
android:visibility="gone"
|
||||
android:id="@+id/btn_anonymous_insecure"
|
||||
android:layout_width="@dimen/width_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/btn_anonymous"
|
||||
android:layout_centerHorizontal="true"
|
||||
app:btnStateIcon="@drawable/ic_anonymous"
|
||||
app:btnStateText="@string/account_anonymous_insecure" />
|
||||
|
||||
@@ -129,11 +123,9 @@
|
||||
style="@style/AuroraTextStyle.Line3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/margin_small"
|
||||
android:textAlignment="center"
|
||||
tools:text="Version 4.0.1" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
16
app/src/main/res/layout/dialog_dispenser_input.xml
Normal file
16
app/src/main/res/layout/dialog_dispenser_input.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.textfield.TextInputLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/textInputLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/padding_large"
|
||||
android:paddingTop="@dimen/padding_normal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/textInputEditText"
|
||||
style="@style/Widget.Material3.TextInputEditText.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/add_dispenser_hint" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
47
app/src/main/res/layout/fragment_dispenser.xml
Normal file
47
app/src/main/res/layout/fragment_dispenser.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".view.ui.dispenser.DispenserFragment">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navigationIcon="@drawable/ic_arrow_back"
|
||||
app:title="@string/pref_dispenser_title" />
|
||||
|
||||
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||
android:id="@+id/epoxy_recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:clipToPadding="false"
|
||||
android:overScrollMode="never"
|
||||
android:padding="@dimen/padding_normal"
|
||||
android:scrollbars="none"
|
||||
app:itemSpacing="@dimen/margin_small"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/toolbar"
|
||||
tools:listitem="@layout/view_dispenser" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/add_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_large"
|
||||
android:contentDescription="@string/action_search"
|
||||
app:backgroundTint="?colorAccent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/ic_add"
|
||||
app:tint="@color/colorWhite" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -70,12 +70,12 @@
|
||||
tools:text="Sign in first" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_action"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_horizontal|center_vertical"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_large"
|
||||
android:visibility="invisible"
|
||||
@@ -86,17 +86,13 @@
|
||||
style="@style/AuroraTextStyle.Line1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/margin_normal"
|
||||
android:text="@string/account_login_using"
|
||||
android:textAlignment="center" />
|
||||
android:text="@string/account_login_using" />
|
||||
|
||||
<com.aurora.store.view.custom.layouts.button.StateButton
|
||||
android:id="@+id/btn_google"
|
||||
android:layout_width="@dimen/width_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/txt_action"
|
||||
android:layout_centerHorizontal="true"
|
||||
app:btnStateIcon="@drawable/ic_google"
|
||||
app:btnStateText="@string/account_google" />
|
||||
|
||||
@@ -104,8 +100,7 @@
|
||||
android:id="@+id/btn_anonymous"
|
||||
android:layout_width="@dimen/width_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/btn_google"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone"
|
||||
app:btnStateIcon="@drawable/ic_anonymous"
|
||||
app:btnStateText="@string/account_anonymous" />
|
||||
|
||||
@@ -113,8 +108,7 @@
|
||||
android:id="@+id/btn_anonymous_insecure"
|
||||
android:layout_width="@dimen/width_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/btn_anonymous"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone"
|
||||
app:btnStateIcon="@drawable/ic_anonymous"
|
||||
app:btnStateText="@string/account_anonymous_insecure" />
|
||||
|
||||
@@ -123,10 +117,8 @@
|
||||
style="@style/AuroraTextStyle.Line3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/margin_small"
|
||||
android:textAlignment="center"
|
||||
tools:text="Version 4.0.1" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
30
app/src/main/res/layout/view_dispenser.xml
Normal file
30
app/src/main/res/layout/view_dispenser.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:background="@drawable/bg_outlined_padded"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/url"
|
||||
style="@style/AuroraTextStyle.Subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@id/btn_action"
|
||||
android:drawableStart="@drawable/ic_server"
|
||||
android:drawablePadding="@dimen/padding_small"
|
||||
tools:text="https://auroraoss.com/api/auth" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_action"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog.Flush"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="@dimen/margin_small"
|
||||
android:text="@string/remove" />
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -394,6 +394,15 @@
|
||||
android:name="com.aurora.store.view.ui.preferences.InstallerFragment"
|
||||
android:label="InstallerFragment"
|
||||
tools:layout="@layout/fragment_installer"/>
|
||||
<fragment
|
||||
android:id="@+id/dispenserFragment"
|
||||
android:name="com.aurora.store.view.ui.dispenser.DispenserFragment"
|
||||
android:label="DispenserFragment"
|
||||
tools:layout="@layout/fragment_dispenser" >
|
||||
<action
|
||||
android:id="@+id/action_dispenserFragment_to_removeDispenserDialog"
|
||||
app:destination="@id/removeDispenserDialog" />
|
||||
</fragment>
|
||||
<dialog
|
||||
android:id="@+id/appMenuSheet"
|
||||
android:name="com.aurora.store.view.ui.sheets.AppMenuSheet"
|
||||
@@ -479,4 +488,15 @@
|
||||
android:id="@+id/moreDialogFragment"
|
||||
android:name="com.aurora.store.view.ui.commons.MoreDialogFragment"
|
||||
android:label="MoreDialogFragment" />
|
||||
<dialog
|
||||
android:id="@+id/inputDispenserDialog"
|
||||
android:name="com.aurora.store.view.ui.dispenser.InputDispenserDialog"
|
||||
android:label="@string/add_dispenser_title" />
|
||||
<dialog
|
||||
android:id="@+id/removeDispenserDialog"
|
||||
android:name="com.aurora.store.view.ui.dispenser.RemoveDispenserDialog"
|
||||
android:label="@string/remove_dispenser_title" >
|
||||
<argument android:name="url"
|
||||
app:argType="string" />
|
||||
</dialog>
|
||||
</navigation>
|
||||
|
||||
@@ -436,4 +436,18 @@
|
||||
<string name="pref_clear_device_owner_title">Clear device owner</string>
|
||||
<string name="pref_clear_device_owner_summary">Removes Aurora Store as the device owner app</string>
|
||||
<string name="pref_clear_device_owner_desc">This will revoke session installer\'s permission to silently install app. Proceed with clearing device ownership?</string>
|
||||
|
||||
<!-- DispenserFragment -->
|
||||
<string name="pref_dispenser_title">Manage dispensers</string>
|
||||
<string name="pref_dispenser_summary">View and manage token dispensers for anonymous logins</string>
|
||||
|
||||
<!-- DialogDispenserInput-->
|
||||
<string name="add_dispenser_title">Add dispenser</string>
|
||||
<string name="add_dispenser_summary">Add a token dispenser to Aurora Store. Token dispensers provide account credentials to Aurora Store for logging in anonymously.</string>
|
||||
<string name="add_dispenser_error">Invalid URL</string>
|
||||
<string name="add_dispenser_hint">Dispenser URL</string>
|
||||
<string name="remove_dispenser_title">Remove dispenser</string>
|
||||
<string name="remove_dispenser_summary">Do you wish to remove the dispenser \"<xliff:g id="url">%1$s</xliff:g>\"?</string>
|
||||
<string name="add">Add</string>
|
||||
<string name="remove">Remove</string>
|
||||
</resources>
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Preference
|
||||
app:allowDividerBelow="true"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="PREFERENCE_DISPENSER_URLS"
|
||||
app:summary="@string/pref_dispenser_summary"
|
||||
app:title="@string/pref_dispenser_title" />
|
||||
|
||||
<PreferenceCategory
|
||||
app:allowDividerAbove="true"
|
||||
app:allowDividerBelow="true"
|
||||
|
||||
Reference in New Issue
Block a user