Skip to content

feat: implement cloud sync#307

Open
dolfies wants to merge 5 commits intomoonlight-mod:mainfrom
dolfies:feat/cloud-sync
Open

feat: implement cloud sync#307
dolfies wants to merge 5 commits intomoonlight-mod:mainfrom
dolfies:feat/cloud-sync

Conversation

@dolfies
Copy link
Copy Markdown

@dolfies dolfies commented Mar 6, 2026

Settings are synced directly to Discord, no remote server required :)

  • Allows picking which account to sync to
  • Should work during account switcher use
  • Should alert the user if any conflicts happen when saving from multiple clients
  • Definitely needs more testing for state bugs

@NotNite
Copy link
Copy Markdown
Member

NotNite commented Mar 6, 2026

I just woke up, so I haven't had time to fully review it, but some initial concerns from me:

  • We try our best to not show any obvious red flags as a modded client (we aren't perfect, and it's pretty obvious we're modded with something like disableSentry anyways), but I feel a bit uneasy shipping an extension that's by design stuffing extra data in UserSettings no matter how minor. If we shipped this, I think it'd have to be disabled by default and marked with Danger Zone.
  • IMO involving moonlight's core config loading with this is the wrong approach; I'd rather have the core extension overwrite the local config on startup, and listen to config saved events to sync it to the server.
  • I'm not a big fan of making this a hard dependency of moonbase, but we also don't really have a way to specify a soft dependency right now, so not sure what the best solution is there (another tab in settings, maybe?).

Regardless, the implementation here is really clever, well done! Also, feel free to ignore the Nix CI, I can fix that for you.

@NotNite NotNite added enhancement New feature or request core This issue is related to moonlight's core core-extension This issue is related to a core extension of moonlight labels Mar 6, 2026
@dolfies
Copy link
Copy Markdown
Author

dolfies commented Mar 7, 2026

Regarding 1, moonlight is actually already explicitly detected by Discord (and it's not for malicious reasons) so I don't think this makes much of a difference. It's already disabled by default, and I'm not sure how to add a Danger Zone marking given that it's toggled in moonbase, though an extra warning box is probably reasonable

@NotNite
Copy link
Copy Markdown
Member

NotNite commented Mar 7, 2026

Regarding 1, moonlight is actually already explicitly detected by Discord (and it's not for malicious reasons) so I don't think this makes much of a difference.

That detection doesn't actually trigger since we don't load libdiscore's separate Webpack entrypoint immediately - I've been meaning to solve it in a more pleasant way in #301.

It's already disabled by default

I'm pretty sure having it as a dependency of Moonbase will enable it, given that we don't have a mechanism to do soft dependency resolution ATM. We should probably fix that... Alternatively, we could not integrate it with Moonbase at all and just have a separate settings tab, I guess?

and I'm not sure how to add a Danger Zone marking given that it's toggled in moonbase

dangerZone tag in the extension manifest.

Copy link
Copy Markdown
Member

@NotNite NotNite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the wait on reviewing this!

I'm pretty happy with how this is implemented overall, but I still think we should split this off from Moonbase proper into its own settings panel. This fits better as a standalone extension anyways, because we have the relevant config events already exposed in moonlight core. Beyond that, this seems very clean; well done!

version: string;
branch: MoonlightBranch;

getFullConfig: () => Config;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason we need getFullConfig over the config getter here?

Comment thread biome.jsonc
"indentStyle": "space",
"lineWidth": 120
"lineWidth": 120,
"lineEnding": "auto"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this changed? We should ideally be using LF everywhere (though I'm not actually sure if we have any CRLF files in the repository).

"authors": ["Cynosphere", "NotNite", "redstonekasi"]
},
"dependencies": ["spacepack", "settings", "common", "notices", "contextMenu"],
"dependencies": ["spacepack", "settings", "common", "notices", "contextMenu", "cloudSync"],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm of the opinion that we shouldn't directly tie this UI into Moonbase. Because it has cloudSync as a dependency, it'll be implicitly enabled by the dependency resolver and thus always enabled for every user; this is a weird quirk we do for libraries inherited from before we had proper dependency management in Moonbase.

I think the Cloud Sync extension should register a settings pane that's next to Moonbase on the UI:

const redesignTitle = () => "moonlight";
. Integrating it into Moonbase itself is a bad idea IMO, as that should stay purely for extension management and moonlight settings.

import Margins from "@moonlight-mod/wp/discord/styles/shared/Margins.css";
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
import { Button } from "@moonlight-mod/wp/discord/uikit/legacy/Button";
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be using MoonbaseSettingsStore here; just use the setConfigOption function on moonlight. The settings store should automatically pick up the change anyways:

moonlightNode.events.addEventListener(NodeEventType.ConfigSaved, (config) => {

}

setExtensionConfig(id: string, key: string, value: any) {
setExtensionConfig(id: string, key: string, value: any, permanent: boolean = false) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this; this code is here so that config changes can be rolled back in Moonbase, so the concept of "permanent" here is unnecessary.

}

export default function CloudSyncPage() {
const enabled = MoonbaseSettingsStore.getExtensionConfigRaw<boolean>("cloudSync", "enabled", false) ?? false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to decouple this from Moonbase fully, I think we can remove this "enabled" switch, as the user can just disable the extension. The accountId option won't be displayed in Moonbase as long as it's not defined in the manifest, so we can keep that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core This issue is related to moonlight's core core-extension This issue is related to a core extension of moonlight enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants