diff --git a/locales/en-US.yml b/locales/en-US.yml
index 173404e7c4..97f5313c80 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -1400,6 +1400,7 @@ _profile:
metadataContent: "Content"
changeAvatar: "Change avatar"
changeBanner: "Change banner"
+ locationDescription: "If entered properly, this will display your local time to other users."
_exportOrImport:
allNotes: "All posts"
followingList: "Followed users"
diff --git a/package.json b/package.json
index d1173a5d40..ef22dab20d 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,12 @@
{
"name": "calckey",
- "version": "13.2.0-dev10",
+ "version": "13.2.0-dev11",
"codename": "aqua",
"repository": {
"type": "git",
"url": "https://codeberg.org/calckey/calckey.git"
},
- "packageManager": "pnpm@7.27.0",
+ "packageManager": "pnpm@7.27.1",
"private": true,
"scripts": {
"rebuild": "pnpm run clean && pnpm -r run build && pnpm run gulp",
diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts
index 10ab5c66f5..a0945ae7b1 100644
--- a/packages/backend/src/remote/activitypub/models/note.ts
+++ b/packages/backend/src/remote/activitypub/models/note.ts
@@ -122,7 +122,6 @@ export async function createNote(
}
logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`);
-
logger.info(`Creating the Note: ${note.id}`);
// Skip if note is made before 2007 (1yr before Fedi was created)
diff --git a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts
index cc60a8db9b..9a690e19f0 100644
--- a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts
+++ b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts
@@ -54,7 +54,7 @@ export function apiMastodonCompatible(router: Router): void {
// displayed without being logged in
try {
const data = await client.getInstance();
- ctx.body = getInstance(data.data);
+ ctx.body = await getInstance(data.data);
} catch (e: any) {
console.error(e);
ctx.status = 401;
diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts
index f395c5a9c5..5b7df948e3 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/account.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts
@@ -98,20 +98,23 @@ export function apiAccountMastodon(router: Router): void {
ctx.body = e.response.data;
}
});
- router.get<{ Params: { id: string } }>("/v1/accounts/:id", async (ctx) => {
- const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
- const accessTokens = ctx.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- const data = await client.getAccount(ctx.params.id);
- ctx.body = data.data;
- } catch (e: any) {
- console.error(e);
- console.error(e.response.data);
- ctx.status = 401;
- ctx.body = e.response.data;
- }
- });
+ router.get<{ Params: { id: string } }>(
+ "/v1/accounts/:id(^.*\\d.*$)",
+ async (ctx) => {
+ const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
+ const accessTokens = ctx.headers.authorization;
+ const client = getClient(BASE_URL, accessTokens);
+ try {
+ const data = await client.getAccount(ctx.params.id);
+ ctx.body = data.data;
+ } catch (e: any) {
+ console.error(e);
+ console.error(e.response.data);
+ ctx.status = 401;
+ ctx.body = e.response.data;
+ }
+ },
+ );
router.get<{ Params: { id: string } }>(
"/v1/accounts/:id/statuses",
async (ctx) => {
@@ -304,11 +307,12 @@ export function apiAccountMastodon(router: Router): void {
const client = getClient(BASE_URL, accessTokens);
let users;
try {
- const idsRaw = ctx.request.body ? ["id[]"] : null;
+ // TODO: this should be body
+ const idsRaw = ctx.request.query ? ctx.request.query["id[]"] : null;
const ids = typeof idsRaw === "string" ? [idsRaw] : idsRaw;
users = ids;
relationshopModel.id = idsRaw?.toString() || "1";
- if (!(idsRaw && ids)) {
+ if (!idsRaw) {
ctx.body = [relationshopModel];
return;
}
@@ -316,9 +320,11 @@ export function apiAccountMastodon(router: Router): void {
ctx.body = data.data;
} catch (e: any) {
console.error(e);
- console.error(e.response.data);
+ let data = e.response.data;
+ data.users = users;
+ console.error(data);
ctx.status = 401;
- ctx.body = e.response.data;
+ ctx.body = data;
}
});
router.get("/v1/bookmarks", async (ctx) => {
diff --git a/packages/backend/src/server/api/mastodon/endpoints/meta.ts b/packages/backend/src/server/api/mastodon/endpoints/meta.ts
index a67edc5b2f..5fba6f8a63 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/meta.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/meta.ts
@@ -1,6 +1,9 @@
import { Entity } from "@calckey/megalodon";
+import { fetchMeta } from "@/misc/fetch-meta.js";
+
// TODO: add calckey features
-export function getInstance(response: Entity.Instance) {
+export async function getInstance(response: Entity.Instance) {
+ const meta = await fetchMeta(true);
return {
uri: response.uri,
title: response.title || "",
@@ -11,8 +14,8 @@ export function getInstance(response: Entity.Instance) {
urls: response.urls,
stats: response.stats,
thumbnail: response.thumbnail || "",
- languages: ["en", "de", "ja"],
- registrations: response.registrations,
+ languages: meta.langs,
+ registrations: !meta.disableRegistration || response.registrations,
approval_required: !response.registrations,
invites_enabled: response.registrations,
configuration: {
@@ -77,17 +80,17 @@ export function getInstance(response: Entity.Instance) {
bot: true,
discoverable: false,
group: false,
- created_at: "1971-01-01T00:00:00.000Z",
- note: "",
- url: "https://http.cat/404",
- avatar: "https://http.cat/404",
- avatar_static: "https://http.cat/404",
+ created_at: Math.floor(new Date().getTime() / 1000),
+ note: "Please refer to the original instance for the actual admin contact.",
+ url: "/",
+ avatar: "/static-assets/badges/info.png",
+ avatar_static: "/static-assets/badges/info.png",
header: "https://http.cat/404",
header_static: "https://http.cat/404",
followers_count: -1,
following_count: 0,
statuses_count: 0,
- last_status_at: "1971-01-01T00:00:00.000Z",
+ last_status_at: Math.floor(new Date().getTime() / 1000),
noindex: true,
emojis: [],
fields: [],
diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts
index 2be79c73a7..a72ac2c7e0 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/status.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts
@@ -404,7 +404,7 @@ async function getFirstReaction(
) {
const accessTokenArr = accessTokens?.split(" ") ?? [null];
const accessToken = accessTokenArr[accessTokenArr.length - 1];
- let react = "👍";
+ let react = "⭐";
try {
const api = await axios.post(`${BASE_URL}/api/i/registry/get-unsecure`, {
scope: ["client", "base"],
@@ -412,7 +412,7 @@ async function getFirstReaction(
i: accessToken,
});
const reactRaw = api.data;
- react = Array.isArray(reactRaw) ? api.data[0] : "👍";
+ react = Array.isArray(reactRaw) ? api.data[0] : "⭐";
console.log(api.data);
return react;
} catch (e) {
@@ -426,16 +426,16 @@ export function statusModel(
emojis: MastodonEntity.Emoji[],
content: string,
) {
- const now = "1970-01-02T00:00:00.000Z";
+ const now = Math.floor(new Date().getTime() / 1000);
return {
id: "9atm5frjhb",
uri: "https://http.cat/404", // ""
url: "https://http.cat/404", // "",
account: {
id: "9arzuvv0sw",
- username: "ReactionBot",
- acct: "ReactionBot",
- display_name: "ReactionsToThisPost",
+ username: "Reactions",
+ acct: "Reactions",
+ display_name: "Reactions to this post",
locked: false,
created_at: now,
followers_count: 0,
@@ -443,8 +443,8 @@ export function statusModel(
statuses_count: 0,
note: "",
url: "https://http.cat/404",
- avatar: "https://http.cat/404",
- avatar_static: "https://http.cat/404",
+ avatar: "/static-assets/badges/info.png",
+ avatar_static: "/static-assets/badges/info.png",
header: "https://http.cat/404", // ""
header_static: "https://http.cat/404", // ""
emojis: [],
diff --git a/packages/backend/src/server/web/bios.js b/packages/backend/src/server/web/bios.js
index 1acdafd1d5..e715a01068 100644
--- a/packages/backend/src/server/web/bios.js
+++ b/packages/backend/src/server/web/bios.js
@@ -1,7 +1,7 @@
-'use strict';
+"use strict";
window.onload = async () => {
- const account = JSON.parse(localStorage.getItem('account'));
+ const account = JSON.parse(localStorage.getItem("account"));
const i = account.token;
const api = (endpoint, data = {}) => {
@@ -10,42 +10,44 @@ window.onload = async () => {
if (i) data.i = i;
// Send request
- fetch(endpoint.indexOf('://') > -1 ? endpoint : `/api/${endpoint}`, {
- method: 'POST',
+ fetch(endpoint.indexOf("://") > -1 ? endpoint : `/api/${endpoint}`, {
+ method: "POST",
body: JSON.stringify(data),
- credentials: 'omit',
- cache: 'no-cache'
- }).then(async (res) => {
- const body = res.status === 204 ? null : await res.json();
+ credentials: "omit",
+ cache: "no-cache",
+ })
+ .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);
+ if (res.status === 200) {
+ resolve(body);
+ } else if (res.status === 204) {
+ resolve();
+ } else {
+ reject(body.error);
+ }
+ })
+ .catch(reject);
});
return promise;
};
- const content = document.getElementById('content');
+ const content = document.getElementById("content");
- document.getElementById('ls').addEventListener('click', () => {
- content.innerHTML = '';
+ document.getElementById("ls").addEventListener("click", () => {
+ content.innerHTML = "";
- const lsEditor = document.createElement('div');
- lsEditor.id = 'lsEditor';
+ const lsEditor = document.createElement("div");
+ lsEditor.id = "lsEditor";
- const adder = document.createElement('div');
- adder.classList.add('adder');
- const addKeyInput = document.createElement('input');
- const addValueTextarea = document.createElement('textarea');
- const addButton = document.createElement('button');
- addButton.textContent = 'Add';
- addButton.addEventListener('click', () => {
+ const adder = document.createElement("div");
+ adder.classList.add("adder");
+ const addKeyInput = document.createElement("input");
+ const addValueTextarea = document.createElement("textarea");
+ const addButton = document.createElement("button");
+ addButton.textContent = "Add";
+ addButton.addEventListener("click", () => {
localStorage.setItem(addKeyInput.value, addValueTextarea.value);
location.reload();
});
@@ -57,21 +59,21 @@ window.onload = async () => {
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
- const record = document.createElement('div');
- record.classList.add('record');
- const header = document.createElement('header');
+ const record = document.createElement("div");
+ record.classList.add("record");
+ const header = document.createElement("header");
header.textContent = k;
- const textarea = document.createElement('textarea');
+ const textarea = document.createElement("textarea");
textarea.textContent = localStorage.getItem(k);
- const saveButton = document.createElement('button');
- saveButton.textContent = 'Save';
- saveButton.addEventListener('click', () => {
+ const saveButton = document.createElement("button");
+ saveButton.textContent = "Save";
+ saveButton.addEventListener("click", () => {
localStorage.setItem(k, textarea.value);
location.reload();
});
- const removeButton = document.createElement('button');
- removeButton.textContent = 'Remove';
- removeButton.addEventListener('click', () => {
+ const removeButton = document.createElement("button");
+ removeButton.textContent = "Remove";
+ removeButton.addEventListener("click", () => {
localStorage.removeItem(k);
location.reload();
});
diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js
index f4e0707a93..e7e859d20c 100644
--- a/packages/backend/src/server/web/boot.js
+++ b/packages/backend/src/server/web/boot.js
@@ -9,120 +9,122 @@
* 注: webpackは介さないため、このファイルではrequireやimportは使えません。
*/
-'use strict';
+"use strict";
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
(async () => {
window.onerror = (e) => {
console.error(e);
- renderError('SOMETHING_HAPPENED', e);
+ renderError("SOMETHING_HAPPENED", e);
};
window.onunhandledrejection = (e) => {
console.error(e);
- renderError('SOMETHING_HAPPENED_IN_PROMISE', e);
+ renderError("SOMETHING_HAPPENED_IN_PROMISE", e);
};
//#region Detect language & fetch translations
- const v = localStorage.getItem('v') || VERSION;
+ const v = localStorage.getItem("v") || VERSION;
const supportedLangs = LANGS;
- let lang = localStorage.getItem('lang');
+ let lang = localStorage.getItem("lang");
if (lang == null || !supportedLangs.includes(lang)) {
if (supportedLangs.includes(navigator.language)) {
lang = navigator.language;
} else {
- lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
+ lang = supportedLangs.find((x) => x.split("-")[0] === navigator.language);
// Fallback
- if (lang == null) lang = 'en-US';
+ if (lang == null) lang = "en-US";
}
}
const res = await fetch(`/assets/locales/${lang}.${v}.json`);
if (res.status === 200) {
- localStorage.setItem('lang', lang);
- localStorage.setItem('locale', await res.text());
- localStorage.setItem('localeVersion', v);
+ localStorage.setItem("lang", lang);
+ localStorage.setItem("locale", await res.text());
+ localStorage.setItem("localeVersion", v);
} else {
await checkUpdate();
- renderError('LOCALE_FETCH');
+ renderError("LOCALE_FETCH");
return;
}
//#endregion
//#region Script
function importAppScript() {
- import(`/assets/${CLIENT_ENTRY}`)
- .catch(async e => {
- await checkUpdate();
- console.error(e);
- renderError('APP_IMPORT', e);
- });
+ import(`/assets/${CLIENT_ENTRY}`).catch(async (e) => {
+ await checkUpdate();
+ console.error(e);
+ renderError("APP_IMPORT", e);
+ });
}
// タイミングによっては、この時点でDOMの構築が済んでいる場合とそうでない場合とがある
- if (document.readyState !== 'loading') {
+ if (document.readyState !== "loading") {
importAppScript();
} else {
- window.addEventListener('DOMContentLoaded', () => {
+ window.addEventListener("DOMContentLoaded", () => {
importAppScript();
});
}
//#endregion
//#region Theme
- const theme = localStorage.getItem('theme');
+ const theme = localStorage.getItem("theme");
if (theme) {
for (const [k, v] of Object.entries(JSON.parse(theme))) {
document.documentElement.style.setProperty(`--${k}`, v.toString());
// HTMLの theme-color 適用
- if (k === 'htmlThemeColor') {
+ if (k === "htmlThemeColor") {
for (const tag of document.head.children) {
- if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') {
- tag.setAttribute('content', v);
+ if (
+ tag.tagName === "META" &&
+ tag.getAttribute("name") === "theme-color"
+ ) {
+ tag.setAttribute("content", v);
break;
}
}
}
}
}
- const colorSchema = localStorage.getItem('colorSchema');
+ const colorSchema = localStorage.getItem("colorSchema");
if (colorSchema) {
- document.documentElement.style.setProperty('color-schema', colorSchema);
+ document.documentElement.style.setProperty("color-schema", colorSchema);
}
//#endregion
- const fontSize = localStorage.getItem('fontSize');
+ const fontSize = localStorage.getItem("fontSize");
if (fontSize) {
- document.documentElement.classList.add('f-' + fontSize);
+ document.documentElement.classList.add("f-" + fontSize);
}
- const useSystemFont = localStorage.getItem('useSystemFont');
+ const useSystemFont = localStorage.getItem("useSystemFont");
if (useSystemFont) {
- document.documentElement.classList.add('useSystemFont');
+ document.documentElement.classList.add("useSystemFont");
}
- const wallpaper = localStorage.getItem('wallpaper');
+ const wallpaper = localStorage.getItem("wallpaper");
if (wallpaper) {
document.documentElement.style.backgroundImage = `url(${wallpaper})`;
}
- const customCss = localStorage.getItem('customCss');
+ const customCss = localStorage.getItem("customCss");
if (customCss && customCss.length > 0) {
- const style = document.createElement('style');
+ const style = document.createElement("style");
style.innerHTML = customCss;
document.head.appendChild(style);
}
async function addStyle(styleText) {
- let css = document.createElement('style');
+ let css = document.createElement("style");
css.appendChild(document.createTextNode(styleText));
document.head.appendChild(css);
}
function renderError(code, details) {
- let errorsElement = document.getElementById('errors');
+ let errorsElement = document.getElementById("errors");
if (!errorsElement) {
document.body.innerHTML = `
@@ -158,9 +160,9 @@