diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-22 11:13:26 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-22 11:13:26 +0200 |
| commit | 9afba17e880840b8d138d1f5906d65afeaf8d5a6 (patch) | |
| tree | 35696b7ab68a2ec55c4749ecfcf1fed549836446 /app/src/main/java/mygram/droid/SetupActivity.java | |
| parent | c222cb8e784d65f17ac29433fe51cd4c56e1b261 (diff) | |
| download | mygram-droid-9afba17e880840b8d138d1f5906d65afeaf8d5a6.tar.gz mygram-droid-9afba17e880840b8d138d1f5906d65afeaf8d5a6.zip | |
Add LAN discovery and instance picker
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'app/src/main/java/mygram/droid/SetupActivity.java')
| -rw-r--r-- | app/src/main/java/mygram/droid/SetupActivity.java | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/app/src/main/java/mygram/droid/SetupActivity.java b/app/src/main/java/mygram/droid/SetupActivity.java index ef1f68c..106ec9c 100644 --- a/app/src/main/java/mygram/droid/SetupActivity.java +++ b/app/src/main/java/mygram/droid/SetupActivity.java @@ -15,6 +15,112 @@ package mygram.droid; import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.text.InputType; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; +import java.util.LinkedHashMap; +import java.util.Map; + +/** Instance picker: LAN scan, manual URL, then the password when the instance asks for one. */ public final class SetupActivity extends Activity { + private LinearLayout box; + + @Override + protected void onCreate(Bundle state) { + super.onCreate(state); + box = Ui.column(this); + setContentView(box); + scan(); + } + + private void scan() { + reset("Searching the network for Foldergram…"); + Api.async(() -> { + Map<String, String> found = new LinkedHashMap<>(); + String self = Discovery.localIpv4(this); + if (self != null) + for (String base : Discovery.scan(self)) + found.put(base, Discovery.label(base)); + return found; + }, this::found, e -> { + reset("Scan failed: " + e.getMessage()); + actions(); + }); + } + + private void found(Map<String, String> instances) { + reset(instances.isEmpty() ? "No Foldergram found on port " + Discovery.PORT : "Choose an instance"); + for (Map.Entry<String, String> e : instances.entrySet()) { + TextView t = Ui.text(this, e.getValue(), 20); + int p = Ui.dp(this, 12); + t.setPadding(p * 2, p, p * 2, p); + Ui.focusable(t); + t.setOnClickListener(v -> choose(e.getKey())); + box.addView(t); + } + actions(); + box.getChildAt(1).requestFocus(); + } + + private void actions() { + LinearLayout row = Ui.row(this); + row.addView(Ui.iconButton(this, R.drawable.ic_refresh, "Rescan", v -> scan())); + row.addView(Ui.iconButton(this, R.drawable.ic_edit, "Enter URL", v -> manual())); + box.addView(row); + } + + private void manual() { + reset("Instance URL"); + EditText url = Ui.field(this, "http://host:" + Discovery.PORT, + InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); + box.addView(url); + box.addView(Ui.iconButton(this, R.drawable.ic_check, "Connect", + v -> choose(Api.normalize(url.getText().toString())))); + url.requestFocus(); + } + + private void choose(String base) { + reset("Connecting to " + base + "…"); + Api.async(() -> Api.authStatus(base), status -> { + if ("public".equals(status.optString("accessMode"))) + save(base, ""); + else + password(base); + }, e -> { + reset("Cannot reach " + base + ": " + e.getMessage()); + actions(); + }); + } + + private void password(String base) { + reset("Viewer password for " + base); + EditText pw = Ui.field(this, "Password", Ui.password()); + box.addView(pw); + box.addView(Ui.iconButton(this, R.drawable.ic_check, "Log in", v -> { + String s = pw.getText().toString(); + Api.async(() -> { + Api.login(base, s); + return true; + }, ok -> save(base, s), e -> Toast.makeText(this, + e instanceof Api.HttpError && ((Api.HttpError) e).code == 401 ? "Wrong password" : e.getMessage(), + Toast.LENGTH_LONG).show()); + })); + pw.requestFocus(); + } + + private void save(String base, String password) { + Prefs.setServer(base, password); + startActivity(new Intent(this, MainActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)); + } + + private void reset(String title) { + box.removeAllViews(); + box.addView(Ui.text(this, title, 24)); + } } |
