merge: upstream
This commit is contained in:
commit
38e35e1472
185 changed files with 4442 additions and 2501 deletions
|
|
@ -8,7 +8,7 @@ import * as os from '@/os.js';
|
|||
import { $i } from '@/account.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { customEmojis } from '@/custom-emojis.js';
|
||||
import { lang } from '@/config.js';
|
||||
import { url, lang } from '@/config.js';
|
||||
|
||||
export function createAiScriptEnv(opts) {
|
||||
return {
|
||||
|
|
@ -17,6 +17,7 @@ export function createAiScriptEnv(opts) {
|
|||
USER_USERNAME: $i ? values.STR($i.username) : values.NULL,
|
||||
CUSTOM_EMOJIS: utils.jsToVal(customEmojis.value),
|
||||
LOCALE: values.STR(lang),
|
||||
SERVER_URL: values.STR(url),
|
||||
'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => {
|
||||
await os.alert({
|
||||
type: type ? type.value : 'info',
|
||||
|
|
@ -48,6 +49,16 @@ export function createAiScriptEnv(opts) {
|
|||
return values.ERROR('request_failed', utils.jsToVal(err));
|
||||
});
|
||||
}),
|
||||
'Mk:apiExternal': values.FN_NATIVE(async ([host, ep, param, token]) => {
|
||||
utils.assertString(host);
|
||||
utils.assertString(ep);
|
||||
if (token) utils.assertString(token);
|
||||
return os.apiExternal(host.value, ep.value, utils.valToJs(param), token?.value).then(res => {
|
||||
return utils.jsToVal(res);
|
||||
}, err => {
|
||||
return values.ERROR('request_failed', utils.jsToVal(err));
|
||||
});
|
||||
}),
|
||||
'Mk:save': values.FN_NATIVE(([key, value]) => {
|
||||
utils.assertString(key);
|
||||
miLocalStorage.setItem(`aiscript:${opts.storageKey}:${key.value}`, JSON.stringify(utils.valToJs(value)));
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export const pendingApiRequestsCount = ref(0);
|
|||
|
||||
// Implements Misskey.api.ApiClient.request
|
||||
export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Misskey.Endpoints[E]['res']> {
|
||||
if (endpoint.includes('://')) throw new Error('invalid endpoint');
|
||||
pendingApiRequestsCount.value++;
|
||||
|
||||
const onFinally = () => {
|
||||
|
|
@ -23,7 +24,50 @@ export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoin
|
|||
if (token !== undefined) (data as any).i = token;
|
||||
|
||||
// Send request
|
||||
window.fetch(endpoint.indexOf('://') > -1 ? endpoint : `${apiUrl}/${endpoint}`, {
|
||||
window.fetch(`${apiUrl}/${endpoint}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'omit',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
signal,
|
||||
}).then(async (res) => {
|
||||
const body = res.status === 204 ? null : await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
resolve(body);
|
||||
} else if (res.status === 204) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(body.error);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
|
||||
promise.then(onFinally, onFinally);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
export function apiExternal<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(hostUrl: string, endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Misskey.Endpoints[E]['res']> {
|
||||
if (!/^https?:\/\//.test(hostUrl)) throw new Error('invalid host name');
|
||||
if (endpoint.includes('://')) throw new Error('invalid endpoint');
|
||||
pendingApiRequestsCount.value++;
|
||||
|
||||
const onFinally = () => {
|
||||
pendingApiRequestsCount.value--;
|
||||
};
|
||||
|
||||
const promise = new Promise<Misskey.Endpoints[E]['res'] | void>((resolve, reject) => {
|
||||
// Append a credential
|
||||
(data as any).i = token;
|
||||
|
||||
const fullUrl = (hostUrl.slice(-1) === '/' ? hostUrl.slice(0, -1) : hostUrl)
|
||||
+ '/api/' + (endpoint.slice(0, 1) === '/' ? endpoint.slice(1) : endpoint);
|
||||
// Send request
|
||||
window.fetch(fullUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'omit',
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ export function getNoteMenu(props: {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit(): void {
|
||||
os.post({
|
||||
initialNote: appearNote,
|
||||
|
|
@ -190,7 +191,7 @@ export function getNoteMenu(props: {
|
|||
channel: appearNote.channel,
|
||||
editId: appearNote.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFavorite(favorite: boolean): void {
|
||||
claimAchievement('noteFavorited1');
|
||||
|
|
@ -307,7 +308,7 @@ export function getNoteMenu(props: {
|
|||
text: i18n.ts.share,
|
||||
action: share,
|
||||
},
|
||||
instance.translatorAvailable ? {
|
||||
$i && $i.policies.canUseTranslator && instance.translatorAvailable ? {
|
||||
icon: 'ph-translate ph-bold ph-lg',
|
||||
text: i18n.ts.translate,
|
||||
action: translate,
|
||||
|
|
|
|||
|
|
@ -80,6 +80,15 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
|
|||
});
|
||||
}
|
||||
|
||||
async function toggleWithReplies() {
|
||||
os.apiWithDialog('following/update', {
|
||||
userId: user.id,
|
||||
withReplies: !user.withReplies,
|
||||
}).then(() => {
|
||||
user.withReplies = !user.withReplies;
|
||||
});
|
||||
}
|
||||
|
||||
async function toggleNotify() {
|
||||
os.apiWithDialog('following/update', {
|
||||
userId: user.id,
|
||||
|
|
@ -282,6 +291,10 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
|
|||
// フォローしたとしても user.isFollowing はリアルタイム更新されないので不便なため
|
||||
//if (user.isFollowing) {
|
||||
menu = menu.concat([{
|
||||
icon: user.withReplies ? 'ph-envelope ph-bold pg-lg-off' : 'ph-envelope ph-bold',
|
||||
text: user.withReplies ? i18n.ts.hideRepliesToOthersInTimeline : i18n.ts.showRepliesToOthersInTimeline,
|
||||
action: toggleWithReplies,
|
||||
}, {
|
||||
icon: user.notify === 'none' ? 'ph-bell ph-bold pg-lg' : 'ph-bell ph-bold pg-lg-off',
|
||||
text: user.notify === 'none' ? i18n.ts.notifyNotes : i18n.ts.unnotifyNotes,
|
||||
action: toggleNotify,
|
||||
|
|
|
|||
|
|
@ -72,6 +72,13 @@ export function useNoteCapture(props: {
|
|||
break;
|
||||
}
|
||||
|
||||
case 'updated': {
|
||||
note.value.updatedAt = new Date().toISOString();
|
||||
note.value.cw = body.cw;
|
||||
note.value.text = body.text;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'deleted': {
|
||||
props.isDeletedRef.value = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ export function useTooltip(
|
|||
|
||||
let changeShowingState: (() => void) | null;
|
||||
|
||||
let autoHidingTimer;
|
||||
|
||||
const open = () => {
|
||||
close();
|
||||
if (!isHovering) return;
|
||||
|
|
@ -33,6 +35,16 @@ export function useTooltip(
|
|||
changeShowingState = () => {
|
||||
showing.value = false;
|
||||
};
|
||||
|
||||
autoHidingTimer = window.setInterval(() => {
|
||||
if (!document.body.contains(elRef.value)) {
|
||||
if (!isHovering) return;
|
||||
isHovering = false;
|
||||
window.clearTimeout(timeoutId);
|
||||
close();
|
||||
window.clearInterval(autoHidingTimer);
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
|
|
@ -53,6 +65,7 @@ export function useTooltip(
|
|||
if (!isHovering) return;
|
||||
isHovering = false;
|
||||
window.clearTimeout(timeoutId);
|
||||
window.clearInterval(autoHidingTimer);
|
||||
close();
|
||||
};
|
||||
|
||||
|
|
@ -67,6 +80,7 @@ export function useTooltip(
|
|||
if (!isHovering) return;
|
||||
isHovering = false;
|
||||
window.clearTimeout(timeoutId);
|
||||
window.clearInterval(autoHidingTimer);
|
||||
close();
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue