No description
  • TypeScript 85.8%
  • Objective-C++ 7.2%
  • Swift 5.3%
  • C++ 1.1%
  • Kotlin 0.2%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
yuk1n0w eae891c5f0 feat: choose the /translate language, chat runs under the toolbar and composer, hover bar stays reachable, code messages get a bubble
- Translation language: per-conversation language menu (composer, header, draft sheet), /translate picks the language, saved choice, Swift preference whitelist.
- Layout: the timeline fills the pane and scrolls under the native toolbar and the composer (edge fade), so the glass has content to show through.
- Hover bar: each bubble row owns its whole line and the ground under its action pill; rows tile so the pill never sits in another row's hover area.
- Messages with code report their bubble as fitted, so they get glass like the rest.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-17 20:31:32 +01:00
__tests__ feat: choose the /translate language, chat runs under the toolbar and composer, hover bar stays reachable, code messages get a bubble 2026-10-17 20:31:32 +01:00
android feat(android): add secure credential vault foundation 2026-10-08 11:08:19 -04:00
assets feat(commands): slash commands in threads and forum posts, and /nick 2026-10-11 13:21:08 +01:00
ios Initial import 2026-10-07 08:36:06 +01:00
macos feat: choose the /translate language, chat runs under the toolbar and composer, hover bar stays reachable, code messages get a bubble 2026-10-17 20:31:32 +01:00
scripts feat(macos): chat parity, app actions, file paste and drop, composer input fix 2026-10-10 17:21:31 +01:00
src feat: choose the /translate language, chat runs under the toolbar and composer, hover bar stays reachable, code messages get a bubble 2026-10-17 20:31:32 +01:00
windows feat(windows): scaffold React Native Windows desktop target 2026-10-08 12:33:57 -04:00
.eslintignore Initial import 2026-10-07 08:36:06 +01:00
.eslintrc.js Initial import 2026-10-07 08:36:06 +01:00
.gitignore Initial import 2026-10-07 08:36:06 +01:00
.prettierrc.js Initial import 2026-10-07 08:36:06 +01:00
.watchmanconfig Initial import 2026-10-07 08:36:06 +01:00
app.json Initial import 2026-10-07 08:36:06 +01:00
App.tsx feat(macos): chat parity, app actions, file paste and drop, composer input fix 2026-10-10 17:21:31 +01:00
babel.config.js Initial import 2026-10-07 08:36:06 +01:00
Gemfile Initial import 2026-10-07 08:36:06 +01:00
Gemfile.lock Initial import 2026-10-07 08:36:06 +01:00
index.js Initial import 2026-10-07 08:36:06 +01:00
jest.cleanup.js Initial import 2026-10-07 08:36:06 +01:00
jest.config.js Initial import 2026-10-07 08:36:06 +01:00
jest.config.windows.js feat(windows): scaffold React Native Windows desktop target 2026-10-08 12:33:57 -04:00
jest.setup.js Initial import 2026-10-07 08:36:06 +01:00
metro.config.js feat(windows): scaffold React Native Windows desktop target 2026-10-08 12:33:57 -04:00
NuGet.config feat(windows): scaffold React Native Windows desktop target 2026-10-08 12:33:57 -04:00
package-lock.json feat(windows): scaffold React Native Windows desktop target 2026-10-08 12:33:57 -04:00
package.json feat(windows): scaffold React Native Windows desktop target 2026-10-08 12:33:57 -04:00
PORTING_PLAN.md docs: add Android and desktop porting plan 2026-10-08 10:56:40 -04:00
README.md feat(macos): chat parity, app actions, file paste and drop, composer input fix 2026-10-10 17:21:31 +01:00
THIRD_PARTY_NOTICES.md Initial import 2026-10-07 08:36:06 +01:00
tsconfig.json Initial import 2026-10-07 08:36:06 +01:00

Ancord

Ancord is the start of an independent Android and macOS client shaped by SakuraCord's design language. It uses React Native 0.81.6 with Microsoft's React Native macOS 0.81.8. The macOS preview follows SakuraCord's direct-message and server-channel layout; Android still uses the initial server and channel preview.

Ancord includes an offline sample workspace on both platforms and a connected account path on macOS. When signed out, macOS uses SakuraCord’s synthetic direct messages, guilds, channels, members, and artwork. With a saved account, it restores the account through the native credential vault and Gateway-first provider, loads the REST workspace, and applies live Gateway updates. Text and announcement channels have ordinary message rows (consecutive messages from one person share an avatar within a configurable interval, and joins, calls, pins, and boosts read as notices), channel introductions, and role-grouped members. A one-to-one conversation shows the other person’s profile beside it. Right-clicking a message (or its author’s avatar or name) offers Apps, the right-click commands that servers’ applications register, with a search field, Frequently Used, and each application’s commands. Forums have search, tag filters, list/gallery controls, and local post details. Voice rooms have a room panel and collapsible chat. On Android, the sample guild rail, grouped channels, history, and local sends use the same in-memory workspace store. Back returns from a conversation to its channel list. Android forum browsing and account sign-in are not connected yet. The existing Swift SakuraCord checkout remains the reference while the shared client is developed.

Design

  • A quiet, continuous surface with clear hierarchy and few nested panels.
  • Compact DM navigation, edge-anchored message bubbles, a floating composer, and an optional member pane on macOS.
  • A native desktop-sampling window backdrop, AppKit Liquid Glass beneath bubbles and controls, and an AppKit toolbar with SF Symbols on macOS.
  • Dark neutrals with Sakura pink used sparingly for selection and identity.
  • No visible feature until its behavior works.
  • Choose new features deliberately instead of automatically following upstream.
  • Keep the conversation central on both phone and desktop.

Run

Use Node 20 or later, the Android SDK, Visual Studio 2022 with the Windows development workload, Xcode, and CocoaPods for native builds. The macOS app requires macOS 26 or later for native Liquid Glass.

  1. Run npm ci --ignore-scripts to install JavaScript dependencies. The --ignore-scripts option avoids an optional fsevents compile that stalled on the current Node 26 environment.
  2. Run npm start for Metro.
  3. Run npm run android for Android.
  4. Run bundle install, then bundle exec pod install --project-directory=macos, and npm run macos for a macOS development run.
  5. Run npm run windows for the React Native Windows development build. The generated windows/Ancord.sln targets Win32, x64, and ARM64.

For a standalone macOS preview, run npm run macos:release. It builds a universal app with its JavaScript included and copies it to dist/Ancord.app. Open that app directly on this Mac. The local build is unsigned; distribution to other Macs will require signing and notarization.

Music activity sharing on macOS uses Discord's optional Social SDK. Download the C++ SDK archive from the Discord application registered for Ancord, enable Public Client, and register http://127.0.0.1/callback as an OAuth redirect. Install it locally with bash scripts/install-discord-social-sdk.sh /path/to/DiscordSocialSdk-1.10.19337.zip. The framework, headers, and SDK notices are excluded from Git; release builds embed them when installed. Builds without the SDK still work, with activity sharing unavailable.

To look at the interface without touching a saved account, launch the built app with ANCORD_OFFLINE_PREVIEW=1 in its environment (for example ANCORD_OFFLINE_PREVIEW=1 dist/Ancord.app/Contents/MacOS/ancord). It opens the offline sample workspace and never reads the saved accounts.

Checks: npm run typecheck, npm run lint, and npm test -- --runInBand. You can also create platform bundles with npx react-native bundle --platform android or --platform macos.

Windows uses React Native Windows 0.81.2 to match the React Native 0.81 runtime. The initial Windows shell uses the shared conversation UI and offline provider; macOS-only Keychain, AppKit, voice, and Liquid Glass modules are not loaded on Windows. Add Windows-native credential, tray, notification, media, and update adapters behind platform contracts before enabling connected accounts.

Migration path

The macOS Swift app remains the reference for existing behavior, including its protocol boundaries, reliability work, and features already chosen for SakuraCord. Both platform previews use WorkspaceStore and the provider boundary in src/workspace; the macOS account path also uses them for live history, selection, and sending. src/discord/MacDiscordWorkspaceProvider.ts restores the saved account through Gateway READY, then adapts REST data through src/discord/DiscordWorkspaceProvider.ts and applies Gateway updates to the rendered workspace. Android remains on the local provider.

The macOS account port has a native Keychain boundary and staged in-memory credentials that can be committed after Gateway READY.user supplies the account ID. A reconnecting Gateway session uses the SakuraCord desktop handshake (ETF, zstd-stream, Identify, QoS heartbeat, READY, and in-memory resume state). A saved-account provider requires Gateway READY to match the Keychain account before loading its REST workspace, with one native metadata snapshot shared by the Gateway and REST headers. The REST projection includes private/group DMs and guild channels. Message history supports replies, attachments, stickers, embeds, Unicode and live guild custom emoji reactions, and Components V2. Custom guild emojis follow GUILD_CREATE, GUILD_UPDATE, and GUILD_EMOJIS_UPDATE; reaction tokens preserve Discord’s static and animated emoji format, selected custom emojis appear in Recent, and emoji favorites plus frequently used rankings load from and update Discord’s settings proto. Components decode and render in both macOS timelines. On a connected account, buttons and selects are sent to the app that owns the message, user, role, mentionable, and channel selects load their choices from Discord, and the app’s answer is matched back over the Gateway by nonce. Forms an app returns for a click or a slash command open as a window-level sheet; text fields, option lists, and checkboxes can be submitted, with Discord’s per-field rejections shown in place. Forms that require a member, role, or channel picker, or a file upload, are shown but cannot be submitted yet. The bounded native Zstandard stream decoder, JSON-compatible ETF codec, and vendored Zstandard 1.5.7 source with its BSD license are in the transport layer.