Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GH-314] Export native app user settings on change #380

Merged

Conversation

Johennes
Copy link
Contributor

@Johennes Johennes commented May 3, 2021

Summary

This switches from exporting the native app user settings on window close to exporting on settings change. This way the settings export remains independent of native application life-cycle events.

This is a stop-gap towards enabling settings export on the native Linux app. The latter does not have an easy way to catch window close events.

As a positive side-effect this also makes the settings export on the native macOS app more reliable and prevents settings loss when the app crashes or is force-killed. Additionally, the required code on the native app side is reduced.

On the negative side, the settings are still exported as blob which now causes more processing since the export happens more often. I already exposed the changed settings key in the script message so it should be relatively easy to switch to storing the settings individually in a follow-up change.

Ticket Link

Relates to #314

This switches from exporting the native app user settings on window close to exporting
on settings change. This way the settings export remains independent of native application
life-cycle events.

This is a stop-gap towards enabling settings export on the native Linux app. The latter
does not have an easy way to catch window close events.

Relates to: mattermost-community#314
@mattermod
Copy link
Contributor

Hello @Johennes,

Thanks for your pull request! A Core Committer will review your pull request soon. For code contributions, you can learn more about the review process here.

let timeout = DispatchTime.now() + .seconds(3)
var result: DispatchTimeoutResult?

// Busy wait because evaluateJavaScript can only be called from *and* signals on the main thread
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Busy wait be gone! 🎉


import './styles/variables.scss'
import './styles/main.scss'
import './styles/labels.scss'

store.setHandlers({getter: UserSettings.getEmojiMartSetting, setter: UserSettings.setEmojiMartSetting})
importNativeAppSettings()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved this here because the initThemes call below already reads from localStorage.


const keys = ['language', 'theme', 'lastBoardId', 'lastViewId', 'emoji-mart.last', 'emoji-mart.frequently']
static getEmojiMartSetting(key: string): any {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method and the one below are a bit hairy. There's some documentation about the emoji-mart settings keys and values in the upstream README (see the "Storage" section).

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, thanks for parsing the Emojimart settings! We expect to refactor the emoji picker in the future, so this will likely change (not for a while though).

@Johennes
Copy link
Contributor Author

Johennes commented May 3, 2021

For some reason ESLint keeps rejecting the enum as a shadowing declaration.

 /home/runner/work/focalboard/focalboard/webapp/src/userSettings.ts
  7:6  error  'UserSettingKey' is already declared in the upper scope on line 7 column 6  no-shadow

I suspect this is a false positive as I can't see how this would shadow an existing declaration?

EDIT: I added an inline comment to disable the rule on this line.

@jespino jespino requested a review from chenilim May 10, 2021 15:20
Conflicts:
	webapp/src/userSettings.ts
@mattermod
Copy link
Contributor

This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!

/cc @jasonblais @jfrerich @emilyacook

@chenilim
Copy link
Contributor

Thanks so much @Johennes! I'm so sorry for the delay. Totally my fault for missing this on my todo list! Reviewing now.

Copy link
Contributor

@chenilim chenilim left a comment

Choose a reason for hiding this comment

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

Thanks @Johennes, and sorry again for the delay. This looks great, and the only change I think we should make now is to check the key membership for UserSettings.

Adding @sbishel as an FYI. We need to later expand the UserSettings persistence to Windows and Linux, and can continue to refine it.

export function notifySettingsChanged(key: string) {
postWebKitMessage({type: 'didChangeUserSettings', key, settingsBlob: exportUserSettingsBlob()})
}

function postWebKitMessage(message: any) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Love this construct - for extending webapp-to-native messaging in the future. We'll add a mental todo to also adapt this for Windows / Linux in the future.


const keys = ['language', 'theme', 'lastBoardId', 'lastViewId', 'emoji-mart.last', 'emoji-mart.frequently']
static getEmojiMartSetting(key: string): any {
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, thanks for parsing the Emojimart settings! We expect to refactor the emoji picker in the future, so this will likely change (not for a while though).

webapp/src/userSettings.ts Show resolved Hide resolved
@Johennes
Copy link
Contributor Author

Johennes commented May 21, 2021

Thanks so much @Johennes! I'm so sorry for the delay. Totally my fault for missing this on my todo list! Reviewing now.

Ah, no worries at all @chenilim. I actually forgot that I did this myself until I received the notification about the "stale" label being added last night. 😅

I made the change to check the local storage keys.

Copy link
Contributor

@chenilim chenilim left a comment

Choose a reason for hiding this comment

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

Thanks for making the changes @Johennes! LGTM!

I thought about it a bit more, and it's probably less about being a security issue (if someone can inject JS, there's not much we can do), but this verification would help catch any code or typo errors in the future.

@hanzei
Copy link

hanzei commented Jun 1, 2021

@chenilim Should this PR be reviewed by someone else?

@hanzei hanzei added the 2: Dev Review Requires review by a core committer label Jun 1, 2021
@Johennes
Copy link
Contributor Author

Johennes commented Jun 4, 2021

I rebased this on main and resolved the conflict but I think it needs another look now. When I start and stop the app multiple times in a row, I sometimes see the previous settings not being retained on relaunch. They're imported at first but then something seems to overwrite them again. I will have to investigate that. 😞

@Johennes
Copy link
Contributor Author

Johennes commented Jun 5, 2021

So this was one of these cases where a simple typo makes you go on a two-hour goose chase and lets you question God and the world until you finally realize that you fat-fingeredly used Object.values(UserSettings) instead of Object.values(UserSettingKey). 🤦

This is fixed now and things appear to work correctly again. I left some of the extended logging that I used to analyze the issue around as well. The interaction between the web view and the app is quite tedious to debug so this might come in handy in future. 🙂

@jasonblais
Copy link

cc @jespino on above

@jespino jespino self-requested a review June 24, 2021 22:28
@mattermod
Copy link
Contributor

This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!

/cc @jasonblais @jfrerich @emilyacook

Conflicts:
	webapp/src/app.tsx
	webapp/src/i18n.tsx
	webapp/src/main.tsx
	webapp/src/pages/boardPage.tsx
@Johennes Johennes requested a review from a team as a code owner August 12, 2021 13:37
@Johennes
Copy link
Contributor Author

Johennes commented Aug 12, 2021

@jespino / @chenilim many apologies for the huge delay. I finally found the time to merge the main branch in again. I briefly re-tested the change again and it's now ready for code review (and hopefully merging). 🙂

@jespino
Copy link
Contributor

jespino commented Aug 13, 2021

I'll review it ASAP. Thanks for all the effort and the patience @Johennes

@hahmadia hahmadia removed the request for review from a team August 13, 2021 15:11
Copy link
Contributor

@jespino jespino left a comment

Choose a reason for hiding this comment

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

LGTM

@jespino jespino added 3: Reviews Complete All reviewers have approved the pull request and removed 2: Dev Review Requires review by a core committer labels Aug 15, 2021
@jespino jespino merged commit b6d32da into mattermost-community:main Aug 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3: Reviews Complete All reviewers have approved the pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants