From 271e6f569ef0332d5a39095ba36ebbaee687996a Mon Sep 17 00:00:00 2001 From: Sarto Date: Fri, 3 Apr 2026 22:08:54 +0330 Subject: [PATCH] Implement profiles management and settings API - Added Profile and ProfileList structs to manage user profiles with unique IDs and nicknames. - Introduced endpoints for CRUD operations on profiles: `/api/profiles` for managing profiles and `/api/profiles/switch` for switching active profiles. - Implemented settings management with an endpoint `/api/settings` to handle user preferences like font size and debug mode. - Enhanced the server to load and save profiles from a `profiles.json` file. - Updated the fetcher initialization to respect the active profile's configuration. - Added comprehensive end-to-end tests for profiles and settings APIs to ensure functionality and persistence. --- .../java/com/thefeed/android/MainActivity.kt | 6 +- internal/client/resolver.go | 10 + internal/web/static/index.html | 2040 +++++++---------- internal/web/web.go | 317 ++- test/e2e/e2e_test.go | 302 ++- 5 files changed, 1505 insertions(+), 1170 deletions(-) diff --git a/android/app/src/main/java/com/thefeed/android/MainActivity.kt b/android/app/src/main/java/com/thefeed/android/MainActivity.kt index c858a81..3a2a53c 100644 --- a/android/app/src/main/java/com/thefeed/android/MainActivity.kt +++ b/android/app/src/main/java/com/thefeed/android/MainActivity.kt @@ -65,7 +65,7 @@ class MainActivity : ComponentActivity() { webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { if (url != null && url.startsWith("http://127.0.0.1")) { - txtStatus.text = "Connected" + txtStatus.text = "" retryCount = 0 } } @@ -128,7 +128,7 @@ class MainActivity : ComponentActivity() { companion object { private const val MAX_RETRIES = 25 - private const val RETRY_DELAY_MS = 2000L - private const val INITIAL_DELAY_MS = 5000L + private const val RETRY_DELAY_MS = 10000L + private const val INITIAL_DELAY_MS = 15000L } } diff --git a/internal/client/resolver.go b/internal/client/resolver.go index 9cbd4ca..ab6a3b5 100644 --- a/internal/client/resolver.go +++ b/internal/client/resolver.go @@ -42,8 +42,18 @@ func (rc *ResolverChecker) SetLogFunc(fn LogFunc) { // An initial check runs immediately; subsequent checks happen every 10 minutes. // ctx controls the lifetime — cancel it to stop the checker. func (rc *ResolverChecker) Start(ctx context.Context) { + rc.StartAndNotify(ctx, nil) +} + +// StartAndNotify is like Start but calls onFirstDone (if non-nil) after the +// initial health-check pass finishes, before the periodic ticker begins. +// This lets callers sequence "DNS scan → metadata fetch" without races. +func (rc *ResolverChecker) StartAndNotify(ctx context.Context, onFirstDone func()) { go func() { rc.CheckNow() + if onFirstDone != nil { + onFirstDone() + } ticker := time.NewTicker(30 * time.Minute) defer ticker.Stop() for { diff --git a/internal/web/static/index.html b/internal/web/static/index.html index 8f4907f..e1a038a 100644 --- a/internal/web/static/index.html +++ b/internal/web/static/index.html @@ -1,1222 +1,950 @@ - + - - - thefeed - +::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px} + -
-
- -

thefeed

- - - -
-
- - -
+
+ + +