Merge branch 'develop' into block-deliver-by-software

This commit is contained in:
anatawa12 2025-04-02 09:34:12 +09:00 committed by GitHub
commit 7949a1aa07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
86 changed files with 923 additions and 561 deletions

View File

@ -22,7 +22,7 @@ jobs:
uses: pnpm/action-setup@v4.1.0
- name: Setup Node.js
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -14,7 +14,7 @@ jobs:
- name: Checkout head
uses: actions/checkout@v4.2.2
- name: Setup Node.js
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'

View File

@ -29,7 +29,7 @@ jobs:
- name: setup node
id: setup-node
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: pnpm

View File

@ -33,7 +33,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -38,7 +38,7 @@ jobs:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- uses: actions/setup-node@v4.2.0
- uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -69,13 +69,13 @@ jobs:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- uses: actions/setup-node@v4.2.0
- uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
- run: pnpm i --frozen-lockfile
- name: Restore eslint cache
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: ${{ env.eslint-cache-path }}
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
@ -99,7 +99,7 @@ jobs:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- uses: actions/setup-node@v4.2.0
- uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -20,7 +20,7 @@ jobs:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- uses: actions/setup-node@v4.2.0
- uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -26,7 +26,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -45,7 +45,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js 20.x
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -62,7 +62,7 @@ jobs:
fi
done
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
@ -109,7 +109,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -44,7 +44,7 @@ jobs:
fi
done
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -38,7 +38,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
@ -93,7 +93,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -33,7 +33,7 @@ jobs:
uses: pnpm/action-setup@v4.1.0
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -26,7 +26,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -27,7 +27,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.2.0
uses: actions/setup-node@v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

View File

@ -1,4 +1,4 @@
## 2025.3.2
## 2025.4.0
### General
- Feat: チャットがリニューアルして復活しました(beta)

View File

@ -1128,7 +1128,7 @@ pleaseAgreeAllToContinue: "Has d'acceptar tots els camps de dalt per poder conti
continue: "Continuar"
preservedUsernames: "Noms d'usuaris reservats"
preservedUsernamesDescription: "Llistat de noms d'usuaris que no es poden fer servir separats per salts de linia. Aquests noms d'usuaris no estaran disponibles quan es creï un compte d'usuari normal, però els administradors els poden fer servir per crear comptes manualment. Per altre banda els comptes ja creats amb aquests noms d'usuari no es veure'n afectats."
createNoteFromTheFile: "Compon una nota des d'aquest fitxer"
createNoteFromTheFile: "Escriu una nota incloent aquest fitxer"
archive: "Arxiu"
archived: "Arxivat"
unarchive: "Desarxivar"
@ -1336,6 +1336,9 @@ chat: "Xat"
migrateOldSettings: "Migració de la configuració antiga "
migrateOldSettings_description: "Normalment això es fa automàticament, però si la transició no es fa, el procés es pot iniciar manualment. S'esborrarà la configuració actual."
compress: "Comprimir "
right: "Dreta"
bottom: "A baix "
top: "A dalt "
_chat:
noMessagesYet: "Encara no tens missatges "
newMessage: "Missatge nou"
@ -2593,6 +2596,9 @@ _notification:
_deck:
alwaysShowMainColumn: "Mostrar sempre la columna principal"
columnAlign: "Alinea les columnes"
columnGap: "Espai entre columnes"
deckMenuPosition: "Posició del menú del tauler"
navbarPosition: "Posició de la barra de navegació "
addColumn: "Afig una columna"
newNoteNotificationSettings: "Configuració de notificacions per a notes noves"
configureColumn: "Configuració de columnes"

View File

@ -962,8 +962,8 @@ cropImageAsk: "Möchtest du das Bild zuschneiden?"
cropYes: "Zuschneiden"
cropNo: "Unbearbeitet verwenden"
file: "Datei"
recentNHours: "Letzten {n} Stunden"
recentNDays: "Letzten {n} Tage"
recentNHours: "Letzte {n} Stunden"
recentNDays: "Letzte {n} Tage"
noEmailServerWarning: "Es ist kein Email-Server konfiguriert."
thereIsUnresolvedAbuseReportWarning: "Es liegen ungelöste Meldungen vor."
recommended: "Empfehlung"
@ -971,7 +971,7 @@ check: "Check"
driveCapOverrideLabel: "Die Drive-Kapazität dieses Nutzers verändern"
driveCapOverrideCaption: "Gib einen Wert von 0 oder weniger ein, um die Kapazität auf den Standard zurückzusetzen."
requireAdminForView: "Melde dich mit einem Administratorkonto an, um dies einzusehen."
isSystemAccount: "Ein Benutzerkonto, dass durch das System erstellt und automatisch kontrolliert wird."
isSystemAccount: "Ein Benutzerkonto, das durch das System erstellt und automatisch verwaltet wird."
typeToConfirm: "Bitte gib zur Bestätigung {x} ein"
deleteAccount: "Benutzerkonto löschen"
document: "Dokumentation"

View File

@ -345,7 +345,7 @@ emptyDrive: "Your Drive is empty"
emptyFolder: "This folder is empty"
unableToDelete: "Unable to delete"
inputNewFileName: "Enter a new filename"
inputNewDescription: "Enter new caption"
inputNewDescription: "Enter new alt text"
inputNewFolderName: "Enter a new folder name"
circularReferenceFolder: "The destination folder is a subfolder of the folder you wish to move."
hasChildFilesOrFolders: "Since this folder is not empty, it can not be deleted."
@ -643,8 +643,8 @@ disablePlayer: "Close video player"
expandTweet: "Expand post"
themeEditor: "Theme editor"
description: "Description"
describeFile: "Add caption"
enterFileDescription: "Enter caption"
describeFile: "Add alt text"
enterFileDescription: "Enter alt text"
author: "Author"
leaveConfirm: "There are unsaved changes. Do you want to discard them?"
manage: "Management"
@ -1014,7 +1014,7 @@ sendPushNotificationReadMessageCaption: "This may increase the power consumption
windowMaximize: "Maximize"
windowMinimize: "Minimize"
windowRestore: "Restore"
caption: "Caption"
caption: "Alt text"
loggedInAsBot: "Currently logged in as bot"
tools: "Tools"
cannotLoad: "Unable to load"
@ -1336,6 +1336,9 @@ chat: "Chat"
migrateOldSettings: "Migrate old client settings"
migrateOldSettings_description: "This should be done automatically but if for some reason the migration was not successful, you can trigger the migration process yourself manually. The current configuration information will be overwritten."
compress: "Compress"
right: "Right"
bottom: "Bottom"
top: "Top"
_chat:
noMessagesYet: "No messages yet"
newMessage: "New message"
@ -2593,6 +2596,9 @@ _notification:
_deck:
alwaysShowMainColumn: "Always show main column"
columnAlign: "Align columns"
columnGap: "Margin between columns"
deckMenuPosition: "Deck menu position"
navbarPosition: "Navigation bar position"
addColumn: "Add column"
newNoteNotificationSettings: "Notification setting for new notes"
configureColumn: "Column settings"
@ -2606,7 +2612,7 @@ _deck:
newProfile: "New profile"
deleteProfile: "Delete profile"
introduction: "Create the perfect interface for you by arranging columns freely!"
introduction2: "Click on the + on the right of the screen to add new colums whenever you want."
introduction2: "Click on the + on the right of the screen to add new columns whenever you want."
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
useSimpleUiForNonRootPages: "Use simple UI for navigated pages"
usedAsMinWidthWhenFlexible: "Minimum width will be used for this when the \"Auto-adjust width\" option is enabled"

View File

@ -1295,6 +1295,7 @@ messageToFollower: "Mensaje a seguidores"
target: "Para"
federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador."
federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores"
preferences: "Preferencias"
postForm: "Formulario"
information: "Información"
_chat:

30
locales/index.d.ts vendored
View File

@ -5513,7 +5513,7 @@ export interface Locale extends ILocale {
*/
"thisUserAllowsChatOnlyFromFollowers": string;
/**
*
*
*/
"thisUserAllowsChatOnlyFromFollowing": string;
/**
@ -8251,23 +8251,19 @@ export interface Locale extends ILocale {
*/
"header": string;
/**
*
*
*/
"navBg": string;
/**
*
*
*/
"navFg": string;
/**
* ()
*/
"navHoverFg": string;
/**
* ()
* ()
*/
"navActive": string;
/**
*
*
*/
"navIndicator": string;
/**
@ -8287,7 +8283,7 @@ export interface Locale extends ILocale {
*/
"mentionMe": string;
/**
* Renote
*
*/
"renote": string;
/**
@ -8350,10 +8346,6 @@ export interface Locale extends ILocale {
*
*/
"driveFolderBg": string;
/**
*
*/
"wallpaperOverlay": string;
/**
*
*/
@ -8362,14 +8354,6 @@ export interface Locale extends ILocale {
*
*/
"messageBg": string;
/**
* ()
*/
"accentDarken": string;
/**
* ()
*/
"accentLighten": string;
/**
* 調
*/
@ -10158,7 +10142,7 @@ export interface Locale extends ILocale {
*/
"introduction": string;
/**
* +
* +
*/
"introduction2": string;
/**

View File

@ -1375,7 +1375,7 @@ _chat:
cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。"
chatWithThisUser: "チャットする"
thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのみチャットを受け付けています。"
thisUserAllowsChatOnlyFromFollowing: "このユーザーはフォローしているユーザーからのみチャットを受け付けています。"
thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしているユーザーからのみチャットを受け付けています。"
thisUserAllowsChatOnlyFromMutualFollowing: "このユーザーは相互フォローのユーザーからのみチャットを受け付けています。"
thisUserNotAllowedChatAnyone: "このユーザーは誰からもチャットを受け付けていません。"
chatAllowedUsers: "チャットを許可する相手"
@ -2165,16 +2165,15 @@ _theme:
panel: "パネル"
shadow: "影"
header: "ヘッダー"
navBg: "サイドバーの背景"
navFg: "サイドバーの文字"
navHoverFg: "サイドバー文字(ホバー)"
navActive: "サイドバー文字(アクティブ)"
navIndicator: "サイドバーのインジケーター"
navBg: "ナビゲーションバーの背景"
navFg: "ナビゲーションバーの文字"
navActive: "ナビゲーションバー文字(アクティブ)"
navIndicator: "ナビゲーションバーのインジケーター"
link: "リンク"
hashtag: "ハッシュタグ"
mention: "メンション"
mentionMe: "あなた宛てメンション"
renote: "Renote"
renote: "リノート"
modalBg: "モーダルの背景"
divider: "分割線"
scrollbarHandle: "スクロールバーの取っ手"
@ -2190,11 +2189,8 @@ _theme:
buttonHoverBg: "ボタンの背景 (ホバー)"
inputBorder: "入力ボックスの縁取り"
driveFolderBg: "ドライブフォルダーの背景"
wallpaperOverlay: "壁紙のオーバーレイ"
badge: "バッジ"
messageBg: "チャットの背景"
accentDarken: "アクセント (暗め)"
accentLighten: "アクセント (明るめ)"
fgHighlighted: "強調された文字"
_sfx:
@ -2685,7 +2681,7 @@ _deck:
newProfile: "新規プロファイル"
deleteProfile: "プロファイルを削除"
introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!"
introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。"
introduction2: "カラムを追加するには、画面の + をクリックします。"
widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください"
useSimpleUiForNonRootPages: "非ルートページは簡易UIで表示"
usedAsMinWidthWhenFlexible: "「幅を自動調整」が有効の場合、これが幅の最小値となります"

View File

@ -1336,6 +1336,9 @@ chat: "聊天"
migrateOldSettings: "迁移旧设置信息"
migrateOldSettings_description: "通常设置信息将自动迁移。但如果由于某种原因迁移不成功,则可以手动触发迁移过程。当前的配置信息将被覆盖。"
compress: "压缩"
right: "右"
bottom: "下"
top: "上"
_chat:
noMessagesYet: "还没有消息"
newMessage: "新消息"
@ -2593,6 +2596,9 @@ _notification:
_deck:
alwaysShowMainColumn: "总是显示主列"
columnAlign: "列对齐"
columnGap: "列间距"
deckMenuPosition: "Deck 菜单位置"
navbarPosition: "导航栏位置"
addColumn: "添加列"
newNoteNotificationSettings: "新帖子通知设定"
configureColumn: "列设置"
@ -2606,7 +2612,7 @@ _deck:
newProfile: "新建配置文件"
deleteProfile: "删除配置文件"
introduction: "将各列进行组合以创建您自己的界面!"
introduction2: "可以随时通过屏幕右侧的 + 来添加列"
introduction2: "可以随时通过屏幕右侧的 + 来添加列"
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"
useSimpleUiForNonRootPages: "用简易UI表示非根页面"
usedAsMinWidthWhenFlexible: "「自适应宽度」被启用的时候,这就是最小的宽度"

View File

@ -1336,6 +1336,9 @@ chat: "聊天"
migrateOldSettings: "遷移舊設定資訊"
migrateOldSettings_description: "通常情況下,這會自動進行,但若因某些原因未能順利遷移,您可以手動觸發遷移處理。請注意,當前的設定資訊將會被覆寫。"
compress: "壓縮"
right: "右"
bottom: "下"
top: "上"
_chat:
noMessagesYet: "尚無訊息"
newMessage: "新訊息"
@ -2593,6 +2596,9 @@ _notification:
_deck:
alwaysShowMainColumn: "總是顯示主欄"
columnAlign: "對齊欄位"
columnGap: "欄與欄之間的邊距"
deckMenuPosition: "多欄模式的選單位置"
navbarPosition: "導覽列位置"
addColumn: "新增欄位"
newNoteNotificationSettings: "新貼文通知的設定"
configureColumn: "欄位的設定"

View File

@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "2025.3.2-beta.18",
"version": "2025.4.0-beta.0",
"codename": "nasubi",
"repository": {
"type": "git",

View File

@ -127,11 +127,6 @@
document.documentElement.classList.add('useSystemFont');
}
const wallpaper = localStorage.getItem('wallpaper');
if (wallpaper) {
document.documentElement.style.backgroundImage = `url(${wallpaper})`;
}
const customCss = localStorage.getItem('customCss');
if (customCss && customCss.length > 0) {
const style = document.createElement('style');

View File

@ -34,7 +34,7 @@
"typescript": "5.8.2",
"uuid": "11.1.0",
"json5": "2.2.3",
"vite": "6.2.3",
"vite": "6.2.4",
"vue": "3.5.13"
},
"devDependencies": {

View File

@ -95,7 +95,7 @@ async function onclick(ev: MouseEvent) {
position: absolute;
border-radius: 6px;
background-color: var(--MI_THEME-fg);
color: var(--MI_THEME-accentLighten);
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
font-size: 12px;
opacity: .5;
padding: 5px 8px;
@ -153,7 +153,7 @@ html[data-color-scheme=light] .visible {
/* Hardcode to black because either --MI_THEME-bg or --MI_THEME-fg makes it hard to read in dark/light mode */
background-color: black;
border-radius: 6px;
color: var(--MI_THEME-accentLighten);
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
display: inline-block;
font-weight: bold;
font-size: 0.8em;

View File

@ -278,7 +278,7 @@ rt {
}
._acrylic {
background: var(--MI_THEME-acrylicPanel);
background: color(from var(--MI_THEME-panel) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -10,13 +10,10 @@
props: {
accent: '#86b300',
accentDarken: ':darken<10<@accent',
accentLighten: ':lighten<10<@accent',
accentedBg: ':alpha<0.15<@accent',
love: '#dd2e44',
focus: ':alpha<0.3<@accent',
bg: '#000',
acrylicBg: ':alpha<0.5<@bg',
fg: '#dadada',
fgTransparentWeak: ':alpha<0.75<@fg',
fgTransparent: ':alpha<0.5<@fg',
@ -31,14 +28,12 @@
panelHeaderFg: '@fg',
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
panelBorder: '" solid 1px var(--MI_THEME-divider)',
acrylicPanel: ':alpha<0.5<@panel',
windowHeader: ':alpha<0.85<@panel',
popup: ':lighten<3<@panel',
shadow: 'rgba(0, 0, 0, 0.3)',
header: ':alpha<0.7<@panel',
navBg: '@panel',
navFg: '@fg',
navHoverFg: ':lighten<17<@fg',
navActive: '@accent',
navIndicator: '@indicator',
link: '#44a4c1',
@ -68,7 +63,6 @@
inputBorder: 'rgba(255, 255, 255, 0.1)',
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
driveFolderBg: ':alpha<0.3<@accent',
wallpaperOverlay: 'rgba(0, 0, 0, 0.5)',
badge: '#31b1ce',
messageBg: '@bg',
success: '#86b300',

View File

@ -10,13 +10,10 @@
props: {
accent: '#86b300',
accentDarken: ':darken<10<@accent',
accentLighten: ':lighten<10<@accent',
accentedBg: ':alpha<0.15<@accent',
love: '#dd2e44',
focus: ':alpha<0.3<@accent',
bg: '#fff',
acrylicBg: ':alpha<0.5<@bg',
fg: '#5f5f5f',
fgTransparentWeak: ':alpha<0.75<@fg',
fgTransparent: ':alpha<0.5<@fg',
@ -31,14 +28,12 @@
panelHeaderFg: '@fg',
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
panelBorder: '" solid 1px var(--MI_THEME-divider)',
acrylicPanel: ':alpha<0.5<@panel',
windowHeader: ':alpha<0.85<@panel',
popup: ':lighten<3<@panel',
shadow: 'rgba(0, 0, 0, 0.1)',
header: ':alpha<0.7<@panel',
navBg: '@panel',
navFg: '@fg',
navHoverFg: ':darken<17<@fg',
navActive: '@accent',
navIndicator: '@indicator',
link: '#44a4c1',
@ -68,7 +63,6 @@
inputBorder: 'rgba(0, 0, 0, 0.1)',
inputBorderHover: 'rgba(0, 0, 0, 0.2)',
driveFolderBg: ':alpha<0.3<@accent',
wallpaperOverlay: 'rgba(255, 255, 255, 0.5)',
badge: '#31b1ce',
messageBg: '@bg',
success: '#86b300',

View File

@ -25,22 +25,17 @@
mention: '#ffd152',
modalBg: 'rgba(0, 0, 0, 0.5)',
success: '#86b300',
acrylicBg: ':alpha<0.5<@bg',
indicator: '@accent',
mentionMe: '#fb5d38',
messageBg: '@bg',
navActive: '@accent',
infoWarnBg: '#42321c',
infoWarnFg: '#ffbd3e',
navHoverFg: ':lighten<17<@fg',
dateLabelFg: '@fg',
inputBorder: 'rgba(255, 255, 255, 0.1)',
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
panelBorder: '" solid 1px var(--MI_THEME-divider)',
accentDarken: ':darken<10<@accent',
acrylicPanel: ':alpha<0.5<@panel',
navIndicator: '@accent',
accentLighten: ':lighten<10<@accent',
buttonGradateA: '@accent',
buttonGradateB: ':hue<-20<@accent',
driveFolderBg: ':alpha<0.3<@accent',
@ -51,7 +46,6 @@
fgOnWhite: '@accent',
panelHighlight: ':lighten<3<@panel',
scrollbarHandle: 'rgba(255, 255, 255, 0.2)',
wallpaperOverlay: 'rgba(0, 0, 0, 0.5)',
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',
},

View File

@ -31,7 +31,6 @@
modalBg: 'rgba(0, 0, 0, 0.5)',
success: '#86b300',
switchBg: 'rgba(255, 255, 255, 0.15)',
acrylicBg: ':alpha<0.5<@bg',
indicator: '@accent',
mentionMe: '@mention',
messageBg: '@bg',
@ -43,15 +42,11 @@
fgOnWhite: '@accent',
infoWarnBg: '#42321c',
infoWarnFg: '#ffbd3e',
navHoverFg: ':lighten<17<@fg',
codeBoolean: '#c59eff',
dateLabelFg: '@fg',
inputBorder: 'rgba(255, 255, 255, 0.1)',
panelBorder: '" solid 1px var(--MI_THEME-divider)',
accentDarken: ':darken<10<@accent',
acrylicPanel: ':alpha<0.5<@panel',
navIndicator: '@indicator',
accentLighten: ':lighten<10<@accent',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':lighten<3<@fg',
fgTransparent: ':alpha<0.5<@fg',
@ -63,7 +58,6 @@
panelHighlight: ':lighten<3<@panel',
scrollbarHandle: 'rgba(255, 255, 255, 0.2)',
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
wallpaperOverlay: 'rgba(0, 0, 0, 0.5)',
fgTransparentWeak: ':alpha<0.75<@fg',
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',

View File

@ -32,7 +32,6 @@
success: '#86b300',
buttonBg: '#0000000d',
switchBg: 'rgba(255, 255, 255, 0.15)',
acrylicBg: ':alpha<0.5<@bg',
indicator: '@accent',
mentionMe: '@mention',
messageBg: '@bg',
@ -44,15 +43,11 @@
fgOnWhite: '@accent',
infoWarnBg: '#42321c',
infoWarnFg: '#ffbd3e',
navHoverFg: ':lighten<17<@fg',
codeBoolean: '#c59eff',
dateLabelFg: '@fg',
inputBorder: 'rgba(255, 255, 255, 0.1)',
panelBorder: '" solid 1px var(--MI_THEME-divider)',
accentDarken: ':darken<10<@accent',
acrylicPanel: ':alpha<0.5<@panel',
navIndicator: '@indicator',
accentLighten: ':lighten<10<@accent',
buttonHoverBg: '#0000001a',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':lighten<3<@fg',
@ -65,7 +60,6 @@
panelHighlight: ':lighten<3<@panel',
scrollbarHandle: '#74747433',
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
wallpaperOverlay: 'rgba(0, 0, 0, 0.5)',
fgTransparentWeak: ':alpha<0.75<@fg',
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',

View File

@ -28,22 +28,17 @@
mention: '@accent',
modalBg: 'rgba(0, 0, 0, 0.3)',
success: '#86b300',
acrylicBg: ':alpha<0.5<@bg',
indicator: '@accent',
mentionMe: '@mention',
messageBg: '@bg',
navActive: '@accent',
infoWarnBg: '#fff0db',
infoWarnFg: '#8f6e31',
navHoverFg: ':darken<17<@fg',
dateLabelFg: '@fg',
inputBorder: 'rgba(0, 0, 0, 0.1)',
inputBorderHover: 'rgba(0, 0, 0, 0.2)',
panelBorder: '" solid 1px var(--MI_THEME-divider)',
accentDarken: ':darken<10<@accent',
acrylicPanel: ':alpha<0.5<@panel',
navIndicator: '@accent',
accentLighten: ':lighten<10<@accent',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':darken<3<@fg',
fgTransparent: ':alpha<0.5<@fg',
@ -53,7 +48,6 @@
htmlThemeColor: '@bg',
panelHighlight: ':darken<3<@panel',
scrollbarHandle: 'rgba(0, 0, 0, 0.2)',
wallpaperOverlay: 'rgba(255, 255, 255, 0.5)',
fgTransparentWeak: ':alpha<0.75<@fg',
panelHeaderDivider: '@divider',
scrollbarHandleHover: 'rgba(0, 0, 0, 0.4)',

View File

@ -74,7 +74,7 @@
"typescript": "5.8.2",
"uuid": "11.1.0",
"v-code-diff": "1.13.1",
"vite": "6.2.3",
"vite": "6.2.4",
"vue": "3.5.13",
"vuedraggable": "next",
"wanakana": "5.3.1"

View File

@ -420,7 +420,7 @@ onBeforeUnmount(() => {
}
&:active {
background: var(--MI_THEME-accentDarken);
background: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
color: #fff !important;
}
}

View File

@ -103,13 +103,13 @@ async function onClick() {
background: var(--MI_THEME-accent);
&:hover {
background: var(--MI_THEME-accentLighten);
border-color: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
border-color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
&:active {
background: var(--MI_THEME-accentDarken);
border-color: var(--MI_THEME-accentDarken);
background: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
border-color: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
}
}

View File

@ -151,11 +151,11 @@ function onDragend() {
background: var(--MI_THEME-accent);
&:hover {
background: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
&:active {
background: var(--MI_THEME-accentDarken);
background: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
}
> .label {

View File

@ -239,7 +239,7 @@ onMounted(() => {
bottom: var(--MI-stickyBottom, 0px);
left: 0;
padding: 12px;
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
background-size: auto auto;

View File

@ -211,13 +211,13 @@ onBeforeUnmount(() => {
background: var(--MI_THEME-accent);
&:hover {
background: var(--MI_THEME-accentLighten);
border-color: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
border-color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
&:active {
background: var(--MI_THEME-accentDarken);
border-color: var(--MI_THEME-accentDarken);
background: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
border-color: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
}
}

View File

@ -51,7 +51,7 @@ withDefaults(defineProps<{
padding-top: calc(var(--fukidashi-radius) * .13);
&.accented {
--fukidashi-bg: var(--MI_THEME-accent);
--fukidashi-bg: color-mix(in srgb, var(--MI_THEME-accent), var(--MI_THEME-panel) 85%);
}
&.shadow {
@ -87,6 +87,12 @@ withDefaults(defineProps<{
padding: 10px 14px;
}
@container (max-width: 450px) {
.content {
padding: 8px 12px;
}
}
.tail {
position: absolute;
top: 0;

View File

@ -220,7 +220,7 @@ function showMenu(ev: MouseEvent) {
position: absolute;
border-radius: 6px;
background-color: var(--MI_THEME-fg);
color: var(--MI_THEME-accentLighten);
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
font-size: 12px;
opacity: .5;
padding: 5px 8px;
@ -294,7 +294,7 @@ html[data-color-scheme=light] .visible {
/* Hardcode to black because either --MI_THEME-bg or --MI_THEME-fg makes it hard to read in dark/light mode */
background-color: black;
border-radius: 6px;
color: var(--MI_THEME-accentLighten);
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
display: inline-block;
font-weight: bold;
font-size: 0.8em;

View File

@ -553,7 +553,7 @@ onDeactivated(() => {
/* Hardcode to black because either --MI_THEME-bg or --MI_THEME-fg makes it hard to read in dark/light mode */
background-color: black;
border-radius: 6px;
color: var(--MI_THEME-accentLighten);
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
display: inline-block;
font-weight: bold;
font-size: 0.8em;
@ -565,7 +565,7 @@ onDeactivated(() => {
position: absolute;
border-radius: 6px;
background-color: var(--MI_THEME-fg);
color: var(--MI_THEME-accentLighten);
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
font-size: 12px;
opacity: .5;
padding: 5px 8px;

View File

@ -287,7 +287,7 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
border-radius: 999px;
&:hover {
background: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
}
}

View File

@ -125,7 +125,7 @@ async function done() {
left: 0;
padding: 12px;
border-top: solid 0.5px var(--MI_THEME-divider);
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -144,7 +144,7 @@ fetchRoles();
}
.roleItemArea {
background-color: var(--MI_THEME-acrylicBg);
background-color: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
border-radius: var(--MI-radius);
padding: 12px;
overflow-y: auto;

View File

@ -84,7 +84,7 @@ function onLogin(res: Misskey.entities.SigninFlowResponse & { finished: true })
align-items: center;
font-weight: bold;
backdrop-filter: var(--MI-blur, blur(15px));
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
z-index: 1;
}

View File

@ -280,7 +280,7 @@ onMounted(async () => {
left: 0;
padding: 12px;
border-top: solid 0.5px var(--MI_THEME-divider);
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -4,50 +4,48 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<svg
version="1.1"
viewBox="0 0 203.2 152.4"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<svg viewBox="0 0 200 150">
<g fill-rule="evenodd">
<rect width="203.2" height="152.4" :fill="themeVariables.bg" stroke-width=".26458" />
<rect width="65.498" height="152.4" :fill="themeVariables.panel" stroke-width=".26458" />
<rect x="65.498" width="137.7" height="40.892" :fill="themeVariables.acrylicBg" stroke-width=".265" />
<path transform="scale(.26458)" d="m439.77 247.19c-43.673 0-78.832 35.157-78.832 78.83v249.98h407.06v-328.81z" :fill="themeVariables.panel" />
<rect width="200" height="150" :fill="themeVariables.bg"/>
<rect width="64" height="150" :fill="themeVariables.navBg"/>
<rect x="64" width="136" height="41" :fill="themeVariables.bg"/>
<path transform="scale(.26458)" d="m439.77 247.19c-43.673 0-78.832 35.157-78.832 78.83v249.98h407.06v-328.81z" :fill="themeVariables.panel"/>
</g>
<circle cx="32.749" cy="83.054" r="21.132" :fill="themeVariables.accentedBg" stroke-dasharray="0.319256, 0.319256" stroke-width=".15963" style="paint-order:stroke fill markers" />
<circle cx="136.67" cy="106.76" r="23.876" :fill="themeVariables.fg" fill-opacity="0.5" stroke-dasharray="0.352425, 0.352425" stroke-width=".17621" style="paint-order:stroke fill markers" />
<g :fill="themeVariables.fg" fill-rule="evenodd" stroke-width=".26458">
<rect x="171.27" y="87.815" width="48.576" height="6.8747" ry="3.4373"/>
<rect x="171.27" y="105.09" width="48.576" height="6.875" ry="3.4375"/>
<rect x="171.27" y="121.28" width="48.576" height="6.875" ry="3.4375"/>
<rect x="171.27" y="137.47" width="48.576" height="6.875" ry="3.4375"/>
<circle cx="32" cy="83" r="21" :fill="themeVariables.accentedBg"/>
<g>
<rect x="120" y="88" width="40" height="6" ry="3" :fill="themeVariables.fg"/>
<rect x="170" y="88" width="20" height="6" ry="3" :fill="themeVariables.mention"/>
<rect x="120" y="108" width="20" height="6" ry="3" :fill="themeVariables.hashtag"/>
<rect x="150" y="108" width="40" height="6" ry="3" :fill="themeVariables.fg"/>
<rect x="120" y="128" width="40" height="6" ry="3" :fill="themeVariables.fg"/>
<rect x="170" y="128" width="20" height="6" ry="3" :fill="themeVariables.link"/>
</g>
<path d="m65.498 40.892h137.7" :stroke="themeVariables.divider" stroke-width="0.75" />
<path d="m65.498 40.892h137.7" :stroke="themeVariables.divider" stroke-width="0.75"/>
<g transform="matrix(.60823 0 0 .60823 25.45 75.755)" fill="none" :stroke="themeVariables.accent" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="m0 0h24v24h-24z" fill="none" stroke="none" />
<path d="m5 12h-2l9-9 9 9h-2" />
<path d="m5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-7" />
<path d="m9 21v-6a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6" />
<path d="m0 0h24v24h-24z" fill="none" stroke="none"/>
<path d="m5 12h-2l9-9 9 9h-2"/>
<path d="m5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-7"/>
<path d="m9 21v-6a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6"/>
</g>
<g transform="matrix(.61621 0 0 .61621 25.354 117.92)" fill="none" :stroke="themeVariables.fg" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="m0 0h24v24h-24z" fill="none" stroke="none" />
<path d="m10 5a2 2 0 1 1 4 0 7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2-3v-3a7 7 0 0 1 4-6" />
<path d="m9 17v1a3 3 0 0 0 6 0v-1" />
<path d="m0 0h24v24h-24z" fill="none" stroke="none"/>
<path d="m10 5a2 2 0 1 1 4 0 7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2-3v-3a7 7 0 0 1 4-6"/>
<path d="m9 17v1a3 3 0 0 0 6 0v-1"/>
</g>
<image x="20.948" y="18.388" width="23.602" height="23.602" image-rendering="optimizeSpeed" preserveAspectRatio="xMidYMid meet" v-bind="{ 'xlink:href': instance.iconUrl || '/favicon.ico' }" />
<circle cx="32" cy="32" r="16" :fill="themeVariables.accent"/>
<circle cx="140" cy="20" r="6" :fill="themeVariables.success"/>
<circle cx="160" cy="20" r="6" :fill="themeVariables.warn"/>
<circle cx="180" cy="20" r="6" :fill="themeVariables.error"/>
</svg>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
import { instance } from '@/instance.js';
import { compile } from '@/theme.js';
import type { Theme } from '@/theme.js';
import { deepClone } from '@/utility/clone.js';
import lightTheme from '@@/themes/_light.json5';
import darkTheme from '@@/themes/_dark.json5';
import type { Theme } from '@/theme.js';
import { compile } from '@/theme.js';
import { deepClone } from '@/utility/clone.js';
const props = defineProps<{
theme: Theme;
@ -55,20 +53,32 @@ const props = defineProps<{
const themeVariables = ref<{
bg: string;
acrylicBg: string;
panel: string;
fg: string;
mention: string;
hashtag: string;
link: string;
divider: string;
accent: string;
accentedBg: string;
navBg: string;
success: string;
warn: string;
error: string;
}>({
bg: 'var(--MI_THEME-bg)',
acrylicBg: 'var(--MI_THEME-acrylicBg)',
panel: 'var(--MI_THEME-panel)',
fg: 'var(--MI_THEME-fg)',
mention: 'var(--MI_THEME-mention)',
hashtag: 'var(--MI_THEME-hashtag)',
link: 'var(--MI_THEME-link)',
divider: 'var(--MI_THEME-divider)',
accent: 'var(--MI_THEME-accent)',
accentedBg: 'var(--MI_THEME-accentedBg)',
navBg: 'var(--MI_THEME-navBg)',
success: 'var(--MI_THEME-success)',
warn: 'var(--MI_THEME-warn)',
error: 'var(--MI_THEME-error)',
});
watch(() => props.theme, (theme) => {
@ -76,7 +86,7 @@ watch(() => props.theme, (theme) => {
const _theme = deepClone(theme);
if (_theme?.base != null) {
if (_theme.base != null) {
const base = [lightTheme, darkTheme].find(x => x.id === _theme.base);
if (base) _theme.props = Object.assign({}, base.props, _theme.props);
}
@ -85,12 +95,18 @@ watch(() => props.theme, (theme) => {
themeVariables.value = {
bg: compiled.bg ?? 'var(--MI_THEME-bg)',
acrylicBg: compiled.acrylicBg ?? 'var(--MI_THEME-acrylicBg)',
panel: compiled.panel ?? 'var(--MI_THEME-panel)',
fg: compiled.fg ?? 'var(--MI_THEME-fg)',
mention: compiled.mention ?? 'var(--MI_THEME-mention)',
hashtag: compiled.hashtag ?? 'var(--MI_THEME-hashtag)',
link: compiled.link ?? 'var(--MI_THEME-link)',
divider: compiled.divider ?? 'var(--MI_THEME-divider)',
accent: compiled.accent ?? 'var(--MI_THEME-accent)',
accentedBg: compiled.accentedBg ?? 'var(--MI_THEME-accentedBg)',
navBg: compiled.navBg ?? 'var(--MI_THEME-navBg)',
success: compiled.success ?? 'var(--MI_THEME-success)',
warn: compiled.warn ?? 'var(--MI_THEME-warn)',
error: compiled.error ?? 'var(--MI_THEME-error)',
};
}, { immediate: true });
</script>

View File

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div>
<MkAnimBg style="position: absolute;"/>
<div class="_pageScrollable" style="position: absolute; top: 0; width: 100%; height: 100%;">
<div class="_pageScrollable" :class="$style.body">
<slot></slot>
</div>
</div>
@ -17,5 +17,13 @@ import MkAnimBg from '@/components/MkAnimBg.vue';
</script>
<style lang="scss" module>
.body {
position: absolute;
top: 0;
width: 100%;
height: 100%;
// _pageScrollable
background: transparent !important;
}
</style>

View File

@ -345,7 +345,7 @@ $cellHeight: 28px;
border: solid 0.5px transparent;
&.selected {
border: solid 0.5px var(--MI_THEME-accentLighten);
border: solid 0.5px hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
&.ranged {

View File

@ -17,7 +17,6 @@ export type Keys = (
'lang' |
'drafts' |
'hashtags' |
'wallpaper' |
'colorScheme' |
'useSystemFont' |
'fontSize' |

View File

@ -296,7 +296,7 @@ onMounted(async () => {
left: 0;
padding: 12px;
border-top: solid 0.5px var(--MI_THEME-divider);
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -213,7 +213,7 @@ async function del() {
left: 0;
padding: 12px;
border-top: solid 0.5px var(--MI_THEME-divider);
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -273,7 +273,7 @@ definePage(() => ({
.footer {
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
border-top: solid 0.5px var(--MI_THEME-divider);
}

View File

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="[$style.root, { [$style.isMe]: isMe }]">
<MkAvatar :class="$style.avatar" :user="message.fromUser" :link="!isMe" :preview="false"/>
<div :class="$style.body" @contextmenu.stop="onContextmenu">
<div v-if="!isMe && prefer.s['chat.showSenderName']" :class="$style.header"><MkUserName :user="message.fromUser"/></div>
<div :class="$style.header"><MkUserName v-if="!isMe && prefer.s['chat.showSenderName']" :user="message.fromUser"/></div>
<MkFukidashi :class="$style.fukidashi" :tail="isMe ? 'right' : 'left'" :accented="isMe">
<div v-if="!message.isDeleted" :class="$style.content">
<Mfm
@ -216,10 +216,6 @@ function showMenu(ev: MouseEvent, contextmenu = false) {
flex-direction: row-reverse;
text-align: right;
.content {
color: var(--MI_THEME-fgOnAccent);
}
.footer {
flex-direction: row-reverse;
}
@ -230,8 +226,27 @@ function showMenu(ev: MouseEvent, contextmenu = false) {
position: sticky;
top: calc(16px + var(--MI-stickyTop, 0px));
display: block;
width: 52px;
height: 52px;
width: 50px;
height: 50px;
}
@container (max-width: 450px) {
.root {
&.isMe {
.avatar {
display: none;
}
}
}
.avatar {
width: 42px;
height: 42px;
}
.fukidashi {
font-size: 90%;
}
}
.body {
@ -239,6 +254,7 @@ function showMenu(ev: MouseEvent, contextmenu = false) {
}
.header {
min-height: 4px; // fukidashi調
font-size: 80%;
}
@ -252,9 +268,6 @@ function showMenu(ev: MouseEvent, contextmenu = false) {
word-break: break-word;
}
.file {
}
.footer {
display: flex;
flex-direction: row;

View File

@ -119,7 +119,8 @@ function start(ev: MouseEvent) {
}
async function startUser() {
os.selectUser().then(user => {
// TODO: localOnly
os.selectUser({ localOnly: true }).then(user => {
router.push(`/chat/user/${user.id}`);
});
}

View File

@ -63,11 +63,11 @@ function save() {
async function del() {
const { canceled } = await os.confirm({
type: 'warning',
text: i18n.ts.areYouSure,
text: i18n.tsx.deleteAreYouSure({ x: name_.value }),
});
if (canceled) return;
misskeyApi('chat/rooms/delete', {
await os.apiWithDialog('chat/rooms/delete', {
roomId: props.room.id,
});
router.push('/chat');
@ -81,10 +81,6 @@ watch(isMuted, async () => {
mute: isMuted.value,
});
});
onMounted(async () => {
});
</script>
<style lang="scss" module>

View File

@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkUserCardMini :user="room.owner"/>
</MkA>
<hr>
<hr v-if="memberships.length > 0">
<div v-for="membership in memberships" :key="membership.id" :class="$style.membership">
<MkA :class="$style.membershipBody" :to="`${userPage(membership.user)}`">

View File

@ -9,20 +9,25 @@ SPDX-License-Identifier: AGPL-3.0-only
v-model="searchQuery"
:placeholder="i18n.ts._chat.searchMessages"
type="search"
@enter="search()"
>
<template #prefix><i class="ti ti-search"></i></template>
</MkInput>
<MkButton v-if="searchQuery.length > 0" primary rounded @click="search">{{ i18n.ts.search }}</MkButton>
<MkButton primary rounded @click="search">{{ i18n.ts.search }}</MkButton>
<MkFoldableSection v-if="searched">
<template #header>{{ i18n.ts.searchResult }}</template>
<div class="_gaps_s">
<div v-if="searchResults.length > 0" class="_gaps_s">
<div v-for="message in searchResults" :key="message.id" :class="$style.searchResultItem">
<XMessage :message="message" :user="message.fromUser" :isSearchResult="true"/>
</div>
</div>
<div v-else class="_fullinfo">
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.notFound }}</div>
</div>
</MkFoldableSection>
</div>
</template>
@ -33,6 +38,7 @@ import * as Misskey from 'misskey-js';
import XMessage from './XMessage.vue';
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import * as os from '@/os.js';
import MkInput from '@/components/MkInput.vue';

View File

@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<Transition name="fade">
<div v-show="showIndicator" :class="$style.new">
<button class="_buttonPrimary" :class="$style.newButton" @click="onIndicatorClick">
<i class="fas ti-fw fa-arrow-circle-down" :class="$style.newIcon"></i>{{ i18n.ts.newMessageExists }}
<i class="fas ti-fw fa-arrow-circle-down" :class="$style.newIcon"></i>{{ i18n.ts._chat.newMessage }}
</button>
</div>
</Transition>
@ -391,6 +391,7 @@ const headerActions = computed(() => [{
definePage(computed(() => !initializing.value ? user.value ? {
userName: user,
title: user.value.name ?? user.value.username,
avatar: user,
} : {
title: room.value?.name,

View File

@ -245,7 +245,7 @@ async function del() {
left: 0;
padding: 12px;
border-top: solid 0.5px var(--MI_THEME-divider);
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -467,7 +467,7 @@ definePage(() => ({
<style lang="scss" module>
.footer {
backdrop-filter: var(--MI-blur, blur(15px));
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
border-top: solid .5px var(--MI_THEME-divider);
}
</style>

View File

@ -292,7 +292,7 @@ onUnmounted(() => {
.footer {
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
border-top: solid 0.5px var(--MI_THEME-divider);
}
</style>

View File

@ -12,6 +12,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</SearchMarker>
<hr>
<SearchMarker :keywords="['ui', 'root', 'page']">
<MkPreferenceContainer k="deck.useSimpleUiForNonRootPages">
<MkSwitch v-model="useSimpleUiForNonRootPages">
@ -74,19 +76,29 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkRange>
</MkPreferenceContainer>
</SearchMarker>
<SearchMarker :keywords="['wallpaper']">
<MkPreferenceContainer k="deck.wallpaper">
<MkButton v-if="wallpaper == null" @click="setWallpaper"><SearchLabel>{{ i18n.ts.setWallpaper }}</SearchLabel></MkButton>
<MkButton v-else @click="wallpaper = null">{{ i18n.ts.removeWallpaper }}</MkButton>
</MkPreferenceContainer>
</SearchMarker>
</div>
</SearchMarker>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkRadios from '@/components/MkRadios.vue';
import MkRange from '@/components/MkRange.vue';
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js';
import { prefer } from '@/preferences.js';
import MkPreferenceContainer from '@/components/MkPreferenceContainer.vue';
import { reloadAsk } from '@/utility/reload-ask.js';
import { selectFile } from '@/utility/select-file.js';
const navWindow = prefer.model('deck.navWindow');
const useSimpleUiForNonRootPages = prefer.model('deck.useSimpleUiForNonRootPages');
@ -95,6 +107,17 @@ const columnAlign = prefer.model('deck.columnAlign');
const columnGap = prefer.model('deck.columnGap');
const menuPosition = prefer.model('deck.menuPosition');
const navbarPosition = prefer.model('deck.navbarPosition');
const wallpaper = prefer.model('deck.wallpaper');
watch(wallpaper, async () => {
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
});
function setWallpaper(ev: MouseEvent) {
selectFile(ev.currentTarget ?? ev.target, null).then(file => {
wallpaper.value = file.url;
});
}
const profilesSyncEnabled = ref(prefer.isSyncEnabled('deck.profiles'));

View File

@ -38,14 +38,13 @@ import MkTextarea from '@/components/MkTextarea.vue';
import MkSelect from '@/components/MkSelect.vue';
import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue';
import { getBuiltinThemesRef } from '@/theme.js';
import { getBuiltinThemesRef, getThemesRef, removeTheme } from '@/theme.js';
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
import * as os from '@/os.js';
import { getThemes, removeTheme } from '@/theme-store.js';
import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js';
const installedThemes = ref(getThemes());
const installedThemes = getThemesRef();
const builtinThemes = getBuiltinThemesRef();
const selectedThemeId = ref<string | null>(null);

View File

@ -189,17 +189,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<FormLink to="/theme-editor"><template #icon><i class="ti ti-paint"></i></template>{{ i18n.ts._theme.make }}</FormLink>
</div>
</FormSection>
<SearchMarker :keywords="['wallpaper']">
<MkButton v-if="wallpaper == null" @click="setWallpaper"><SearchLabel>{{ i18n.ts.setWallpaper }}</SearchLabel></MkButton>
<MkButton v-else @click="wallpaper = null">{{ i18n.ts.removeWallpaper }}</MkButton>
</SearchMarker>
</div>
</SearchMarker>
</template>
<script lang="ts" setup>
import { computed, onActivated, ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import JSON5 from 'json5';
import defaultLightTheme from '@@/themes/l-light.json5';
import defaultDarkTheme from '@@/themes/d-green-lime.json5';
@ -207,23 +202,21 @@ import type { Theme } from '@/theme.js';
import MkSwitch from '@/components/MkSwitch.vue';
import FormSection from '@/components/form/section.vue';
import FormLink from '@/components/form/link.vue';
import MkButton from '@/components/MkButton.vue';
import MkFolder from '@/components/MkFolder.vue';
import MkThemePreview from '@/components/MkThemePreview.vue';
import { getBuiltinThemesRef } from '@/theme.js';
import { getBuiltinThemesRef, getThemesRef } from '@/theme.js';
import { selectFile } from '@/utility/select-file.js';
import { isDeviceDarkmode } from '@/utility/is-device-darkmode.js';
import { store } from '@/store.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { uniqueBy } from '@/utility/array.js';
import { getThemes } from '@/theme-store.js';
import { definePage } from '@/page.js';
import { miLocalStorage } from '@/local-storage.js';
import { reloadAsk } from '@/utility/reload-ask.js';
import { prefer } from '@/preferences.js';
const installedThemes = ref(getThemes());
const installedThemes = getThemesRef();
const builtinThemes = getBuiltinThemesRef();
const instanceDarkTheme = computed<Theme | null>(() => instance.defaultDarkTheme ? JSON5.parse(instance.defaultDarkTheme) : null);
@ -263,7 +256,6 @@ const lightThemeId = computed({
const darkMode = computed(store.makeGetterSetter('darkMode'));
const syncDeviceDarkMode = prefer.model('syncDeviceDarkMode');
const wallpaper = ref(miLocalStorage.getItem('wallpaper'));
const themesCount = installedThemes.value.length;
watch(syncDeviceDarkMode, () => {
@ -272,25 +264,6 @@ watch(syncDeviceDarkMode, () => {
}
});
watch(wallpaper, async () => {
if (wallpaper.value == null) {
miLocalStorage.removeItem('wallpaper');
} else {
miLocalStorage.setItem('wallpaper', wallpaper.value);
}
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
});
onActivated(() => {
installedThemes.value = getThemes();
});
function setWallpaper(event) {
selectFile(event.currentTarget ?? event.target, null).then(file => {
wallpaper.value = file.url;
});
}
const headerActions = computed(() => []);
const headerTabs = computed(() => []);

View File

@ -77,7 +77,7 @@ definePage(() => ({
.footer {
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
background: var(--MI_THEME-acrylicBg);
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
border-top: solid 0.5px var(--MI_THEME-divider);
display: flex;
}

View File

@ -86,10 +86,9 @@ import MkCodeEditor from '@/components/MkCodeEditor.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import MkFolder from '@/components/MkFolder.vue';
import { $i } from '@/i.js';
import { applyTheme } from '@/theme.js';
import { addTheme, applyTheme } from '@/theme.js';
import * as os from '@/os.js';
import { store } from '@/store.js';
import { addTheme } from '@/theme-store.js';
import { i18n } from '@/i18n.js';
import { useLeaveGuard } from '@/use/use-leave-guard.js';
import { definePage } from '@/page.js';

View File

@ -151,7 +151,7 @@ misskeyApiGet('federation/instances', {
left: 0;
right: 0;
margin: auto;
background: var(--MI_THEME-acrylicPanel);
background: color(from var(--MI_THEME-panel) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
border-radius: 999px;

View File

@ -382,6 +382,9 @@ export const PREF_DEF = {
'deck.navbarPosition': {
default: 'left' as 'left' | 'top' | 'bottom',
},
'deck.wallpaper': {
default: null as string | null,
},
'chat.showSenderName': {
default: false,

View File

@ -398,7 +398,7 @@ rt {
}
._acrylic {
background: var(--MI_THEME-acrylicPanel);
background: color(from var(--MI_THEME-panel) srgb r g b / 0.5);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
}

View File

@ -1,33 +0,0 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { Theme } from '@/theme.js';
import { getBuiltinThemes } from '@/theme.js';
import { $i } from '@/i.js';
import { prefer } from '@/preferences.js';
export function getThemes(): Theme[] {
if ($i == null) return [];
return prefer.s.themes;
}
export async function addTheme(theme: Theme): Promise<void> {
if ($i == null) return;
const builtinThemes = await getBuiltinThemes();
if (builtinThemes.some(t => t.id === theme.id)) {
throw new Error('builtin theme');
}
const themes = getThemes();
if (themes.some(t => t.id === theme.id)) {
throw new Error('already exists');
}
prefer.commit('themes', [...themes, theme]);
}
export async function removeTheme(theme: Theme): Promise<void> {
if ($i == null) return;
const themes = getThemes().filter(t => t.id !== theme.id);
prefer.commit('themes', themes);
}

View File

@ -8,11 +8,13 @@ import tinycolor from 'tinycolor2';
import lightTheme from '@@/themes/_light.json5';
import darkTheme from '@@/themes/_dark.json5';
import JSON5 from 'json5';
import type { Ref } from 'vue';
import type { BundledTheme } from 'shiki/themes';
import { deepClone } from '@/utility/clone.js';
import { globalEvents } from '@/events.js';
import { miLocalStorage } from '@/local-storage.js';
import { addTheme, getThemes } from '@/theme-store.js';
import { $i } from '@/i.js';
import { prefer } from '@/preferences.js';
export type Theme = {
id: string;
@ -57,11 +59,34 @@ export const getBuiltinThemes = () => Promise.all(
].map(name => import(`@@/themes/${name}.json5`).then(({ default: _default }): Theme => _default)),
);
export const getBuiltinThemesRef = () => {
export function getBuiltinThemesRef() {
const builtinThemes = ref<Theme[]>([]);
getBuiltinThemes().then(themes => builtinThemes.value = themes);
return builtinThemes;
};
}
export function getThemesRef(): Ref<Theme[]> {
return prefer.r.themes;
}
export async function addTheme(theme: Theme): Promise<void> {
if ($i == null) return;
const builtinThemes = await getBuiltinThemes();
if (builtinThemes.some(t => t.id === theme.id)) {
throw new Error('builtin theme');
}
const themes = prefer.s.themes;
if (themes.some(t => t.id === theme.id)) {
throw new Error('already exists');
}
prefer.commit('themes', [...themes, theme]);
}
export async function removeTheme(theme: Theme): Promise<void> {
if ($i == null) return;
const themes = prefer.s.themes.filter(t => t.id !== theme.id);
prefer.commit('themes', themes);
}
let timeout: number | null = null;
@ -173,7 +198,7 @@ export function parseThemeCode(code: string): Theme {
if (!validateTheme(theme)) {
throw new Error('This theme is invaild');
}
if (getThemes().some(t => t.id === theme.id)) {
if (prefer.s.themes.some(t => t.id === theme.id)) {
throw new Error('This theme is already installed');
}

View File

@ -159,7 +159,7 @@ function more() {
&:hover, &.active {
&::before {
background: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
}
}
@ -221,7 +221,7 @@ function more() {
&:hover {
text-decoration: none;
color: var(--MI_THEME-navHoverFg);
color: light-dark(hsl(from var(--MI_THEME-navFg) h s calc(l - 17)), hsl(from var(--MI_THEME-navFg) h s calc(l + 17)));
}
&.active {

View File

@ -149,7 +149,7 @@ onMounted(() => {
&:hover {
text-decoration: none;
color: var(--MI_THEME-navHoverFg);
color: light-dark(hsl(from var(--MI_THEME-navFg) h s calc(l - 17)), hsl(from var(--MI_THEME-navFg) h s calc(l + 17)));
}
&.active {

View File

@ -382,7 +382,7 @@ function menuEdit() {
&:hover, &.active {
&::before {
background: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
}
}
@ -456,7 +456,7 @@ function menuEdit() {
&:hover {
text-decoration: none;
color: var(--MI_THEME-navHoverFg);
color: light-dark(hsl(from var(--MI_THEME-navFg) h s calc(l - 17)), hsl(from var(--MI_THEME-navFg) h s calc(l + 17)));
}
&.active {
@ -612,7 +612,7 @@ function menuEdit() {
&:hover, &.active {
&::before {
background: var(--MI_THEME-accentLighten);
background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
}
}
}

View File

@ -35,7 +35,6 @@ SPDX-License-Identifier: AGPL-3.0-only
</section>
<div v-if="layout.length === 0" class="_panel" :class="$style.onboarding">
<div>{{ i18n.ts._deck.introduction }}</div>
<MkButton primary style="margin: 1em auto;" @click="addColumn">{{ i18n.ts._deck.addColumn }}</MkButton>
<div>{{ i18n.ts._deck.introduction2 }}</div>
</div>
</div>
@ -49,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
</div>
<div :class="$style.sideMenuBottom">
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings"></i></button>
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
</div>
</div>
</div>
@ -63,7 +62,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.bottomMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
</div>
<div :class="$style.bottomMenuRight">
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.bottomMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings"></i></button>
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.bottomMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
</div>
</div>
@ -113,13 +112,12 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, useTemplateRef, watch } from 'vue';
import { computed, defineAsyncComponent, ref, useTemplateRef } from 'vue';
import { v4 as uuid } from 'uuid';
import XCommon from './_common_/common.vue';
import XSidebar from '@/ui/_common_/navbar.vue';
import XNavbarH from '@/ui/_common_/navbar-h.vue';
import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
import { navbarItemDef } from '@/navbar.js';
import { $i } from '@/i.js';
@ -138,7 +136,6 @@ import XDirectColumn from '@/ui/deck/direct-column.vue';
import XRoleTimelineColumn from '@/ui/deck/role-timeline-column.vue';
import { mainRouter } from '@/router.js';
import { columns, layout, columnTypes, switchProfileMenu, addColumn as addColumnToStore, deleteProfile as deleteProfile_ } from '@/deck.js';
import { miLocalStorage } from '@/local-storage.js';
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
const XAnnouncements = defineAsyncComponent(() => import('@/ui/_common_/announcements.vue'));
@ -172,7 +169,7 @@ window.addEventListener('resize', () => {
});
const snapScroll = deviceKind === 'smartphone' || deviceKind === 'tablet';
const withWallpaper = miLocalStorage.getItem('wallpaper') != null;
const withWallpaper = prefer.s['deck.wallpaper'] != null;
const drawerMenuShowing = ref(false);
const gap = prefer.r['deck.columnGap'];
@ -228,9 +225,6 @@ function onWheel(ev: WheelEvent) {
}
}
window.document.documentElement.style.overflowY = 'hidden';
window.document.documentElement.style.scrollBehavior = 'auto';
async function deleteProfile() {
if (prefer.s['deck.profile'] == null) return;
@ -245,6 +239,12 @@ async function deleteProfile() {
os.success();
}
window.document.documentElement.style.overflowY = 'hidden';
window.document.documentElement.style.scrollBehavior = 'auto';
if (prefer.s['deck.wallpaper'] != null) {
window.document.documentElement.style.backgroundImage = `url(${prefer.s['deck.wallpaper']})`;
}
</script>
<style lang="scss" module>

View File

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div
:class="[$style.root, { [$style.paged]: isMainColumn, [$style.naked]: naked, [$style.active]: active, [$style.draghover]: draghover, [$style.dragging]: dragging, [$style.dropready]: dropready }]"
:class="[$style.root, { [$style.paged]: isMainColumn, [$style.naked]: naked, [$style.active]: active, [$style.draghover]: draghover, [$style.dragging]: dragging, [$style.dropready]: dropready, [$style.withWallpaper]: withWallpaper }]"
@dragover.prevent.stop="onDragover"
@dragleave="onDragleave"
@drop.prevent.stop="onDrop"
@ -48,11 +48,14 @@ import type { MenuItem } from '@/types/menu.js';
import { updateColumn, swapLeftColumn, swapRightColumn, swapUpColumn, swapDownColumn, stackLeftColumn, popRightColumn, removeColumn, swapColumn } from '@/deck.js';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { prefer } from '@/preferences.js';
provide('shouldHeaderThin', true);
provide('shouldOmitHeaderTitle', true);
provide('forceSpacerMin', true);
const withWallpaper = prefer.s['deck.wallpaper'] != null;
const props = withDefaults(defineProps<{
column: Column;
isStacked?: boolean;
@ -352,9 +355,7 @@ function onDrop(ev) {
}
&.naked {
background: var(--MI_THEME-acrylicBg) !important;
-webkit-backdrop-filter: var(--MI-blur, blur(10px));
backdrop-filter: var(--MI-blur, blur(10px));
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5) !important;
> .header {
background: transparent;
@ -372,6 +373,22 @@ function onDrop(ev) {
}
}
&.withWallpaper {
&.naked {
background: color(from var(--MI_THEME-bg) srgb r g b / 0.75) !important;
-webkit-backdrop-filter: var(--MI-blur, blur(10px));
backdrop-filter: var(--MI-blur, blur(10px));
> .header {
color: light-dark(#000000bf, #ffffffbf);
}
}
.tabShape {
display: none;
}
}
&.paged {
background: var(--MI_THEME-bg) !important;

View File

@ -37,11 +37,6 @@ export const searchIndexes: SearchIndexItem[] = [
label: i18n.ts.themeForDarkMode,
keywords: ['dark', 'theme'],
},
{
id: '8wcoRp76b',
label: i18n.ts.setWallpaper,
keywords: ['wallpaper'],
},
],
label: i18n.ts.theme,
keywords: ['theme'],
@ -861,40 +856,45 @@ export const searchIndexes: SearchIndexItem[] = [
keywords: ['sync', 'profiles', 'devices'],
},
{
id: 'iEF0gqNAo',
id: 'wWH4pxMQN',
label: i18n.ts._deck.useSimpleUiForNonRootPages,
keywords: ['ui', 'root', 'page'],
},
{
id: 'BNdSeWxZn',
id: '3LR509BvD',
label: i18n.ts.defaultNavigationBehaviour,
keywords: ['default', 'navigation', 'behaviour', 'window'],
},
{
id: 'zT9pGm8DF',
id: 'ybU8RLXgm',
label: i18n.ts._deck.alwaysShowMainColumn,
keywords: ['always', 'show', 'main', 'column'],
},
{
id: '5dk2xv1vc',
id: 'xRasZyAVl',
label: i18n.ts._deck.columnAlign,
keywords: ['column', 'align'],
},
{
id: 'gtdEA4FTa',
id: '6qcyPd0oJ',
label: i18n.ts._deck.deckMenuPosition,
keywords: ['menu', 'position'],
},
{
id: 'DHVFdPBT6',
id: '4zk2Now4S',
label: i18n.ts._deck.navbarPosition,
keywords: ['navbar', 'position'],
},
{
id: '3UQ8rUssZ',
id: 'CGNtJ2I3n',
label: i18n.ts._deck.columnGap,
keywords: ['column', 'gap', 'margin'],
},
{
id: 'rxPDMo7bE',
label: i18n.ts.setWallpaper,
keywords: ['wallpaper'],
},
],
label: i18n.ts.deck,
keywords: ['deck', 'ui'],

View File

@ -9,9 +9,9 @@ import type { toHiragana as toHiraganaType } from 'wanakana';
let toHiragana: typeof toHiraganaType = (str?: string) => str ?? '';
let isWanakanaLoaded = false;
/**
/**
* lazy-loading
*
*
* 使
*/
export async function initIntlString(forceWanakana = false) {
@ -82,16 +82,17 @@ export function normalizeStringWithHiragana(str: string) {
/** aとbが同じかどうか */
export function compareStringEquals(a: string, b: string) {
return (
normalizeString(a) === normalizeString(b) ||
normalizeStringWithHiragana(a) === normalizeStringWithHiragana(b)
);
if (a === b) return true; // まったく同じ場合はtrue。なお、ーマライズ前後で文字数が変化することがあるため、文字数が違うからといってfalseにはできない
if (normalizeString(a) === normalizeString(b)) return true;
if (normalizeStringWithHiragana(a) === normalizeStringWithHiragana(b)) return true;
return false;
}
/** baseにqueryが含まれているかどうか */
export function compareStringIncludes(base: string, query: string) {
return (
normalizeString(base).includes(normalizeString(query)) ||
normalizeStringWithHiragana(base).includes(normalizeStringWithHiragana(query))
);
if (base === query) return true; // まったく同じ場合は含まれていると考えてよいのでtrue
if (base.includes(query)) return true;
if (normalizeString(base).includes(normalizeString(query))) return true;
if (normalizeStringWithHiragana(base).includes(normalizeStringWithHiragana(query))) return true;
return false;
}

View File

@ -8,9 +8,9 @@
},
"devDependencies": {
"@readme/openapi-parser": "2.7.0",
"@types/node": "22.13.9",
"@typescript-eslint/eslint-plugin": "8.26.0",
"@typescript-eslint/parser": "8.26.0",
"@types/node": "22.13.15",
"@typescript-eslint/eslint-plugin": "8.29.0",
"@typescript-eslint/parser": "8.29.0",
"openapi-types": "12.1.3",
"openapi-typescript": "6.7.6",
"ts-case-convert": "2.1.0",

View File

@ -1,7 +1,7 @@
{
"type": "module",
"name": "misskey-js",
"version": "2025.3.2-beta.18",
"version": "2025.4.0-beta.0",
"description": "Misskey SDK for JavaScript",
"license": "MIT",
"main": "./built/index.js",
@ -35,12 +35,12 @@
"directory": "packages/misskey-js"
},
"devDependencies": {
"@microsoft/api-extractor": "7.51.1",
"@microsoft/api-extractor": "7.52.2",
"@swc/jest": "0.2.37",
"@types/jest": "29.5.14",
"@types/node": "22.13.9",
"@typescript-eslint/eslint-plugin": "8.26.0",
"@typescript-eslint/parser": "8.26.0",
"@types/node": "22.13.15",
"@typescript-eslint/eslint-plugin": "8.29.0",
"@typescript-eslint/parser": "8.29.0",
"jest": "29.7.0",
"jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0",
@ -50,7 +50,7 @@
"execa": "8.0.1",
"tsd": "0.31.2",
"typescript": "5.8.2",
"esbuild": "0.25.0",
"esbuild": "0.25.2",
"glob": "11.0.1"
},
"files": [

File diff suppressed because it is too large Load Diff

View File

@ -9,16 +9,16 @@
"version": "1.0.0",
"devDependencies": {
"@types/mdast": "4.0.4",
"@types/node": "22.13.9",
"@vitest/coverage-v8": "3.0.8",
"@types/node": "22.13.15",
"@vitest/coverage-v8": "3.1.1",
"mdast-util-to-string": "4.0.0",
"remark": "15.0.1",
"remark-parse": "11.0.0",
"typescript": "5.8.2",
"unified": "11.0.5",
"vite": "6.2.3",
"vite-node": "3.0.8",
"vitest": "3.0.8"
"vite": "6.2.4",
"vite-node": "3.1.1",
"vitest": "3.1.1"
}
},
"node_modules/@ampproject/remapping": {
@ -909,9 +909,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "22.13.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz",
"integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==",
"version": "22.13.15",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.15.tgz",
"integrity": "sha512-imAbQEEbVni6i6h6Bd5xkCRwLqFc8hihCsi2GbtDoAtUcAFQ6Zs4pFXTZUUbroTkXdImczWM9AI8eZUuybXE3w==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -925,9 +925,9 @@
"dev": true
},
"node_modules/@vitest/coverage-v8": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.8.tgz",
"integrity": "sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.1.tgz",
"integrity": "sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -940,7 +940,7 @@
"istanbul-reports": "^3.1.7",
"magic-string": "^0.30.17",
"magicast": "^0.3.5",
"std-env": "^3.8.0",
"std-env": "^3.8.1",
"test-exclude": "^7.0.1",
"tinyrainbow": "^2.0.0"
},
@ -948,8 +948,8 @@
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"@vitest/browser": "3.0.8",
"vitest": "3.0.8"
"@vitest/browser": "3.1.1",
"vitest": "3.1.1"
},
"peerDependenciesMeta": {
"@vitest/browser": {
@ -958,14 +958,14 @@
}
},
"node_modules/@vitest/expect": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz",
"integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz",
"integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "3.0.8",
"@vitest/utils": "3.0.8",
"@vitest/spy": "3.1.1",
"@vitest/utils": "3.1.1",
"chai": "^5.2.0",
"tinyrainbow": "^2.0.0"
},
@ -974,13 +974,13 @@
}
},
"node_modules/@vitest/mocker": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz",
"integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz",
"integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "3.0.8",
"@vitest/spy": "3.1.1",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.17"
},
@ -1001,9 +1001,9 @@
}
},
"node_modules/@vitest/pretty-format": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz",
"integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz",
"integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1014,13 +1014,13 @@
}
},
"node_modules/@vitest/runner": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz",
"integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz",
"integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/utils": "3.0.8",
"@vitest/utils": "3.1.1",
"pathe": "^2.0.3"
},
"funding": {
@ -1028,13 +1028,13 @@
}
},
"node_modules/@vitest/snapshot": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz",
"integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz",
"integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.0.8",
"@vitest/pretty-format": "3.1.1",
"magic-string": "^0.30.17",
"pathe": "^2.0.3"
},
@ -1043,9 +1043,9 @@
}
},
"node_modules/@vitest/spy": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz",
"integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz",
"integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1056,13 +1056,13 @@
}
},
"node_modules/@vitest/utils": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz",
"integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz",
"integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.0.8",
"@vitest/pretty-format": "3.1.1",
"loupe": "^3.1.3",
"tinyrainbow": "^2.0.0"
},
@ -1349,9 +1349,9 @@
}
},
"node_modules/expect-type": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz",
"integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz",
"integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@ -2407,9 +2407,9 @@
"dev": true
},
"node_modules/std-env": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
"integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==",
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz",
"integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==",
"dev": true,
"license": "MIT"
},
@ -2724,9 +2724,9 @@
}
},
"node_modules/vite": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz",
"integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==",
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz",
"integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2796,9 +2796,9 @@
}
},
"node_modules/vite-node": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz",
"integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz",
"integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2819,31 +2819,31 @@
}
},
"node_modules/vitest": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz",
"integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz",
"integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/expect": "3.0.8",
"@vitest/mocker": "3.0.8",
"@vitest/pretty-format": "^3.0.8",
"@vitest/runner": "3.0.8",
"@vitest/snapshot": "3.0.8",
"@vitest/spy": "3.0.8",
"@vitest/utils": "3.0.8",
"@vitest/expect": "3.1.1",
"@vitest/mocker": "3.1.1",
"@vitest/pretty-format": "^3.1.1",
"@vitest/runner": "3.1.1",
"@vitest/snapshot": "3.1.1",
"@vitest/spy": "3.1.1",
"@vitest/utils": "3.1.1",
"chai": "^5.2.0",
"debug": "^4.4.0",
"expect-type": "^1.1.0",
"expect-type": "^1.2.0",
"magic-string": "^0.30.17",
"pathe": "^2.0.3",
"std-env": "^3.8.0",
"std-env": "^3.8.1",
"tinybench": "^2.9.0",
"tinyexec": "^0.3.2",
"tinypool": "^1.0.2",
"tinyrainbow": "^2.0.0",
"vite": "^5.0.0 || ^6.0.0",
"vite-node": "3.0.8",
"vite-node": "3.1.1",
"why-is-node-running": "^2.3.0"
},
"bin": {
@ -2859,8 +2859,8 @@
"@edge-runtime/vm": "*",
"@types/debug": "^4.1.12",
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
"@vitest/browser": "3.0.8",
"@vitest/ui": "3.0.8",
"@vitest/browser": "3.1.1",
"@vitest/ui": "3.1.1",
"happy-dom": "*",
"jsdom": "*"
},

View File

@ -10,15 +10,15 @@
},
"devDependencies": {
"@types/mdast": "4.0.4",
"@types/node": "22.13.9",
"@vitest/coverage-v8": "3.0.8",
"@types/node": "22.13.15",
"@vitest/coverage-v8": "3.1.1",
"mdast-util-to-string": "4.0.0",
"remark": "15.0.1",
"remark-parse": "11.0.0",
"typescript": "5.8.2",
"unified": "11.0.5",
"vite": "6.2.3",
"vite-node": "3.0.8",
"vitest": "3.0.8"
"vite": "6.2.4",
"vite-node": "3.1.1",
"vitest": "3.1.1"
}
}