mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-03-14 01:48:50 +01:00
Experimental "cloud" shortcuts settings import/export
This commit is contained in:
parent
a3236ea0f0
commit
a8b5c8cd64
6 changed files with 199 additions and 3 deletions
|
@ -2108,7 +2108,7 @@ meter.donut[hidden] {
|
||||||
:root .toastify {
|
:root .toastify {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
border-radius: 999px;
|
border-radius: 44px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
color: var(--button-text-color);
|
color: var(--button-text-color);
|
||||||
text-shadow: 0 calc(var(--hairline-width) * -1) var(--drop-shadow-color);
|
text-shadow: 0 calc(var(--hairline-width) * -1) var(--drop-shadow-color);
|
||||||
|
|
|
@ -1251,6 +1251,27 @@ function RelatedActions({
|
||||||
</MenuItem>
|
</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>
|
</Menu2>
|
||||||
{!relationship && relationshipUIState === 'loading' && (
|
{!relationship && relationshipUIState === 'loading' && (
|
||||||
<Loader abrupt />
|
<Loader abrupt />
|
||||||
|
|
|
@ -153,6 +153,15 @@
|
||||||
}
|
}
|
||||||
#import-export-container section p {
|
#import-export-container section p {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
|
|
||||||
|
&.field-button {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#import-export-container section details > summary {
|
#import-export-container section details > summary {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -182,3 +191,14 @@
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
flex-shrink: 0;
|
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 pmem from '../utils/pmem';
|
||||||
import showToast from '../utils/show-toast';
|
import showToast from '../utils/show-toast';
|
||||||
import states from '../utils/states';
|
import states from '../utils/states';
|
||||||
|
import store from '../utils/store';
|
||||||
|
|
||||||
import AsyncText from './AsyncText';
|
import AsyncText from './AsyncText';
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
|
@ -716,6 +717,7 @@ function ShortcutForm({
|
||||||
}
|
}
|
||||||
|
|
||||||
function ImportExport({ shortcuts, onClose }) {
|
function ImportExport({ shortcuts, onClose }) {
|
||||||
|
const { masto } = api();
|
||||||
const shortcutsStr = useMemo(() => {
|
const shortcutsStr = useMemo(() => {
|
||||||
if (!shortcuts) return '';
|
if (!shortcuts) return '';
|
||||||
if (!shortcuts.filter(Boolean).length) return '';
|
if (!shortcuts.filter(Boolean).length) return '';
|
||||||
|
@ -754,6 +756,8 @@ function ImportExport({ shortcuts, onClose }) {
|
||||||
}, [importShortcutStr]);
|
}, [importShortcutStr]);
|
||||||
const hasCurrentSettings = states.shortcuts.length > 0;
|
const hasCurrentSettings = states.shortcuts.length > 0;
|
||||||
|
|
||||||
|
const shortcutsImportFieldRef = useRef();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="import-export-container" class="sheet">
|
<div id="import-export-container" class="sheet">
|
||||||
{!!onClose && (
|
{!!onClose && (
|
||||||
|
@ -772,8 +776,9 @@ function ImportExport({ shortcuts, onClose }) {
|
||||||
<Icon icon="arrow-down-circle" size="l" class="insignificant" />{' '}
|
<Icon icon="arrow-down-circle" size="l" class="insignificant" />{' '}
|
||||||
<span>Import</span>
|
<span>Import</span>
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p class="field-button">
|
||||||
<input
|
<input
|
||||||
|
ref={shortcutsImportFieldRef}
|
||||||
type="text"
|
type="text"
|
||||||
name="import"
|
name="import"
|
||||||
placeholder="Paste shortcuts here"
|
placeholder="Paste shortcuts here"
|
||||||
|
@ -782,6 +787,53 @@ function ImportExport({ shortcuts, onClose }) {
|
||||||
setImportShortcutStr(e.target.value);
|
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>
|
</p>
|
||||||
{!!parsedImportShortcutStr &&
|
{!!parsedImportShortcutStr &&
|
||||||
Array.isArray(parsedImportShortcutStr) && (
|
Array.isArray(parsedImportShortcutStr) && (
|
||||||
|
@ -991,8 +1043,64 @@ function ImportExport({ shortcuts, onClose }) {
|
||||||
<Icon icon="share" /> <span>Share</span>
|
<Icon icon="share" /> <span>Share</span>
|
||||||
</button>
|
</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 && (
|
{shortcutsStr.length > 0 && (
|
||||||
<small class="insignificant">
|
<small class="insignificant ib">
|
||||||
{shortcutsStr.length} characters
|
{shortcutsStr.length} characters
|
||||||
</small>
|
</small>
|
||||||
)}
|
)}
|
||||||
|
@ -1008,6 +1116,14 @@ function ImportExport({ shortcuts, onClose }) {
|
||||||
</details>
|
</details>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
{states.settings.shortcutSettingsCloudImportExport && (
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
<Icon icon="cloud" /> Import/export settings from/to instance
|
||||||
|
server (Very experimental)
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
)}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -464,6 +464,39 @@ function Settings({ onClose }) {
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</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>
|
<li>
|
||||||
<label>
|
<label>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -65,6 +65,7 @@ const states = proxy({
|
||||||
contentTranslationTargetLanguage: null,
|
contentTranslationTargetLanguage: null,
|
||||||
contentTranslationHideLanguages: [],
|
contentTranslationHideLanguages: [],
|
||||||
contentTranslationAutoInline: false,
|
contentTranslationAutoInline: false,
|
||||||
|
shortcutSettingsCloudImportExport: false,
|
||||||
mediaAltGenerator: false,
|
mediaAltGenerator: false,
|
||||||
cloakMode: false,
|
cloakMode: false,
|
||||||
},
|
},
|
||||||
|
@ -94,6 +95,8 @@ export function initStates() {
|
||||||
store.account.get('settings-contentTranslationHideLanguages') || [];
|
store.account.get('settings-contentTranslationHideLanguages') || [];
|
||||||
states.settings.contentTranslationAutoInline =
|
states.settings.contentTranslationAutoInline =
|
||||||
store.account.get('settings-contentTranslationAutoInline') ?? false;
|
store.account.get('settings-contentTranslationAutoInline') ?? false;
|
||||||
|
states.settings.shortcutSettingsCloudImportExport =
|
||||||
|
store.account.get('settings-shortcutSettingsCloudImportExport') ?? false;
|
||||||
states.settings.mediaAltGenerator =
|
states.settings.mediaAltGenerator =
|
||||||
store.account.get('settings-mediaAltGenerator') ?? false;
|
store.account.get('settings-mediaAltGenerator') ?? false;
|
||||||
states.settings.cloakMode = store.account.get('settings-cloakMode') ?? false;
|
states.settings.cloakMode = store.account.get('settings-cloakMode') ?? false;
|
||||||
|
@ -121,6 +124,9 @@ subscribe(states, (changes) => {
|
||||||
if (path.join('.') === 'settings.contentTranslationAutoInline') {
|
if (path.join('.') === 'settings.contentTranslationAutoInline') {
|
||||||
store.account.set('settings-contentTranslationAutoInline', !!value);
|
store.account.set('settings-contentTranslationAutoInline', !!value);
|
||||||
}
|
}
|
||||||
|
if (path.join('.') === 'settings.shortcutSettingsCloudImportExport') {
|
||||||
|
store.account.set('settings-shortcutSettingsCloudImportExport', !!value);
|
||||||
|
}
|
||||||
if (path.join('.') === 'settings.contentTranslationTargetLanguage') {
|
if (path.join('.') === 'settings.contentTranslationTargetLanguage') {
|
||||||
console.log('SET', value);
|
console.log('SET', value);
|
||||||
store.account.set('settings-contentTranslationTargetLanguage', value);
|
store.account.set('settings-contentTranslationTargetLanguage', value);
|
||||||
|
|
Loading…
Reference in a new issue