Initial commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# wIRC
|
||||
|
||||
A native Android IRC client: mIRC colors, timestamps, OP powers (kick/ban/op),
|
||||
Ctrl+K/B/I formatting shortcuts, saved servers with on-connect identify
|
||||
commands, and every channel *and* private message opening as its own
|
||||
independently-styled window (1px black border, adjustable background
|
||||
transparency, black/white text toggle).
|
||||
|
||||
## What's built so far (MVP)
|
||||
|
||||
- Raw socket IRC connection (`irc/IrcConnection.kt`) with auto-reconnect/backoff,
|
||||
optional TLS, auto-join on connect.
|
||||
- Full mIRC control-code parser (`irc/MircColorParser.kt`) — colors, bold,
|
||||
underline, reverse, reset — rendered as a Compose `AnnotatedString`.
|
||||
- Protocol line parser (`irc/IrcLineParser.kt`) for PRIVMSG/JOIN/PART/KICK/MODE/
|
||||
TOPIC/NOTICE/QUIT/NAMES.
|
||||
- `ConnectionManager` — app-wide singleton so every open window reads from the
|
||||
same shared state (messages, user list) regardless of which window is active.
|
||||
- `IrcConnectionService` — foreground service that keeps the socket(s) alive
|
||||
when the app is backgrounded (Android kills background network connections
|
||||
aggressively without this).
|
||||
- `ChannelScreen` — the actual window UI: scrollback with mIRC colors + per-line
|
||||
timestamps, input bar, long-press a nick for a Kick/Ban/Op/De-op menu, and a
|
||||
settings panel (gear icon) with the transparency slider and text color toggle.
|
||||
- `ChannelWindowActivity` — one instance per channel. Uses
|
||||
`documentLaunchMode="always"` + `resizeableActivity="true"` in the manifest
|
||||
and `FLAG_ACTIVITY_NEW_DOCUMENT` on launch, which is the standard way an app
|
||||
can offer real independent, draggable/resizable OS-level windows on devices
|
||||
that support freeform multi-window (large tablets, Samsung DeX, etc).
|
||||
- `MainActivity` / `MainScreen` — the main window. Lists saved servers as
|
||||
cards (Connect / Edit / Delete), and per-connected-server a box to join +
|
||||
open a channel window. "+ Add Server" opens `ServerEditDialog` with host,
|
||||
port, TLS, nick, auto-join channels, and a multi-line "on-connect / identify
|
||||
commands" field — e.g. `PRIVMSG NickServ :IDENTIFY hunter2` — sent
|
||||
automatically right after registration on every connect, before auto-join.
|
||||
- `ServerRepository` — persists the saved server list (including on-connect
|
||||
commands) to `servers.json` in app-private storage, so it survives app
|
||||
restarts. This is the "file that saves that information" you asked for.
|
||||
- Private messages: `ConnectionManager` now keys PMs by the *other person's*
|
||||
nick (not our own), and emits a `newQueryBuffers` event the first time a PM
|
||||
from someone new arrives. `IrcConnectionService` listens for that and
|
||||
auto-launches a `ChannelWindowActivity` for it — so a PM pops its own window
|
||||
the same way tapping a channel does, no different from every other window
|
||||
in the app.
|
||||
- Ctrl+K / Ctrl+B / Ctrl+I: hardware-keyboard shortcuts wired into the input
|
||||
field in `ChannelScreen.kt`. Ctrl+B/I insert the raw bold (`\u0002`) /
|
||||
italic (`\u001D`) toggle control chars at the cursor. Ctrl+K opens a 16-swatch
|
||||
mIRC color picker dialog (foreground, then optional background) and inserts
|
||||
the real `\u0003FG,BG` wire code — same bytes mIRC/HexChat send.
|
||||
|
||||
## Known limitations / what's still rough
|
||||
|
||||
- **"Minimize" isn't an app feature** — on devices with freeform multi-window
|
||||
(large tablets, Samsung DeX, etc.) the OS itself draws minimize/maximize/
|
||||
close chrome around any `resizeableActivity="true"` window. Both
|
||||
`MainActivity` and `ChannelWindowActivity` are marked resizable so they get
|
||||
that treatment automatically; there's no button to build on the app side.
|
||||
- **No SASL handshake yet** — `ServerConfig` has `saslUser`/`saslPass` fields
|
||||
but `IrcConnection` only sends `CAP REQ :sasl` and stops there. The
|
||||
"on-connect commands" field is the current way to identify (it just sends a
|
||||
plain `PRIVMSG NickServ :IDENTIFY ...` after registration, which works fine
|
||||
on Rizon/most networks even without real SASL).
|
||||
- **Multi-window is best-effort**, same as before — genuinely dependent on
|
||||
device/OEM support for freeform windowing. This is a platform limitation,
|
||||
not something the app can force.
|
||||
- **No notifications for mentions when a window isn't focused yet.**
|
||||
- **Channel list per server isn't persisted** — only the server configs
|
||||
(including identify commands) are saved; which channels you had open resets
|
||||
each app restart. Worth adding to `ServerRepository` next if it bugs you.
|
||||
|
||||
## Building — Claude Code / PowerShell, no Android Studio
|
||||
|
||||
This project lives at `C:\wallpapers\wIRC`. Since you're picking this up
|
||||
with Claude Code the same way as Cart & Dagger: it needs the Android SDK
|
||||
command-line tools + Gradle, same setup you've already got at
|
||||
`C:\Users\admin\AppData\Local\Android\Sdk`.
|
||||
|
||||
From PowerShell, in `C:\wallpapers\wIRC`:
|
||||
|
||||
```powershell
|
||||
cd C:\wallpapers\wIRC
|
||||
|
||||
# One-time: point Gradle at your existing SDK install
|
||||
$env:ANDROID_HOME = "C:\Users\admin\AppData\Local\Android\Sdk"
|
||||
"sdk.dir=C:\\Users\\admin\\AppData\\Local\\Android\\Sdk" | Out-File -Encoding ascii local.properties
|
||||
|
||||
# Generate the Gradle wrapper jar (not shipped in this zip — it's a binary)
|
||||
# Requires a local Gradle install once, just to bootstrap the wrapper:
|
||||
gradle wrapper --gradle-version 8.9
|
||||
|
||||
# Build
|
||||
.\gradlew.bat assembleDebug
|
||||
```
|
||||
|
||||
The debug APK lands at `C:\wallpapers\wIRC\app\build\outputs\apk\debug\app-debug.apk`.
|
||||
From there, install it the same way you've been doing for Cart & Dagger —
|
||||
`adb install`, or transfer it over your own hosting and install directly on
|
||||
the tablet/phone.
|
||||
|
||||
If Claude Code hits a missing `gradle` command for that one-time wrapper
|
||||
bootstrap, the SDK's `cmdline-tools` don't include Gradle itself — grab it
|
||||
separately (`choco install gradle` if you use Chocolatey, or download the
|
||||
binary distribution and add it to PATH) just for that first `gradle wrapper`
|
||||
call; every build after that uses `.\gradlew.bat` and doesn't need a system
|
||||
Gradle install anymore.
|
||||
|
||||
## Transferring to tablet/phone
|
||||
|
||||
Once you've got an APK (built on the laptop in Android Studio, or later
|
||||
directly on-device via Claude Code in Termux/proot once that's sorted out):
|
||||
|
||||
- Simplest: `adb install app-debug.apk` if the device is plugged in / on the
|
||||
same network with ADB over Wi-Fi enabled.
|
||||
- Or just copy the APK over via your own file transfer (your hosting, a
|
||||
shared folder, whatever you'd normally use) and install it directly on
|
||||
the device — you'll need "install unknown apps" allowed for whichever app
|
||||
you use to open the APK file.
|
||||
|
||||
## Suggested next steps
|
||||
|
||||
1. Wire up persistence for server/channel lists (Room or DataStore) so
|
||||
`MainActivity` remembers your setup between launches.
|
||||
2. Finish SASL PLAIN auth in `IrcConnection`.
|
||||
3. Add a notification path for mentions when a channel window isn't focused.
|
||||
4. Decide on nick auto-complete / tab-complete in the input bar.
|
||||
Reference in New Issue
Block a user