From 4be731044145e2d5054f0db47448c8e0d0c31056 Mon Sep 17 00:00:00 2001 From: SleeplessOne1917 Date: Fri, 17 Nov 2023 03:47:33 +0000 Subject: [PATCH] Settings Import/export (#2223) * Add UI for import/export of settings * Make settings update after import without requiring manual browser refresh * Address PR feedback * Add translations --- lemmy-translations | 2 +- src/shared/components/person/settings.tsx | 191 +++++++++++++++++++++- 2 files changed, 191 insertions(+), 2 deletions(-) diff --git a/lemmy-translations b/lemmy-translations index b0d80808..277e3c33 160000 --- a/lemmy-translations +++ b/lemmy-translations @@ -1 +1 @@ -Subproject commit b0d80808047eb547aa995e923e9c742e87cd8be7 +Subproject commit 277e3c335bbb9c00c4a600bd4d655b273393f84a diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx index 91ff4380..6a5ce87a 100644 --- a/src/shared/components/person/settings.tsx +++ b/src/shared/components/person/settings.tsx @@ -17,7 +17,7 @@ import { capitalizeFirstLetter, debounce } from "@utils/helpers"; import { Choice, RouteDataResponse } from "@utils/types"; import classNames from "classnames"; import { NoOptionI18nKeys } from "i18next"; -import { Component, linkEvent } from "inferno"; +import { Component, createRef, linkEvent } from "inferno"; import { BlockCommunityResponse, BlockInstanceResponse, @@ -60,6 +60,7 @@ import { CommunityLink } from "../community/community-link"; import { PersonListing } from "./person-listing"; import { InitialFetchRequest } from "../../interfaces"; import TotpModal from "../common/totp-modal"; +import { LoadingEllipses } from "../common/loading-ellipses"; type SettingsData = RouteDataResponse<{ instancesRes: GetFederatedInstancesResponse; @@ -119,6 +120,9 @@ interface SettingsState { searchInstanceOptions: Choice[]; isIsomorphic: boolean; show2faModal: boolean; + importSettingsRes: RequestState; + exportSettingsRes: RequestState; + settingsFile?: File; } type FilterType = "user" | "community" | "instance"; @@ -183,6 +187,8 @@ function handleClose2faModal(i: Settings) { export class Settings extends Component { private isoData = setIsoData(this.context); + exportSettingsLink = createRef(); + state: SettingsState = { saveRes: EMPTY_REQUEST, deleteAccountRes: EMPTY_REQUEST, @@ -207,6 +213,8 @@ export class Settings extends Component { generateTotpRes: EMPTY_REQUEST, updateTotpRes: EMPTY_REQUEST, show2faModal: false, + importSettingsRes: EMPTY_REQUEST, + exportSettingsRes: EMPTY_REQUEST, }; constructor(props: any, context: any) { @@ -251,6 +259,7 @@ export class Settings extends Component { show_read_posts, send_notifications_to_email, email, + open_links_in_new_tab, }, person: { avatar, @@ -288,6 +297,7 @@ export class Settings extends Component { bio, send_notifications_to_email, matrix_user_id, + open_links_in_new_tab, }, }; } @@ -332,8 +342,18 @@ export class Settings extends Component { } render() { + /* eslint-disable jsx-a11y/anchor-has-content, jsx-a11y/anchor-is-valid */ return (