Experimental "cloud" shortcuts settings import/export
This commit is contained in:
parent
a3236ea0f0
commit
a8b5c8cd64
|
@ -2108,7 +2108,7 @@ meter.donut[hidden] {
|
|||
:root .toastify {
|
||||
user-select: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 999px;
|
||||
border-radius: 44px;
|
||||
pointer-events: none;
|
||||
color: var(--button-text-color);
|
||||
text-shadow: 0 calc(var(--hairline-width) * -1) var(--drop-shadow-color);
|
||||
|
|
|
@ -1251,6 +1251,27 @@ function RelatedActions({
|
|||
</MenuItem>
|
||||
</>
|
||||
)}
|
||||
{import.meta.env.DEV && currentAuthenticated && isSelf && (
|
||||
<>
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
onClick={async () => {
|
||||
const relationships =
|
||||
await currentMasto.v1.accounts.relationships.fetch({
|
||||
id: [accountID.current],
|
||||
});
|
||||
const { note } = relationships[0] || {};
|
||||
if (note) {
|
||||
alert(note);
|
||||
console.log(note);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon icon="pencil" />
|
||||
<span>See note</span>
|
||||
</MenuItem>
|
||||
</>
|
||||
)}
|
||||
</Menu2>
|
||||
{!relationship && relationshipUIState === 'loading' && (
|
||||
<Loader abrupt />
|
||||
|
|
|
@ -153,6 +153,15 @@
|
|||
}
|
||||
#import-export-container section p {
|
||||
margin: 8px 0;
|
||||
|
||||
&.field-button {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#import-export-container section details > summary {
|
||||
cursor: pointer;
|
||||
|
@ -182,3 +191,14 @@
|
|||
font-size: 90%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#import-export-container {
|
||||
footer {
|
||||
font-size: 90%;
|
||||
color: var(--text-insignificant-color);
|
||||
|
||||
.icon {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import { fetchFollowedTags } from '../utils/followed-tags';
|
|||
import pmem from '../utils/pmem';
|
||||
import showToast from '../utils/show-toast';
|
||||
import states from '../utils/states';
|
||||
import store from '../utils/store';
|
||||
|
||||
import AsyncText from './AsyncText';
|
||||
import Icon from './icon';
|
||||
|
@ -716,6 +717,7 @@ function ShortcutForm({
|
|||
}
|
||||
|
||||
function ImportExport({ shortcuts, onClose }) {
|
||||
const { masto } = api();
|
||||
const shortcutsStr = useMemo(() => {
|
||||
if (!shortcuts) return '';
|
||||
if (!shortcuts.filter(Boolean).length) return '';
|
||||
|
@ -754,6 +756,8 @@ function ImportExport({ shortcuts, onClose }) {
|
|||
}, [importShortcutStr]);
|
||||
const hasCurrentSettings = states.shortcuts.length > 0;
|
||||
|
||||
const shortcutsImportFieldRef = useRef();
|
||||
|
||||
return (
|
||||
<div id="import-export-container" class="sheet">
|
||||
{!!onClose && (
|
||||
|
@ -772,8 +776,9 @@ function ImportExport({ shortcuts, onClose }) {
|
|||
<Icon icon="arrow-down-circle" size="l" class="insignificant" />{' '}
|
||||
<span>Import</span>
|
||||
</h3>
|
||||
<p>
|
||||
<p class="field-button">
|
||||
<input
|
||||
ref={shortcutsImportFieldRef}
|
||||
type="text"
|
||||
name="import"
|
||||
placeholder="Paste shortcuts here"
|
||||
|
@ -782,6 +787,53 @@ function ImportExport({ shortcuts, onClose }) {
|
|||
setImportShortcutStr(e.target.value);
|
||||
}}
|
||||
/>
|
||||
{states.settings.shortcutSettingsCloudImportExport && (
|
||||
<button
|
||||
type="button"
|
||||
class="plain2 small"
|
||||
disabled={importUIState === 'cloud-downloading'}
|
||||
onClick={async () => {
|
||||
setImportUIState('cloud-downloading');
|
||||
const currentAccount = store.session.get('currentAccount');
|
||||
showToast(
|
||||
'Downloading saved shortcuts from instance server…',
|
||||
);
|
||||
try {
|
||||
const relationships =
|
||||
await masto.v1.accounts.relationships.fetch({
|
||||
id: [currentAccount],
|
||||
});
|
||||
const relationship = relationships[0];
|
||||
if (relationship) {
|
||||
const { note = '' } = relationship;
|
||||
if (
|
||||
/<phanpy-shortcuts-settings>(.*)<\/phanpy-shortcuts-settings>/.test(
|
||||
note,
|
||||
)
|
||||
) {
|
||||
const settings = note.match(
|
||||
/<phanpy-shortcuts-settings>(.*)<\/phanpy-shortcuts-settings>/,
|
||||
)[1];
|
||||
const { v, dt, data } = JSON.parse(settings);
|
||||
shortcutsImportFieldRef.current.value = data;
|
||||
shortcutsImportFieldRef.current.dispatchEvent(
|
||||
new Event('input'),
|
||||
);
|
||||
}
|
||||
}
|
||||
setImportUIState('default');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setImportUIState('error');
|
||||
showToast('Unable to download shortcuts');
|
||||
}
|
||||
}}
|
||||
title="Download shortcuts from instance server"
|
||||
>
|
||||
<Icon icon="cloud" />
|
||||
<Icon icon="arrow-down" />
|
||||
</button>
|
||||
)}
|
||||
</p>
|
||||
{!!parsedImportShortcutStr &&
|
||||
Array.isArray(parsedImportShortcutStr) && (
|
||||
|
@ -991,8 +1043,64 @@ function ImportExport({ shortcuts, onClose }) {
|
|||
<Icon icon="share" /> <span>Share</span>
|
||||
</button>
|
||||
)}{' '}
|
||||
{states.settings.shortcutSettingsCloudImportExport && (
|
||||
<button
|
||||
type="button"
|
||||
class="plain2"
|
||||
disabled={importUIState === 'cloud-uploading'}
|
||||
onClick={async () => {
|
||||
setImportUIState('cloud-uploading');
|
||||
const currentAccount = store.session.get('currentAccount');
|
||||
try {
|
||||
const relationships =
|
||||
await masto.v1.accounts.relationships.fetch({
|
||||
id: [currentAccount],
|
||||
});
|
||||
const relationship = relationships[0];
|
||||
if (relationship) {
|
||||
const { note = '' } = relationship;
|
||||
// const newNote = `${note}\n\n\n$<phanpy-shortcuts-settings>{shortcutsStr}</phanpy-shortcuts-settings>`;
|
||||
let newNote = '';
|
||||
if (
|
||||
/<phanpy-shortcuts-settings>(.*)<\/phanpy-shortcuts-settings>/.test(
|
||||
note,
|
||||
)
|
||||
) {
|
||||
const settingsJSON = JSON.stringify({
|
||||
v: '1', // version
|
||||
dt: Date.now(), // datetime stamp
|
||||
data: shortcutsStr, // shortcuts settings string
|
||||
});
|
||||
newNote = note.replace(
|
||||
/<phanpy-shortcuts-settings>(.*)<\/phanpy-shortcuts-settings>/,
|
||||
`<phanpy-shortcuts-settings>${settingsJSON}</phanpy-shortcuts-settings>`,
|
||||
);
|
||||
} else {
|
||||
newNote = `${note}\n\n\n<phanpy-shortcuts-settings>${settingsJSON}</phanpy-shortcuts-settings>`;
|
||||
}
|
||||
showToast('Saving shortcuts to instance server…');
|
||||
await masto.v1.accounts
|
||||
.$select(currentAccount)
|
||||
.note.create({
|
||||
comment: newNote,
|
||||
});
|
||||
setImportUIState('default');
|
||||
showToast('Shortcuts saved');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setImportUIState('error');
|
||||
showToast('Unable to save shortcuts');
|
||||
}
|
||||
}}
|
||||
title="Sync to instance server"
|
||||
>
|
||||
<Icon icon="cloud" />
|
||||
<Icon icon="arrow-up" />
|
||||
</button>
|
||||
)}{' '}
|
||||
{shortcutsStr.length > 0 && (
|
||||
<small class="insignificant">
|
||||
<small class="insignificant ib">
|
||||
{shortcutsStr.length} characters
|
||||
</small>
|
||||
)}
|
||||
|
@ -1008,6 +1116,14 @@ function ImportExport({ shortcuts, onClose }) {
|
|||
</details>
|
||||
)}
|
||||
</section>
|
||||
{states.settings.shortcutSettingsCloudImportExport && (
|
||||
<footer>
|
||||
<p>
|
||||
<Icon icon="cloud" /> Import/export settings from/to instance
|
||||
server (Very experimental)
|
||||
</p>
|
||||
</footer>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -464,6 +464,39 @@ function Settings({ onClose }) {
|
|||
</div>
|
||||
</li>
|
||||
)}
|
||||
{authenticated && (
|
||||
<li>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={
|
||||
snapStates.settings.shortcutSettingsCloudImportExport
|
||||
}
|
||||
onChange={(e) => {
|
||||
states.settings.shortcutSettingsCloudImportExport =
|
||||
e.target.checked;
|
||||
}}
|
||||
/>{' '}
|
||||
"Cloud" import/export for shortcuts settings{' '}
|
||||
<Icon icon="cloud" class="more-insignificant" />
|
||||
</label>
|
||||
<div class="sub-section insignificant">
|
||||
<small>
|
||||
⚠️⚠️⚠️ Very experimental.
|
||||
<br />
|
||||
Stored in your own profile’s notes. Profile (private) notes
|
||||
are mainly used for other profiles, and hidden for own
|
||||
profile.
|
||||
</small>
|
||||
</div>
|
||||
<div class="sub-section insignificant">
|
||||
<small>
|
||||
Note: This feature uses currently-logged-in instance server
|
||||
API.
|
||||
</small>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
<li>
|
||||
<label>
|
||||
<input
|
||||
|
|
|
@ -65,6 +65,7 @@ const states = proxy({
|
|||
contentTranslationTargetLanguage: null,
|
||||
contentTranslationHideLanguages: [],
|
||||
contentTranslationAutoInline: false,
|
||||
shortcutSettingsCloudImportExport: false,
|
||||
mediaAltGenerator: false,
|
||||
cloakMode: false,
|
||||
},
|
||||
|
@ -94,6 +95,8 @@ export function initStates() {
|
|||
store.account.get('settings-contentTranslationHideLanguages') || [];
|
||||
states.settings.contentTranslationAutoInline =
|
||||
store.account.get('settings-contentTranslationAutoInline') ?? false;
|
||||
states.settings.shortcutSettingsCloudImportExport =
|
||||
store.account.get('settings-shortcutSettingsCloudImportExport') ?? false;
|
||||
states.settings.mediaAltGenerator =
|
||||
store.account.get('settings-mediaAltGenerator') ?? false;
|
||||
states.settings.cloakMode = store.account.get('settings-cloakMode') ?? false;
|
||||
|
@ -121,6 +124,9 @@ subscribe(states, (changes) => {
|
|||
if (path.join('.') === 'settings.contentTranslationAutoInline') {
|
||||
store.account.set('settings-contentTranslationAutoInline', !!value);
|
||||
}
|
||||
if (path.join('.') === 'settings.shortcutSettingsCloudImportExport') {
|
||||
store.account.set('settings-shortcutSettingsCloudImportExport', !!value);
|
||||
}
|
||||
if (path.join('.') === 'settings.contentTranslationTargetLanguage') {
|
||||
console.log('SET', value);
|
||||
store.account.set('settings-contentTranslationTargetLanguage', value);
|
||||
|
|
Loading…
Reference in a new issue