diff --git a/CALCKEY.md b/CALCKEY.md index b05d4064d..7ab6f1f94 100644 --- a/CALCKEY.md +++ b/CALCKEY.md @@ -57,7 +57,6 @@ - Quotes have solid border - Reply limit bug fixed - Make showing the update popup optional -- Obliteration of Ai-chan - [Make showing ads optional](https://github.com/misskey-dev/misskey/pull/8996) - [OAuth bearer token authentication](https://github.com/misskey-dev/misskey/pull/9021) - [Styled Repair Tools](https://github.com/misskey-dev/misskey/pull/8956) diff --git a/cypress/e2e/widgets.cy.js b/cypress/e2e/widgets.cy.js index db35a60b5..56ad95ee9 100644 --- a/cypress/e2e/widgets.cy.js +++ b/cypress/e2e/widgets.cy.js @@ -61,4 +61,5 @@ describe('After user signed in', () => { buildWidgetTest('jobQueue'); buildWidgetTest('button'); buildWidgetTest('aiscript'); + buildWidgetTest('aichan'); }); diff --git a/locales/en-US.yml b/locales/en-US.yml index f64a7c20d..212e49e4e 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1,6 +1,6 @@ --- _lang_: "English" -headlineMisskey: "An open source, decentralized social media platform that's free forever! 🚀" +headlineMisskey: "A network connected by notes" introMisskey: "Welcome! Calckey is an open source, decentralized microblogging service.\nCreate \"notes\" to share your thoughts with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀" monthAndDay: "{month}/{day}" search: "Search" diff --git a/packages/backend/src/models/schema/user.ts b/packages/backend/src/models/schema/user.ts index 218d861e5..1c8fe9785 100644 --- a/packages/backend/src/models/schema/user.ts +++ b/packages/backend/src/models/schema/user.ts @@ -15,7 +15,7 @@ export const packedUserLiteSchema = { username: { type: 'string', nullable: false, optional: false, - example: 'calc', + example: 'ai', }, host: { type: 'string', diff --git a/packages/backend/src/server/api/openapi/errors.ts b/packages/backend/src/server/api/openapi/errors.ts index e632b4a0f..d7f791c6d 100644 --- a/packages/backend/src/server/api/openapi/errors.ts +++ b/packages/backend/src/server/api/openapi/errors.ts @@ -34,11 +34,11 @@ export const errors = { }, }, '418': { - 'I_AM_CALC': { + 'I_AM_AI': { value: { error: { - message: 'You sent a request to Calc, Calckey\'s resident stoner furry, instead of the server.', - code: 'I_AM_CALC', + message: 'You sent a request to Ai-chan, Misskey\'s showgirl, instead of the server.', + code: 'I_AM_AI', id: '60c46cd1-f23a-46b1-bebe-5d2b73951a84', }, }, diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index 00769d100..5c48373d5 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -156,7 +156,7 @@ export function genOpenapiSpec() { }, }, '418': { - description: 'I\'m Calc', + description: 'I\'m Ai', content: { 'application/json': { schema: { diff --git a/packages/client/src/components/sample.vue b/packages/client/src/components/sample.vue index 48c7fe844..fddadd6e9 100644 --- a/packages/client/src/components/sample.vue +++ b/packages/client/src/components/sample.vue @@ -59,7 +59,7 @@ export default defineComponent({ async openDialog() { os.alert({ type: 'warning', - title: 'Oh my Calc', + title: 'Oh my Aichan', text: 'Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', }); }, diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 22b27fad0..021f19b12 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -57,6 +57,7 @@ {{ i18n.ts.disableDrawer }} {{ i18n.ts.showUpdates }} + {{ i18n.ts.aiChanMode }} @@ -145,6 +146,7 @@ const enterSendsMessage = computed(defaultStore.makeGetterSetter('enterSendsMess const useReactionPickerForContextMenu = computed(defaultStore.makeGetterSetter('useReactionPickerForContextMenu')); const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars')); const showUpdates = computed(defaultStore.makeGetterSetter('showUpdates')); +const aiChanMode = computed(defaultStore.makeGetterSetter('aiChanMode')); watch(lang, () => { localStorage.setItem('lang', lang.value as string); @@ -173,6 +175,7 @@ watch([ useSystemFont, enableInfiniteScroll, squareAvatars, + aiChanMode, showGapBetweenNotesInTimeline, instanceTicker, overridedDeviceKind, diff --git a/packages/client/src/pages/settings/preferences-backups.vue b/packages/client/src/pages/settings/preferences-backups.vue index b3aad708d..c7b4ee416 100644 --- a/packages/client/src/pages/settings/preferences-backups.vue +++ b/packages/client/src/pages/settings/preferences-backups.vue @@ -84,6 +84,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [ 'squareAvatars', 'numberOfPageCache', 'showUpdates', + 'aiChanMode', ]; const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ 'lightTheme', diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index 1f141b2c1..3b95e6531 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -247,6 +247,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: 5, }, + aiChanMode: { + where: 'device', + default: false, + }, enterSendsMessage: { where: 'device', default: true, diff --git a/packages/client/src/ui/classic.vue b/packages/client/src/ui/classic.vue index 3c2ca8e5d..c42407f5b 100644 --- a/packages/client/src/ui/classic.vue +++ b/packages/client/src/ui/classic.vue @@ -34,6 +34,8 @@ + + @@ -144,6 +146,28 @@ onMounted(() => { window.addEventListener('resize', () => { isDesktop = (window.innerWidth >= DESKTOP_THRESHOLD); }, { passive: true }); + + if (defaultStore.state.aiChanMode) { + const iframeRect = live2d.getBoundingClientRect(); + window.addEventListener('mousemove', ev => { + live2d.contentWindow.postMessage({ + type: 'moveCursor', + body: { + x: ev.clientX - iframeRect.left, + y: ev.clientY - iframeRect.top, + }, + }, '*'); + }, { passive: true }); + window.addEventListener('touchmove', ev => { + live2d.contentWindow.postMessage({ + type: 'moveCursor', + body: { + x: ev.touches[0].clientX - iframeRect.left, + y: ev.touches[0].clientY - iframeRect.top, + }, + }, '*'); + }, { passive: true }); + } }); diff --git a/packages/client/src/widgets/aichan.vue b/packages/client/src/widgets/aichan.vue new file mode 100644 index 000000000..828490fd9 --- /dev/null +++ b/packages/client/src/widgets/aichan.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/packages/client/src/widgets/index.ts b/packages/client/src/widgets/index.ts index 82d0f5ec8..66bec7c83 100644 --- a/packages/client/src/widgets/index.ts +++ b/packages/client/src/widgets/index.ts @@ -22,6 +22,7 @@ export default function(app: App) { app.component('MkwInstanceCloud', defineAsyncComponent(() => import('./instance-cloud.vue'))); app.component('MkwButton', defineAsyncComponent(() => import('./button.vue'))); app.component('MkwAiscript', defineAsyncComponent(() => import('./aiscript.vue'))); + app.component('MkwAichan', defineAsyncComponent(() => import('./aichan.vue'))); } export const widgets = [ @@ -46,4 +47,5 @@ export const widgets = [ 'jobQueue', 'button', 'aiscript', + 'aichan', ];