Skip to content

Add settings export/import#137

Open
SinnerK0N wants to merge 6 commits intoInrixia:masterfrom
SinnerK0N:settings-import-export
Open

Add settings export/import#137
SinnerK0N wants to merge 6 commits intoInrixia:masterfrom
SinnerK0N:settings-import-export

Conversation

@SinnerK0N
Copy link
Contributor

Add a section to settings for importing/exporting:

  • installed plugins
  • plugin settings
  • themes
  • feature flags
image

@Inrixia
Copy link
Owner

Inrixia commented Feb 13, 2026

Yea I really would rather this doesn't use db calls at all and instead just touches the objects in their respective places (ie on the LunaPlugin class).

There's layers of abstraction already in place to avoid the nightmare that idb is so best to use that.

That also simplifies it down to just reading and writing to the objects in question.

Copy link
Owner

@Inrixia Inrixia left a comment

Choose a reason for hiding this comment

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

Please move away from using idb directly. See my comment above

@SinnerK0N SinnerK0N requested a review from Inrixia February 13, 2026 16:56
Comment on lines +61 to +65
//feature flags
const tidalFlags = Tidal.featureFlags;
const featureFlags: Record<string, boolean> = {};
for (const [name, flag] of Object.entries(tidalFlags))
featureFlags[name] = flag.value;
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to export only redux.store.getState().featureFlags.userOverrides here instead of all flags? That way the export would only contain flags the user explicitly toggled, rather than all ~39 flags with their current values. It could help avoid creating unintended overrides if Tidal changes a default between export and import.

This will change to:

const featureFlags = redux.store.getState().featureFlags.userOverrides;

Copy link
Owner

Choose a reason for hiding this comment

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

This

Copy link
Contributor Author

@SinnerK0N SinnerK0N Feb 14, 2026

Choose a reason for hiding this comment

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

redux.store.getState().featureFlags.userOverrides seems to return only one latest toggled feature flag for some reason so i used the original code and added a check for if the flag is enabled

Copy link
Contributor

Choose a reason for hiding this comment

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

Odd. On my end, it gives every change that I toggled:
[SettingsTransfer] userOverrides would export: 2 {reactions: true, open-links-in-desktop-app: false}

Copy link
Contributor Author

@SinnerK0N SinnerK0N Feb 14, 2026

Choose a reason for hiding this comment

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

oh i know why, its because i had imported all my previous toggled feature flags and only toggled the one manually. so if someone runs the export on previously imported settings it would only return values that they would toggle after importing

Copy link
Owner

@Inrixia Inrixia left a comment

Choose a reason for hiding this comment

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

Looks good, quite a few changes and some nits and scope creep from me.

Most of the minor stuff can be resolved easily

code stripping
full storage dump
clear stores before importing
export only enabled feature flags
dump plugin storage in LunaPlugin
dump and clear methods in ReactiveStore
downloadObject helper function
@SinnerK0N
Copy link
Contributor Author

my bad for dumping everything into one commit, i got a bit carried away and forgot to commit until i had like half of the things done

@SinnerK0N SinnerK0N requested a review from Inrixia February 14, 2026 00:59
Comment on lines +27 to +31
const tidalFlags = Tidal.featureFlags;
const featureFlags: Record<string, boolean> = {};
for (const [name, flag] of Object.entries(tidalFlags))
if (flag.value)
featureFlags[name] = flag.value;
Copy link
Contributor

Choose a reason for hiding this comment

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

This would also pick up flags that are true by default even if the user never changed them. And if a user explicitly set a flag to false it would get filtered out by the if (flag.value) check.

@SinnerK0N
Copy link
Contributor Author

SinnerK0N commented Feb 16, 2026

I haven't found any other solution to the feature flags export so this is the only way to have both:

  • flags set to false by the user
  • flags which were set by a previous export

@Inrixia
Copy link
Owner

Inrixia commented Feb 17, 2026

flags which were set by a previous export

Just exporting the overrides and importing them should work perfectly?

@SinnerK0N
Copy link
Contributor Author

it does, but when using

redux.store.getState().featureFlags.userOverrides

the exported and then later imported feature flags dont appear in this object so we have to use Tidal.featureFlags
but yeah the current implementation works fine

@SinnerK0N SinnerK0N requested a review from Brskt February 20, 2026 15:05
Copy link
Owner

@Inrixia Inrixia left a comment

Choose a reason for hiding this comment

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

Only two changes really needed and this will be ready to merge.

Looking great, thanks again for the work on this <3

@SinnerK0N SinnerK0N requested a review from Inrixia February 21, 2026 23:35
try
{
//feature flags
const featureFlags = redux.store.getState().featureFlags.userOverrides as Record<string, boolean>;;
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo double semicolon


const result = await confirm({
title: "Import Settings",
description: `Import settings exported on ${new Date(data.timestamp).toLocaleString()}? Existing settings will be cleared and replaced, then the app will restart.`,
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment says "Existing settings will be cleared and replaced" but seems not to?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants