Author: Adam <git@apiote.xyz>
begin new login
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 91096abf593d7294f7fb9a4c254b0b069b7e539e..49d36b02d45d1048704889f39a42ec6340d001a9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,6 +24,7 @@ versionName = "3.6.1" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" resourceConfigurations += listOf("en", "pl", "it", "de", "fr", "en-rUS") + manifestPlaceholders["appAuthRedirectScheme"] = "bimba" } buildTypes { @@ -76,6 +77,7 @@ implementation("com.google.guava:guava:31.0.1-android") implementation(project(":fruchtfleisch")) implementation("ch.acra:acra-http:5.11.3") implementation("ch.acra:acra-notification:5.11.3") + implementation("net.openid:appauth:0.11.1") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 66a021e365d8b0f0506f6a62a283ce3d9d891df6..56791c555a19198a39fff5b75aef95583d9fe6b0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,13 +32,6 @@android:name=".search.LineGraphActivity" android:exported="false" android:theme="@style/Theme.Bimba.Style.NoActionBar" /> - <activity - android:name=".settings.ServerChooserActivity" - android:exported="false"> - <meta-data - android:name="android.app.lib_name" - android:value="" /> - </activity> <activity android:name=".onboarding.OnboardingActivity" /> <activity android:name=".settings.feeds.FeedChooserActivity" diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt index ac05a4944b6d577160c3793997583c9c7126ccf1..463fd988ac44fadfa794b06ca42128cce9585455 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt @@ -40,9 +40,9 @@ import xyz.apiote.bimba.czwek.dashboard.ui.map.MapFragment import xyz.apiote.bimba.czwek.dashboard.ui.voyage.VoyageFragment import xyz.apiote.bimba.czwek.databinding.ActivityMainBinding import xyz.apiote.bimba.czwek.onboarding.FirstRunActivity +import xyz.apiote.bimba.czwek.onboarding.OnboardingActivity import xyz.apiote.bimba.czwek.search.ResultsActivity import xyz.apiote.bimba.czwek.settings.DownloadCitiesWorker -import xyz.apiote.bimba.czwek.settings.ServerChooserActivity import xyz.apiote.bimba.czwek.settings.SettingsActivity import xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity @@ -104,8 +104,9 @@ }) binding.navigationDrawer.setNavigationItemSelectedListener { when (it.itemId) { - R.id.drawer_servers -> { - startActivity(Intent(this, ServerChooserActivity::class.java)) + R.id.drawer_account -> { + // TODO if logged-in -> AccountActivity, else -> OnboardingActivity + startActivity(Intent(this, OnboardingActivity::class.java)) } R.id.drawer_cities -> { diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt index f5df578827b6c4cc1cdb8844307a9ca4fa94b4dc..f934bd2eb9c7e7f084b89b67dd6e0cf0d18e97c1 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt @@ -4,26 +4,37 @@ // SPDX-License-Identifier: GPL-3.0-or-later package xyz.apiote.bimba.czwek.onboarding -import android.graphics.Typeface +import android.content.Intent +import android.content.SharedPreferences +import android.net.Uri import android.os.Bundle -import android.text.Spannable -import android.text.SpannableStringBuilder -import android.text.style.RelativeSizeSpan -import android.text.style.StyleSpan -import android.widget.Button +import android.util.Log import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.edit import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding -import xyz.apiote.bimba.czwek.R +import androidx.core.widget.addTextChangedListener +import net.openid.appauth.AuthState +import net.openid.appauth.AuthorizationException +import net.openid.appauth.AuthorizationRequest +import net.openid.appauth.AuthorizationResponse +import net.openid.appauth.AuthorizationService +import net.openid.appauth.AuthorizationServiceConfiguration +import net.openid.appauth.AuthorizationServiceConfiguration.RetrieveConfigurationCallback +import net.openid.appauth.ResponseTypeValues +import xyz.apiote.bimba.czwek.api.Server import xyz.apiote.bimba.czwek.databinding.ActivityOnboardingBinding -import xyz.apiote.bimba.czwek.settings.ServerChooserActivity +import xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity + class OnboardingActivity : AppCompatActivity() { private var _binding: ActivityOnboardingBinding? = null private val binding get() = _binding!! + private lateinit var preferences: SharedPreferences + private lateinit var authState: AuthState private val activityLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { @@ -43,41 +54,108 @@ val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) v.updatePadding(right = insets.right, left = insets.left, bottom = insets.bottom) windowInsets } + preferences = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE) - prepareButton( - binding.buttonSimple, - getString(R.string.onboarding_simple), - getString(R.string.onboarding_simple_action), - true - ) - prepareButton( - binding.buttonAdvanced, - getString(R.string.onboarding_advanced), - getString(R.string.onboarding_advanced_action), - false - ) + preferences.edit(true) { + putBoolean(IN_FEEDS_TRANSACTION, true) + } + + binding.server.editText!!.addTextChangedListener { editable -> + binding.accountButton.isEnabled = !editable.isNullOrBlank() + binding.anonymousButton.isEnabled = !editable.isNullOrBlank() + } + + if (!FirstRunActivity.getFirstRun(this)) { + Server.get(this).let { server -> + binding.server.editText!!.setText(server.host) + } + } + + binding.accountButton.setOnClickListener { + // TODO OIDC flow https://github.com/openid/AppAuth-Android + oidcFlow() + } + + binding.anonymousButton.setOnClickListener { + moveOn() + } } - private fun prepareButton(button: Button, title: String, description: String, simple: Boolean) { - button.text = SpannableStringBuilder().apply { - append( - title, - StyleSpan(Typeface.BOLD), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE - ) - append("\n") - append( - description, - RelativeSizeSpan(.75f), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE - ) + private fun setServer(hostname: String) { + preferences.edit(true) { + putString(Server.HOST_KEY, hostname) } - button.setOnClickListener { - moveOn(simple) + } + + private fun moveOn() { + // TODO test 401/403 + // TODO show rate-limit info, terms and privacy + binding.server.editText?.text?.toString()?.let { serverAddress -> setServer(serverAddress) } + activityLauncher.launch(Intent(this, FeedChooserActivity::class.java)) + } + + private fun oidcFlow() { + AuthorizationServiceConfiguration.fetchFromIssuer( + Uri.parse("https://oauth-bimba.apiote.xyz"), + RetrieveConfigurationCallback { serviceConfiguration, ex -> + if (ex != null) { + Log.e("OIDC", "failed to fetch configuration") + return@RetrieveConfigurationCallback + } + authState = AuthState(serviceConfiguration!!) + + /* + {"client_id":"46e1be27-a747-4507-a1d4-c383f137745f","client_name":"Bimba","client_secret_expires_at":0,"client_uri":"https://bimba.app","contacts":["questions@bimba.app"],"created_at":"2024-09-09T12:41:30Z","grant_types":["authorization_code","refresh_token"],"jwks":{},"logo_uri":"https://bimba.app/bimba.svg","metadata":{},"owner":"","policy_uri":"","redirect_uris":["bimba://callback"],"registration_access_token":"ory_at_xQWn3kMRuev5ZmCM_BgwnuOo57GRKWz-7LAA8EH2OTA.GXZCCf7XCg8fIwjpGZjZGdgJPMSsMSM9E-6B7bE8nB0","registration_client_uri":"https://oauth-bimba.apiote.xyz/oauth2/register/","request_object_signing_alg":"RS256","response_types":["code","id_token"],"scope":"openid offline","skip_consent":false,"skip_logout_consent":false,"subject_type":"public","token_endpoint_auth_method":"none","tos_uri":"","updated_at":"2024-09-09T14:41:29.982386+02:00","userinfo_signed_response_alg":"none"} + */ + val authRequest = AuthorizationRequest.Builder( + serviceConfiguration, + "46e1be27-a747-4507-a1d4-c383f137745f", + ResponseTypeValues.CODE, + Uri.parse("bimba://callback") + ) + .setScope("openid offline") + .build(); + + val authIntent = AuthorizationService(this).getAuthorizationRequestIntent(authRequest) + startActivityForResult(authIntent, RC_AUTH) + }) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == RC_AUTH) { + val resp = AuthorizationResponse.fromIntent(data!!) + val ex = AuthorizationException.fromIntent(data) + if (resp != null) { + authState.update(resp, ex) + AuthorizationService(this).performTokenRequest( + resp.createTokenExchangeRequest() + ) { tokenResponse, tokenException -> + if (tokenResponse != null) { + authState.update(resp, ex) + getSharedPreferences("auth", MODE_PRIVATE).edit { + putString("state", authState.jsonSerializeString()) + } + if (tokenResponse.idToken == null) { + // TODO openid is needed; show some dialogue + } + Log.i("OIDC", "got token: id: ${tokenResponse.idToken}\n access: ${tokenResponse.accessToken}\n params: ${tokenResponse.additionalParameters}") + // TODO moveOn() + } else { + // FIXME token exchange failed: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). + Log.e("OIDC", "token exchange failed: ${tokenException!!.message}") + tokenException.printStackTrace() + } + } + } else { + Log.e("OIDC", "auth failed: ${ex!!.message}") + } } } - private fun moveOn(simple: Boolean) { - activityLauncher.launch(ServerChooserActivity.getIntent(this, simple)) + companion object { + const val PREFERENCES_NAME = "shp" + const val IN_FEEDS_TRANSACTION = "inFeedsTransaction" + const val RC_AUTH = 42 } } \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/ServerChooserActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/ServerChooserActivity.kt deleted file mode 100644 index 8eb69c2ac80b7122daaae47c52eb377f6755e1d4..0000000000000000000000000000000000000000 --- a/app/src/main/java/xyz/apiote/bimba/czwek/settings/ServerChooserActivity.kt +++ /dev/null @@ -1,235 +0,0 @@ -// SPDX-FileCopyrightText: Adam Evyčędo -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package xyz.apiote.bimba.czwek.settings - -import android.content.Context -import android.content.Intent -import android.content.SharedPreferences -import android.graphics.Color -import android.os.Bundle -import android.util.Log -import androidx.activity.enableEdgeToEdge -import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.content.res.AppCompatResources -import androidx.core.content.edit -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.updatePadding -import androidx.core.widget.addTextChangedListener -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.yaml.snakeyaml.error.YAMLException -import xyz.apiote.bimba.czwek.R -import xyz.apiote.bimba.czwek.api.Bimba -import xyz.apiote.bimba.czwek.api.Server -import xyz.apiote.bimba.czwek.api.TrafficFormatException -import xyz.apiote.bimba.czwek.api.getBimba -import xyz.apiote.bimba.czwek.databinding.ActivityServerChooserBinding -import xyz.apiote.bimba.czwek.onboarding.FirstRunActivity -import xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity - -class ServerChooserActivity : AppCompatActivity() { - companion object { - const val PARAM_SIMPLE = "simple" - const val IN_FEEDS_TRANSACTION = "inFeedsTransaction" - const val PREFERENCES_NAME = "shp" - fun getIntent(context: Context, simple: Boolean) = Intent(context, ServerChooserActivity::class.java).apply { - putExtra(PARAM_SIMPLE, simple) - } - } - - private var _binding: ActivityServerChooserBinding? = null - private val binding get() = _binding!! - - private val activityLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - if (!preferences.getBoolean(IN_FEEDS_TRANSACTION, true)) { - finish() - } - } - - private lateinit var preferences: SharedPreferences - - override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() - super.onCreate(savedInstanceState) - - preferences = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE) - - if (intent.getBooleanExtra(PARAM_SIMPLE, false)) { - setServer(Server.DEFAULT, "") - checkServer(true) - } else { - _binding = ActivityServerChooserBinding.inflate(layoutInflater) - setContentView(binding.root) - - ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, windowInsets -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.updatePadding(right = insets.right, left = insets.left, top = insets.top) - windowInsets - } - - preferences.edit(true) { - putBoolean(IN_FEEDS_TRANSACTION, true) - } - - if (preferences.getBoolean("shibboleet", false)) { - binding.button.setBackgroundColor(Color.rgb(35, 93, 121)) - binding.button.setTextColor(Color.WHITE) - } - - binding.button.isEnabled = false - binding.serverField.editText!!.addTextChangedListener { editable -> - binding.button.isEnabled = !editable.isNullOrBlank() - } - - if (!FirstRunActivity.getFirstRun(this)) { - Server.get(this).let { server -> - binding.serverField.editText!!.setText(server.host) - binding.tokenField.editText!!.setText(server.token) - } - } - - binding.button.setOnClickListener { - when (binding.serverField.editText!!.text.toString()) { - ":shibboleet" -> { - binding.button.setBackgroundColor(Color.rgb(35, 93, 121)) - binding.button.setTextColor(Color.WHITE) - preferences.edit(true) { - putBoolean("shibboleet", true) - } - if (!FirstRunActivity.getFirstRun(this)) { - Server.get(this).let { server -> - binding.serverField.editText!!.setText(server.host) - binding.tokenField.editText!!.setText(server.token) - } - } - } - - ";shibboleet" -> { - _binding = ActivityServerChooserBinding.inflate(layoutInflater) - setContentView(binding.root) - preferences.edit(true) { - putBoolean("shibboleet", false) - } - if (!FirstRunActivity.getFirstRun(this)) { - Server.get(this).let { server -> - binding.serverField.editText!!.setText(server.host) - binding.tokenField.editText!!.setText(server.token) - } - } - } - - else -> { - setServer( - binding.serverField.editText!!.text.toString(), - binding.tokenField.editText!!.text.toString() - ) - checkServer(false) - } - } - } - } - } - - private fun showDialog( - title: Int, description: Int, icon: Int, onPositive: (() -> Unit)? - ) { - MaterialAlertDialogBuilder(this).setIcon(AppCompatResources.getDrawable(this, icon)) - .setTitle(getString(title)).setMessage(getString(description)) - .setNegativeButton(R.string.cancel) { _, _ -> }.apply { - if (onPositive != null) { - setPositiveButton(R.string.continue_) { _, _ -> - onPositive() - } - } - }.show() - } - - private fun checkServer(isSimple: Boolean) { - MainScope().launch { - val result = getBimba(this@ServerChooserActivity, Server.get(this@ServerChooserActivity)) - if (result.error != null) { - showDialog(R.string.error, result.error.stringResource, result.error.imageResource, null) - Log.w( - "ServerChooser", "${result.error.statusCode}, ${getString(result.error.stringResource)}" - ) - return@launch - } - val bimba = try { - withContext(Dispatchers.IO) { - Bimba.unmarshal(result.stream!!) - } - } catch (e: YAMLException) { - Log.w("ServerChooser", e.message ?: "YAML error") - showDialog(R.string.error, R.string.error_traffic_spec, R.drawable.error_server, null) - return@launch - } catch (e: TrafficFormatException) { - Log.w("ServerChooser", e.message) - showDialog(R.string.error, R.string.error_traffic_spec, R.drawable.error_server, null) - return@launch - } - - if (preferences.getBoolean("shibboleet", false)) { - val validServers = bimba.servers.filter { !it.getOrDefault("url", null).isNullOrBlank() } - val servers = validServers.toTypedArray() - MaterialAlertDialogBuilder(this@ServerChooserActivity) - .setTitle(R.string.choose_server) - .setItems(servers.map { it["description"] }.toTypedArray()) { _, i -> - updateServer(servers[i]["url"].toString()) - moveOn(bimba, false) - } - .show() - return@launch - } - - updateServer(bimba.servers[0]["url"]!!) - moveOn(bimba, isSimple) - return@launch - } - } - - private fun moveOn(bimba: Bimba, isSimple: Boolean) { - val token = preferences.getString(Server.TOKEN_KEY, "") - - if (bimba.isPrivate() && token == "") { - showDialog(R.string.error, R.string.server_private_question, R.drawable.error_sec, null) - return - } - if (bimba.isRateLimited() && token == "" && !isSimple) { - showDialog( - R.string.rate_limit, R.string.server_rate_limited_question, R.drawable.error_limit - ) { - runFeedsActivity() - } - return - } - runFeedsActivity() - } - - private fun setServer(hostname: String, token: String) { - preferences.edit(true) { - putString(Server.HOST_KEY, hostname) - putString(Server.TOKEN_KEY, token) - } - } - - private fun updateServer(apiPath: String) { - preferences.edit(true) { - putString(Server.API_PATH_KEY, apiPath) - } - } - - private fun runFeedsActivity() { - activityLauncher.launch(Intent(this, FeedChooserActivity::class.java)) - if (intent.getBooleanExtra(PARAM_SIMPLE, false)) { - finish() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt index 3d49614ac2d04edf2269267b404c0f4c5ecc7b7e..b712d05ae2e23872fe8dea94d7303af43f68b91d 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt @@ -14,7 +14,6 @@ import androidx.core.content.edit import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding -import androidx.core.widget.doAfterTextChanged import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionManager @@ -24,8 +23,8 @@ import xyz.apiote.bimba.czwek.api.Server import xyz.apiote.bimba.czwek.dashboard.MainActivity import xyz.apiote.bimba.czwek.databinding.ActivityFeedChooserBinding import xyz.apiote.bimba.czwek.onboarding.FirstRunActivity +import xyz.apiote.bimba.czwek.onboarding.OnboardingActivity import xyz.apiote.bimba.czwek.repo.FeedInfo -import xyz.apiote.bimba.czwek.settings.ServerChooserActivity // TODO on internet connection -> getServer // TODO swipe to refresh? @@ -68,14 +67,6 @@ setUpRecycler() getServer() - binding.searchBar.editText?.doAfterTextChanged { editable -> - if (editable != null) { - updateItems((viewModel.feeds.value ?: emptyMap()).values.filter { - it.name.contains(editable, true) - }, null) - } - } - binding.button.setOnClickListener { moveOn() } @@ -131,7 +122,7 @@ private fun moveOn() { viewModel.settings.value?.save(this, Server.get(this)) val preferences = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE) preferences.edit(true) { - putBoolean(ServerChooserActivity.IN_FEEDS_TRANSACTION, false) + putBoolean(OnboardingActivity.IN_FEEDS_TRANSACTION, false) } if (FirstRunActivity.getFirstRun(this)) { val intent = Intent(this, MainActivity::class.java) @@ -161,11 +152,6 @@ notify: Boolean = true ) { binding.feedsOverlay.visibility = View.GONE binding.resultsRecycler.visibility = View.VISIBLE - binding.searchBar.visibility = if ((viewModel.feeds.value?.size ?: 0) > 12) { - View.VISIBLE - } else { - View.GONE - } binding.button.visibility = View.VISIBLE adapter.update(feeds, feedsSettings, notify) if (feeds?.isEmpty() == true) { diff --git a/app/src/main/res/drawable/account.xml b/app/src/main/res/drawable/account.xml new file mode 100644 index 0000000000000000000000000000000000000000..c4f8ce8167c6e1a550c0fbe5f26b506554e196f2 --- /dev/null +++ b/app/src/main/res/drawable/account.xml @@ -0,0 +1,17 @@ +<!-- +SPDX-FileCopyrightText: Google + +SPDX-License-Identifier: Apache-2.0 +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorOnSurface" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,6c1.93,0 3.5,1.57 3.5,3.5S13.93,13 12,13s-3.5,-1.57 -3.5,-3.5S10.07,6 12,6zM12,20c-2.03,0 -4.43,-0.82 -6.14,-2.88C7.55,15.8 9.68,15 12,15s4.45,0.8 6.14,2.12C16.43,19.18 14.03,20 12,20z" /> + +</vector> diff --git a/app/src/main/res/drawable/checkmark.xml b/app/src/main/res/drawable/checkmark.xml new file mode 100644 index 0000000000000000000000000000000000000000..3103b5a7baeee9327e2d3e84140d5b3e7ecc02b7 --- /dev/null +++ b/app/src/main/res/drawable/checkmark.xml @@ -0,0 +1,18 @@ +<!-- +SPDX-FileCopyrightText: Google + +SPDX-License-Identifier: Apache-2.0 +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorOnSurface" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" /> + +</vector> diff --git a/app/src/main/res/drawable/edit.xml b/app/src/main/res/drawable/edit.xml new file mode 100644 index 0000000000000000000000000000000000000000..70b1ec3fa132c43251eef2f4f4490d7d02706c3b --- /dev/null +++ b/app/src/main/res/drawable/edit.xml @@ -0,0 +1,18 @@ +<!-- +SPDX-FileCopyrightText: Google + +SPDX-License-Identifier: Apache-2.0 +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorOnSurface" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" /> + +</vector> diff --git a/app/src/main/res/drawable/logout.xml b/app/src/main/res/drawable/logout.xml new file mode 100644 index 0000000000000000000000000000000000000000..65140ae90f047fff227726f0a4a27eb70caf4916 --- /dev/null +++ b/app/src/main/res/drawable/logout.xml @@ -0,0 +1,19 @@ +<!-- +SPDX-FileCopyrightText: Google + +SPDX-License-Identifier: Apache-2.0 +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:autoMirrored="true" + android:tint="?attr/colorOnSurface" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M17,7l-1.41,1.41L18.17,11H8v2h10.17l-2.58,2.58L17,17l5,-5zM4,5h8V3H4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h8v-2H4V5z" /> + +</vector> diff --git a/app/src/main/res/layout/account.xml b/app/src/main/res/layout/account.xml index 3de5cf75542f454fbc97f2b5bcc7a56b4d3f657e..f0edee1eea3f31121dbf710167a97dcb94d810e0 100644 --- a/app/src/main/res/layout/account.xml +++ b/app/src/main/res/layout/account.xml @@ -1,47 +1,166 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.coordinatorlayout.widget.CoordinatorLayout 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"> - <com.google.android.material.textview.MaterialTextView - android:id="@+id/headline" - android:layout_width="wrap_content" + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="32dp" - android:layout_marginTop="64dp" - android:text="Way to go, Adam!" - android:textAppearance="@style/TextAppearance.Material3.HeadlineLarge" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + android:fitsSystemWindows="true"> + + <com.google.android.material.appbar.CollapsingToolbarLayout + style="?attr/collapsingToolbarLayoutLargeStyle" + android:layout_width="match_parent" + android:layout_height="?attr/collapsingToolbarLayoutLargeSize" + app:contentScrim="?attr/colorPrimary" + app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" + tools:title="Way to go, Adam!"> + + <com.google.android.material.appbar.MaterialToolbar + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:elevation="0dp" + app:layout_collapseMode="pin" + app:menu="@menu/account" /> - <com.google.android.material.textview.MaterialTextView - android:id="@+id/login" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="32dp" - android:layout_marginTop="16dp" - android:text="Logged in as adam@bimba.app\non my-bimba.apiote.xyz" - android:textAppearance="@style/TextAppearance.Material3.BodyMedium" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/headline" /> + </com.google.android.material.appbar.CollapsingToolbarLayout> - <Button - android:id="@+id/account_button" - style="?attr/materialIconButtonStyle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - app:icon="@drawable/open_outside" - app:layout_constraintBottom_toBottomOf="@+id/login" - app:layout_constraintStart_toEndOf="@+id/login" - app:layout_constraintTop_toTopOf="@+id/login" /> + </com.google.android.material.appbar.AppBarLayout> - <View - android:id="@+id/divider" + <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" - android:layout_height="1dp" - android:layout_marginTop="16dp" - android:background="?android:attr/listDivider" - app:layout_constraintTop_toBottomOf="@+id/login" /> -</androidx.constraintlayout.widget.ConstraintLayout> + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/identity_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:text="@string/logged_in_as" + android:textAppearance="@style/TextAppearance.Material3.LabelLarge" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/identity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="4dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toStartOf="@+id/identity_button" + app:layout_constraintTop_toTopOf="@+id/identity_label" + tools:text="\@me:apiote.xyz" /> + + <Button + android:id="@+id/identity_button" + style="?attr/materialIconButtonStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@string/open_browser_to_edit_identity" + android:paddingStart="0dp" + android:paddingEnd="16dp" + app:icon="@drawable/open_outside" + app:layout_constraintBottom_toBottomOf="@+id/identity" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/identity" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/server_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:text="@string/using" + android:textAppearance="@style/TextAppearance.Material3.LabelLarge" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/identity" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/server" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/server_label" + tools:text="bimba.apiote.xyz" /> + + <View + android:id="@+id/divider" + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginTop="16dp" + android:background="?android:attr/listDivider" + app:layout_constraintTop_toBottomOf="@+id/server" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/matrix_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:text="@string/matrix_handle" + android:textAppearance="@style/TextAppearance.Material3.LabelLarge" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/divider" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/matrix" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/matrix_label" + tools:text="\@me:apiote.xyz" /> + + <!-- TODO colorError for unverified --> + <com.google.android.material.textview.MaterialTextView + android:id="@+id/matrix_verification" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginEnd="16dp" + android:textAppearance="@style/TextAppearance.Material3.BodySmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/matrix" + tools:text="verified" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/seat_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:text="@string/subscription" + android:textAppearance="@style/TextAppearance.Material3.LabelLarge" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/matrix_verification" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/subscription_end" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginEnd="16dp" + android:textAppearance="@style/TextAppearance.Material3.BodySmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/seat" + tools:text="ends on Thu, May 28" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/seat" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/seat_label" + tools:text="back seat" /> + + </androidx.constraintlayout.widget.ConstraintLayout> +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/account_edit.xml b/app/src/main/res/layout/account_edit.xml index 0d4867f726bc0c3f708f0d068ffb09750af1ee93..a912c25b2175296d2b4ce9b1baf3d2de9879facb 100644 --- a/app/src/main/res/layout/account_edit.xml +++ b/app/src/main/res/layout/account_edit.xml @@ -1,6 +1,79 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.coordinatorlayout.widget.CoordinatorLayout 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"> -</androidx.constraintlayout.widget.ConstraintLayout> + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fitsSystemWindows="true"> + + <com.google.android.material.appbar.CollapsingToolbarLayout + style="?attr/collapsingToolbarLayoutLargeStyle" + android:layout_width="match_parent" + android:layout_height="?attr/collapsingToolbarLayoutLargeSize" + app:contentScrim="?attr/colorPrimary" + app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" + tools:title="Way to go, Adam!"> + + <com.google.android.material.appbar.MaterialToolbar + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:elevation="0dp" + app:layout_collapseMode="pin" + app:menu="@menu/account_edit" /> + + </com.google.android.material.appbar.CollapsingToolbarLayout> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/name" + android:layout_width="300dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:hint="@string/name" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </com.google.android.material.textfield.TextInputLayout> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/matrix" + android:layout_width="300dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:hint="@string/matrix_handle" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/name"> + + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </com.google.android.material.textfield.TextInputLayout> + + <Button + android:id="@+id/outlinedButton" + style="@style/Widget.Material3.Button.TextButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:text="@string/resend_verification_code" + app:layout_constraintEnd_toEndOf="@+id/matrix" + app:layout_constraintTop_toBottomOf="@+id/matrix" /> + </androidx.constraintlayout.widget.ConstraintLayout> +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/activity_feed_chooser.xml b/app/src/main/res/layout/activity_feed_chooser.xml index 6c1203c951164d69fce52f6ab6ba8030869cf919..185ec670caea8124a3461672b379a839a7e80889 100644 --- a/app/src/main/res/layout/activity_feed_chooser.xml +++ b/app/src/main/res/layout/activity_feed_chooser.xml @@ -6,97 +6,107 @@ SPDX-License-Identifier: GPL-3.0-or-later --> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tool="http://schemas.android.com/tools" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tool:context="xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity"> + tools:context="xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fitsSystemWindows="true"> + + <com.google.android.material.appbar.MaterialToolbar + android:id="@+id/topAppBar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + app:menu="@menu/feeds_menu" + app:title="@string/title_cities" > + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_height="wrap_content" + android:visibility="gone" + /> + </com.google.android.material.appbar.MaterialToolbar> + + </com.google.android.material.appbar.AppBarLayout> <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/feeds_overlay" android:layout_width="match_parent" android:layout_height="match_parent"> - <com.google.android.material.progressindicator.CircularProgressIndicator - android:id="@+id/progress" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:indeterminate="true" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/feeds_overlay" + android:layout_width="match_parent" + android:layout_height="match_parent"> - <ImageView - android:id="@+id/error_image" - android:layout_width="92dp" - android:layout_height="92dp" + <com.google.android.material.progressindicator.CircularProgressIndicator + android:id="@+id/progress" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:indeterminate="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/error_image" + android:layout_width="92dp" + android:layout_height="92dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:ignore="ContentDescription" + tools:src="@drawable/error_net" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/error_text" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/error_image" + tools:text="No connection" /> + </androidx.constraintlayout.widget.ConstraintLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/results_recycler" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:layout_marginBottom="8dp" android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" + app:layout_constraintBottom_toTopOf="@+id/button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - tool:ignore="ContentDescription" - tool:src="@drawable/error_net" /> + app:layout_constraintTop_toTopOf="parent" /> - <com.google.android.material.textview.MaterialTextView - android:id="@+id/error_text" - android:layout_width="0dp" + <Button + android:id="@+id/button" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="8dp" android:layout_marginEnd="16dp" - android:textAlignment="center" - android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + android:layout_marginBottom="16dp" + android:text="@string/save" android:visibility="gone" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/error_image" - tool:text="No connection" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/search_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:hint="@string/filter_localities" - android:visibility="gone" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - - <com.google.android.material.textfield.TextInputEditText - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - </com.google.android.material.textfield.TextInputLayout> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/results_recycler" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:visibility="gone" - app:layout_behavior="@string/appbar_scrolling_view_behavior" - app:layout_constraintBottom_toTopOf="@+id/button" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/search_bar" /> - - <Button - android:id="@+id/button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="16dp" - android:layout_marginBottom="16dp" - android:text="@string/save" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file +</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml index 35dc2687c8efce3fa3babc4e1486026d8c6e05c5..dc3a1d72dbf4dd6190d42ec6984161a265996cbe 100644 --- a/app/src/main/res/layout/activity_onboarding.xml +++ b/app/src/main/res/layout/activity_onboarding.xml @@ -1,65 +1,32 @@ <?xml version="1.0" encoding="utf-8"?> - -<!-- -SPDX-FileCopyrightText: Adam Evyčędo - -SPDX-License-Identifier: GPL-3.0-or-later ---> - <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tool="http://schemas.android.com/tools" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" - tool:context="xyz.apiote.bimba.czwek.onboarding.OnboardingActivity"> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline2" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="horizontal" - app:layout_constraintGuide_percent=".125" /> + android:layout_height="match_parent"> - <com.google.android.material.textview.MaterialTextView - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:text="@string/onboarding_question" - android:textAlignment="center" - android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium" + <com.google.android.material.imageview.ShapeableImageView + android:id="@+id/logo" + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_marginTop="32dp" + android:background="@color/bimba_grey" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/guideline2" /> + app:layout_constraintTop_toTopOf="parent" + app:shapeAppearanceOverlay="@style/roundedImageView" + app:srcCompat="@drawable/ic_launcher_foreground" /> - <Button - android:id="@+id/button_simple" - style="?attr/materialButtonOutlinedStyle" - android:layout_width="200dp" - android:layout_height="100dp" - android:layout_marginBottom="16dp" - app:cornerRadius="10dp" - app:layout_constraintBottom_toTopOf="@+id/guideline" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline" + <com.google.android.material.textview.MaterialTextView + android:id="@+id/app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="horizontal" - app:layout_constraintGuide_percent=".5" /> - - <Button - android:id="@+id/button_advanced" - style="?attr/materialButtonOutlinedStyle" - android:layout_width="200dp" - android:layout_height="100dp" android:layout_marginTop="16dp" - app:cornerRadius="10dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/guideline" /> + android:text="@string/app_name" + android:textAppearance="@style/TextAppearance.AppCompat.Display1" + app:layout_constraintEnd_toEndOf="@+id/logo" + app:layout_constraintStart_toStartOf="@+id/logo" + app:layout_constraintTop_toBottomOf="@+id/logo" /> <com.google.android.material.textview.MaterialTextView android:layout_width="0dp" @@ -74,4 +41,45 @@ android:textStyle="italic" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/server" + android:layout_width="400dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="64dp" + android:layout_marginEnd="16dp" + android:hint="@string/bimba_server_address_hint" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/app_name"> + + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="bimba.apiote.xyz" + tools:ignore="HardcodedText" /> + + </com.google.android.material.textfield.TextInputLayout> + + <Button + android:id="@+id/account_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="64dp" + android:text="@string/log_in_or_sign_up" + app:layout_constraintEnd_toEndOf="@+id/server" + app:layout_constraintStart_toStartOf="@+id/server" + app:layout_constraintTop_toBottomOf="@+id/server" /> + + <Button + android:id="@+id/anonymous_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:text="@string/continue_without_account" + app:layout_constraintEnd_toEndOf="@+id/account_button" + app:layout_constraintStart_toStartOf="@+id/account_button" + app:layout_constraintTop_toBottomOf="@+id/account_button" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/login.xml b/app/src/main/res/layout/login.xml deleted file mode 100644 index dc3a1d72dbf4dd6190d42ec6984161a265996cbe..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/login.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <com.google.android.material.imageview.ShapeableImageView - android:id="@+id/logo" - android:layout_width="100dp" - android:layout_height="100dp" - android:layout_marginTop="32dp" - android:background="@color/bimba_grey" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:shapeAppearanceOverlay="@style/roundedImageView" - app:srcCompat="@drawable/ic_launcher_foreground" /> - - <com.google.android.material.textview.MaterialTextView - android:id="@+id/app_name" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="16dp" - android:text="@string/app_name" - android:textAppearance="@style/TextAppearance.AppCompat.Display1" - app:layout_constraintEnd_toEndOf="@+id/logo" - app:layout_constraintStart_toStartOf="@+id/logo" - app:layout_constraintTop_toBottomOf="@+id/logo" /> - - <com.google.android.material.textview.MaterialTextView - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="16dp" - android:text="@string/seatbelts_everyone" - android:textAlignment="center" - android:textAppearance="@style/TextAppearance.Material3.BodySmall" - android:textStyle="italic" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/server" - android:layout_width="400dp" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="64dp" - android:layout_marginEnd="16dp" - android:hint="@string/bimba_server_address_hint" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/app_name"> - - <com.google.android.material.textfield.TextInputEditText - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="bimba.apiote.xyz" - tools:ignore="HardcodedText" /> - - </com.google.android.material.textfield.TextInputLayout> - - <Button - android:id="@+id/account_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="64dp" - android:text="@string/log_in_or_sign_up" - app:layout_constraintEnd_toEndOf="@+id/server" - app:layout_constraintStart_toStartOf="@+id/server" - app:layout_constraintTop_toBottomOf="@+id/server" /> - - <Button - android:id="@+id/anonymous_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="16dp" - android:text="@string/continue_without_account" - app:layout_constraintEnd_toEndOf="@+id/account_button" - app:layout_constraintStart_toStartOf="@+id/account_button" - app:layout_constraintTop_toBottomOf="@+id/account_button" /> - -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/menu/account.xml b/app/src/main/res/menu/account.xml new file mode 100644 index 0000000000000000000000000000000000000000..fc3b526989d14d93d2619016ddafe280fbb33d60 --- /dev/null +++ b/app/src/main/res/menu/account.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/edit" + android:icon="@drawable/edit" + android:title="@string/edit" + app:showAsAction="ifRoom" /> + <item + android:id="@+id/logout" + android:icon="@drawable/logout" + android:title="@string/log_out" + app:showAsAction="ifRoom" /> +</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/account_edit.xml b/app/src/main/res/menu/account_edit.xml new file mode 100644 index 0000000000000000000000000000000000000000..960bf340e27c216bd3f962889429766ecce83464 --- /dev/null +++ b/app/src/main/res/menu/account_edit.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/save" + android:icon="@drawable/checkmark" + android:title="@string/save" + app:showAsAction="ifRoom" /> +</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/drawer.xml b/app/src/main/res/menu/drawer.xml index 5a5194c75d78419d3249ea66b2dc7a1e1354d202..26110bf2cbf93264d7add29c4011b2d9d7143670 100644 --- a/app/src/main/res/menu/drawer.xml +++ b/app/src/main/res/menu/drawer.xml @@ -12,10 +12,10 @@ android:id="@+id/drawer_feeds" android:title="@string/title_feeds"> <menu> <item - android:id="@+id/drawer_servers" + android:id="@+id/drawer_account" android:checkable="true" - android:icon="@drawable/feeds_servers" - android:title="@string/title_servers" /> + android:icon="@drawable/account" + android:title="@string/title_account" /> <item android:id="@+id/drawer_cities" android:checkable="true" diff --git a/app/src/main/res/menu/feeds_menu.xml b/app/src/main/res/menu/feeds_menu.xml new file mode 100644 index 0000000000000000000000000000000000000000..bc87c01e295ede32e965dc043da89413cc2cefc3 --- /dev/null +++ b/app/src/main/res/menu/feeds_menu.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/server" + android:icon="@drawable/feeds_servers" + android:title="@string/title_servers" + app:showAsAction="ifRoom" /> + <item + android:id="@+id/filter" + android:icon="@drawable/filter" + android:title="@string/title_filter" + app:showAsAction="ifRoom" /> +</menu> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78ddc5284daf508032464dfe9be1bb7066e450c2..d3cb71f422f0093ed7e5c8c2bc6768a53b46f8a4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -287,4 +287,14 @@ link to Matrix channel <string name="email_button_description">link to email</string> <string name="log_in_or_sign_up">Log in or Sign up</string> <string name="continue_without_account">Continue without account</string> + <string name="open_browser_to_edit_identity">open browser to edit identity</string> + <string name="edit">Edit</string> + <string name="log_out">Log out</string> + <string name="matrix_handle">Matrix handle</string> + <string name="subscription">Subscription</string> + <string name="logged_in_as">Logged in as</string> + <string name="using">Using</string> + <string name="name">Name</string> + <string name="resend_verification_code">Resend verification code</string> + <string name="title_account">Account</string> </resources>