From 447a05ee58d0ce9668b3a327e2d040bc2a61bc49 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Fri, 15 Aug 2025 23:55:50 -0700 Subject: [PATCH 1/5] Update Layouts and URL Parsing --- .../djangofiles/djangofiles/MainActivity.kt | 38 +-- .../djangofiles/ui/login/LoginFragment.kt | 72 ++++- .../main/res/layout/fragment_authorize.xml | 235 ++++++++-------- app/src/main/res/layout/fragment_login.xml | 109 +++++--- .../main/res/layout/fragment_login_two.xml | 254 +++++++++--------- app/src/main/res/layout/nav_header_main.xml | 3 +- 6 files changed, 388 insertions(+), 323 deletions(-) diff --git a/app/src/main/java/com/djangofiles/djangofiles/MainActivity.kt b/app/src/main/java/com/djangofiles/djangofiles/MainActivity.kt index aa0d30f..bc61edf 100644 --- a/app/src/main/java/com/djangofiles/djangofiles/MainActivity.kt +++ b/app/src/main/java/com/djangofiles/djangofiles/MainActivity.kt @@ -58,8 +58,8 @@ import com.djangofiles.djangofiles.work.DailyWorker import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.io.File -import java.net.URL import java.util.UUID import java.util.concurrent.TimeUnit @@ -202,12 +202,14 @@ class MainActivity : AppCompatActivity() { window.setNavigationBarContrastEnforced(false) } - // Set Nav Header Top Padding + // Update Header Padding val headerView = binding.navView.getHeaderView(0) - ViewCompat.setOnApplyWindowInsetsListener(headerView) { v, insets -> - val bars = insets.getInsets(WindowInsetsCompat.Type.statusBars()) - Log.d("ViewCompat", "top: ${bars.top}") - v.updatePadding(top = bars.top) + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets -> + val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + Log.d("ViewCompat", "binding.root: top: ${bars.top}") + if (bars.top > 0) { + headerView.updatePadding(top = bars.top) + } insets } @@ -418,8 +420,8 @@ class MainActivity : AppCompatActivity() { Log.d("onNewIntent", "SEND TEXT DETECTED") //if (extraText.lowercase().startsWith("http")) { //if (Patterns.WEB_URL.matcher(extraText).matches()) { - if (isURL(extraText)) { - Log.d("onNewIntent", "URL DETECTED: $extraText") + if (isTextUrl(extraText)) { + Log.i("onNewIntent", "URL DETECTED: $extraText") val bundle = Bundle().apply { putString("url", extraText) } navController.navigate( R.id.nav_item_short, bundle, NavOptions.Builder() @@ -662,6 +664,15 @@ class MainActivity : AppCompatActivity() { } } + private fun isTextUrl(input: String): Boolean { + val url = input.toHttpUrlOrNull() ?: return false + if (input != url.toString()) return false + if (url.scheme !in listOf("http", "https")) return false + if (url.host.isBlank()) return false + if (url.toString().length > 2048) return false + return true + } + fun setDrawerLockMode(enabled: Boolean) { Log.d("setDrawerLockMode", "enabled: $enabled") val lockMode = @@ -709,14 +720,3 @@ fun copyToClipboard(context: Context, text: String, msg: String? = null) { clipboard.setPrimaryClip(clip) Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } - -fun isURL(url: String): Boolean { - return try { - URL(url) - Log.d("isURL", "TRUE") - true - } catch (_: Exception) { - Log.d("isURL", "FALSE") - false - } -} diff --git a/app/src/main/java/com/djangofiles/djangofiles/ui/login/LoginFragment.kt b/app/src/main/java/com/djangofiles/djangofiles/ui/login/LoginFragment.kt index 5d8b475..7044cf9 100644 --- a/app/src/main/java/com/djangofiles/djangofiles/ui/login/LoginFragment.kt +++ b/app/src/main/java/com/djangofiles/djangofiles/ui/login/LoginFragment.kt @@ -18,11 +18,11 @@ import androidx.navigation.fragment.findNavController import com.djangofiles.djangofiles.R import com.djangofiles.djangofiles.ServerApi import com.djangofiles.djangofiles.databinding.FragmentLoginBinding -import com.djangofiles.djangofiles.isURL import com.google.android.material.bottomnavigation.BottomNavigationView import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class LoginFragment : Fragment() { @@ -92,7 +92,10 @@ class LoginFragment : Fragment() { binding.hostnameText.setSelection(binding.hostnameText.text.length) } Log.d("loginFunction", "host: $host") - if (!isURL(host)) { + // TODO: Look into the usage of (host.toHttpUrlOrNull() == null) here. + // NOTE: This seems to be less restrictive so should work and can be improved... + //if (!isURL(host)) { + if (host.toHttpUrlOrNull() == null) { binding.hostnameText.error = "Invalid Hostname" return@OnClickListener } @@ -190,16 +193,63 @@ class LoginFragment : Fragment() { } private fun parseHost(urlString: String): String { - var url = urlString.trim() - if (url.isEmpty()) { + try { + var url = urlString.trim() + if (url.isEmpty()) { + return "" + } + if (!url.lowercase().startsWith("http")) { + url = "https://$url" + } + if (url.toHttpUrlOrNull() == null) { + return url + } + val uri = url.toUri() + Log.d("parseHost", "uri: $uri") + Log.d("parseHost", "uri.scheme: ${uri.scheme}") + if (uri.scheme.isNullOrEmpty()) { + return "https://" + } + Log.d("parseHost", "uri.host: ${uri.host}") + if (uri.host.isNullOrEmpty()) { + return "${uri.scheme}://" + } + Log.d("parseHost", "uri.path: ${uri.path}") + val result = "${uri.scheme}://${uri.host}${uri.path}" + Log.i("parseHost", "result: $result") + return if (result.endsWith("/")) { + result.dropLast(1) + } else { + result + } + } catch (e: Throwable) { + Log.d("parseHost", "Exception: $e") return "" } - if (!url.lowercase().startsWith("http")) { - url = "https://$url" - } - if (url.endsWith("/")) { - url = url.substring(0, url.length - 1) - } - return url } + + //private fun parseHost(urlString: String): String { + // var url = urlString.trim() + // if (url.isEmpty()) { + // return "" + // } + // if (!url.lowercase().startsWith("http")) { + // url = "https://$url" + // } + // if (url.endsWith("/")) { + // url = url.substring(0, url.length - 1) + // } + // return url + //} + + //private fun isURL(url: String): Boolean { + // return try { + // URL(url) + // Log.d("isURL", "TRUE") + // true + // } catch (_: Exception) { + // Log.d("isURL", "FALSE") + // false + // } + //} } diff --git a/app/src/main/res/layout/fragment_authorize.xml b/app/src/main/res/layout/fragment_authorize.xml index ae1b64d..01c32ca 100644 --- a/app/src/main/res/layout/fragment_authorize.xml +++ b/app/src/main/res/layout/fragment_authorize.xml @@ -4,143 +4,138 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:fillViewport="true"> + android:fillViewport="true" + tools:ignore="HardcodedText"> + + - + android:orientation="vertical" + android:gravity="center_horizontal" + android:padding="24dp" + tools:ignore="UselessParent"> + + + + + + - - - + android:visibility="visible" + tools:visibility="visible"> - - + android:indeterminate="true" + app:layout_constraintTop_toTopOf="@+id/refresh_layout" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent" /> + - + - + +