diff --git a/app/src/main/assets/sync.js b/app/src/main/assets/sync.js
index 8f2606e4..db9a977e 100644
--- a/app/src/main/assets/sync.js
+++ b/app/src/main/assets/sync.js
@@ -15,22 +15,19 @@ window.loggedIn = async () => {
let localList = null;
async function openLocal() {
// Get the list of local folders for next screen
- (async () => {
- const res = await fetch("http://127.0.0.1/api/config/local-folders");
- localList = await res.json();
+ localList = JSON.parse(window.nativex?.configGetLocalFolders());
- // Add HTML for folders list
- document.getElementById("folder-list").innerHTML = localList
- .map(
- (folder) => `
-
-
-
-
- `
- )
- .join("");
- })();
+ // Add HTML for folders list
+ document.getElementById("folder-list").innerHTML = localList
+ .map(
+ (folder) => `
+
+
+
+
+ `
+ )
+ .join("");
// Show the folders list
sync.classList.add("invisible");
diff --git a/app/src/main/java/gallery/memories/MainActivity.kt b/app/src/main/java/gallery/memories/MainActivity.kt
index f418a81c..c8f14ffa 100644
--- a/app/src/main/java/gallery/memories/MainActivity.kt
+++ b/app/src/main/java/gallery/memories/MainActivity.kt
@@ -189,23 +189,9 @@ class MainActivity : AppCompatActivity() {
}
fun loadDefaultUrl(): Boolean {
- // Load accounts
- val authHeader = nativex.account.authHeader
- val memoriesUrl = nativex.account.memoriesUrl
-
// Load app interface if authenticated
- if (authHeader != null && memoriesUrl != null) {
- // Get host name
- host = Uri.parse(memoriesUrl).host
-
- // Set authorization header
- binding.webview.loadUrl(
- memoriesUrl, mapOf(
- "Authorization" to authHeader
- )
- )
- return true
- }
+ host = nativex.http.loadWebView(binding.webview)
+ if (host != null) return true
// Load welcome page
binding.webview.loadUrl("file:///android_asset/welcome.html");
diff --git a/app/src/main/java/gallery/memories/NativeX.kt b/app/src/main/java/gallery/memories/NativeX.kt
index ae9df528..743ec29d 100644
--- a/app/src/main/java/gallery/memories/NativeX.kt
+++ b/app/src/main/java/gallery/memories/NativeX.kt
@@ -10,19 +10,22 @@ import android.widget.Toast
import androidx.media3.common.util.UnstableApi
import gallery.memories.service.AccountService
import gallery.memories.service.DownloadService
+import gallery.memories.service.HttpService
import gallery.memories.service.ImageService
import gallery.memories.service.TimelineQuery
import org.json.JSONArray
import java.io.ByteArrayInputStream
import java.net.URLDecoder
-@UnstableApi class NativeX(private val mCtx: MainActivity) {
+@UnstableApi
+class NativeX(private val mCtx: MainActivity) {
val TAG = NativeX::class.java.simpleName
private var themeStored = false
val query = TimelineQuery(mCtx)
val image = ImageService(mCtx, query)
- val account = AccountService(mCtx)
+ val http = HttpService()
+ val account = AccountService(mCtx, http)
init {
dlService = DownloadService(mCtx, query)
@@ -60,7 +63,7 @@ import java.net.URLDecoder
@JavascriptInterface
fun setThemeColor(color: String?, isDark: Boolean) {
// Save for getting it back on next start
- if (!themeStored && account.authHeader != null) {
+ if (!themeStored && http.isLoggedIn()) {
themeStored = true
mCtx.storeTheme(color, isDark);
}
@@ -162,9 +165,15 @@ import java.net.URLDecoder
"GET" -> {
routerGet(request)
}
+
"OPTIONS" -> {
- WebResourceResponse("text/plain", "UTF-8", ByteArrayInputStream("".toByteArray()))
+ WebResourceResponse(
+ "text/plain",
+ "UTF-8",
+ ByteArrayInputStream("".toByteArray())
+ )
}
+
else -> {
throw Exception("Method Not Allowed")
}
@@ -200,7 +209,12 @@ import java.net.URLDecoder
} else if (path.matches(API.IMAGE_INFO)) {
makeResponse(query.getImageInfo(parts[4].toLong()))
} else if (path.matches(API.IMAGE_DELETE)) {
- makeResponse(query.delete(parseIds(parts[4]), request.url.getBooleanQueryParameter("dry", false)))
+ makeResponse(
+ query.delete(
+ parseIds(parts[4]),
+ request.url.getBooleanQueryParameter("dry", false)
+ )
+ )
} else if (path.matches(API.IMAGE_PREVIEW)) {
makeResponse(image.getPreview(parts[3].toLong()), "image/jpeg")
} else if (path.matches(API.IMAGE_FULL)) {
@@ -227,7 +241,11 @@ import java.net.URLDecoder
}
private fun makeErrorResponse(): WebResourceResponse {
- val response = WebResourceResponse("application/json", "UTF-8", ByteArrayInputStream("{}".toByteArray()))
+ val response = WebResourceResponse(
+ "application/json",
+ "UTF-8",
+ ByteArrayInputStream("{}".toByteArray())
+ )
response.setStatusCodeAndReasonPhrase(500, "Internal Server Error")
return response
}
diff --git a/app/src/main/java/gallery/memories/service/AccountService.kt b/app/src/main/java/gallery/memories/service/AccountService.kt
index 54a3fb37..b59f73aa 100644
--- a/app/src/main/java/gallery/memories/service/AccountService.kt
+++ b/app/src/main/java/gallery/memories/service/AccountService.kt
@@ -2,7 +2,6 @@ package gallery.memories.service
import android.content.Intent
import android.net.Uri
-import android.util.Base64
import android.util.Log
import android.widget.Toast
import androidx.media3.common.util.UnstableApi
@@ -18,14 +17,11 @@ import org.json.JSONObject
import java.net.SocketTimeoutException
@UnstableApi
-class AccountService(private val mCtx: MainActivity) {
+class AccountService(private val mCtx: MainActivity, private val mHttp: HttpService) {
companion object {
val TAG = AccountService::class.java.simpleName
}
- var authHeader: String? = null
- var memoriesUrl: String? = null
-
/**
* Login to a server
* @param baseUrl The base URL of the server
@@ -151,54 +147,45 @@ class AccountService(private val mCtx: MainActivity) {
* Makes a toast to the user if something is wrong
*/
fun checkCredentialsAndVersion() {
- if (memoriesUrl == null) return
+ if (mHttp.isLoggedIn()) return
- val request = Request.Builder()
- .url(memoriesUrl + "api/describe")
- .get()
- .header("Authorization", authHeader ?: "")
- .build()
-
- val response: Response
try {
- response = OkHttpClient().newCall(request).execute()
+ val response = mHttp.getApiDescription()
+ val body = mHttp.bodyJson(response)
+
+ // Check status code
+ if (response.code == 401) {
+ return loggedOut()
+ }
+
+ // Could not connect to memories
+ if (response.code == 404) {
+ return toast(mCtx.getString(R.string.err_no_ver))
+ }
+
+ // Check body
+ if (body == null || response.code != 200) {
+ toast(mCtx.getString(R.string.err_no_describe))
+ return
+ }
+
+ // Get body values
+ val uid = body.get("uid")
+ val version = body.getString("version")
+
+ // Check UID exists
+ if (uid.equals(null)) {
+ return loggedOut()
+ }
+
+ // Check minimum version
+ if (Version(version) < Version(mCtx.getString(R.string.min_server_version))) {
+ return toast(mCtx.getString(R.string.err_no_ver))
+ }
} catch (e: Exception) {
Log.w(TAG, "checkCredentialsAndVersion: ", e)
return
}
-
- val body = response.body?.string()
- response.body?.close()
-
- // Check status code
- if (response.code == 401) {
- return loggedOut()
- }
-
- // Could not connect to memories
- if (response.code == 404) {
- return toast(mCtx.getString(R.string.err_no_ver))
- }
-
- // Check body
- if (body == null || response.code != 200) {
- toast(mCtx.getString(R.string.err_no_describe))
- return
- }
-
- val json = JSONObject(body)
- val version = json.getString("version")
- val uid = json.get("uid")
-
- // Check UID exists
- if (uid.equals(null) && authHeader != null) {
- return loggedOut()
- }
-
- // Check minimum version
- if (Version(version) < Version(mCtx.getString(R.string.min_server_version))) {
- return toast(mCtx.getString(R.string.err_no_ver))
- }
}
/**
@@ -224,8 +211,8 @@ class AccountService(private val mCtx: MainActivity) {
.putString("user", user)
.putString("password", password)
.apply()
- memoriesUrl = url
- setAuthHeader(Pair(user, password))
+ mHttp.setBaseUrl(url)
+ mHttp.setAuthHeader(Pair(user, password))
}
/**
@@ -234,7 +221,7 @@ class AccountService(private val mCtx: MainActivity) {
*/
fun getCredentials(): Pair? {
val prefs = mCtx.getSharedPreferences("credentials", 0)
- memoriesUrl = prefs.getString("memoriesUrl", null)
+ mHttp.setBaseUrl(prefs.getString("memoriesUrl", null))
val user = prefs.getString("user", null)
val password = prefs.getString("password", null)
if (user == null || password == null) return null
@@ -245,8 +232,8 @@ class AccountService(private val mCtx: MainActivity) {
* Delete the stored credentials
*/
fun deleteCredentials() {
- authHeader = null
- memoriesUrl = null
+ mHttp.setAuthHeader(null)
+ mHttp.setBaseUrl(null)
mCtx.getSharedPreferences("credentials", 0).edit()
.remove("memoriesUrl")
.remove("user")
@@ -258,20 +245,7 @@ class AccountService(private val mCtx: MainActivity) {
* Refresh the authorization header
*/
fun refreshAuthHeader() {
- setAuthHeader(getCredentials())
- }
-
- /**
- * Set the authorization header
- * @param credentials The credentials to use
- */
- private fun setAuthHeader(credentials: Pair?) {
- if (credentials != null) {
- val auth = "${credentials.first}:${credentials.second}"
- authHeader = "Basic ${Base64.encodeToString(auth.toByteArray(), Base64.NO_WRAP)}"
- return
- }
- authHeader = null
+ mHttp.setAuthHeader(getCredentials())
}
/**