mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop
This commit is contained in:
		
						commit
						79370aaee2
					
				
					 5 changed files with 146 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
 | 
			
		||||
### Client
 | 
			
		||||
- Feat: 新しいゲームを追加
 | 
			
		||||
- Feat: 絵文字の詳細ダイアログを追加
 | 
			
		||||
- Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように
 | 
			
		||||
- Enhance: チャンネルノートのピン留めをノートのメニューからできるように
 | 
			
		||||
- Enhance: 管理者の場合はAPI tokenの発行画面で管理機能に関する権限を付与できるように
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										102
									
								
								packages/frontend/src/components/MkCustomEmojiDetailedDialog.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								packages/frontend/src/components/MkCustomEmojiDetailedDialog.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,102 @@
 | 
			
		|||
<!--
 | 
			
		||||
SPDX-FileCopyrightText: syuilo and other misskey contributors
 | 
			
		||||
SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <MkModalWindow ref="dialogEl" @close="cancel()" @closed="$emit('closed')">
 | 
			
		||||
    <template #header>:{{ emoji.name }}:</template>
 | 
			
		||||
    <template #default>
 | 
			
		||||
      <MkSpacer>
 | 
			
		||||
        <div style="display: flex; flex-direction: column; gap: 1em;">
 | 
			
		||||
          <div :class="$style.emojiImgWrapper">
 | 
			
		||||
            <MkCustomEmoji :name="emoji.name" :normal="true" style="height: 100%;"></MkCustomEmoji>
 | 
			
		||||
          </div>
 | 
			
		||||
          <MkKeyValue>
 | 
			
		||||
            <template #key>{{ i18n.ts.name }}</template>
 | 
			
		||||
            <template #value>{{ emoji.name }}</template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
          <MkKeyValue>
 | 
			
		||||
            <template #key>{{ i18n.ts.tags }}</template>
 | 
			
		||||
            <template #value>
 | 
			
		||||
              <div v-if="emoji.aliases.length === 0">{{ i18n.ts.none }}</div>
 | 
			
		||||
              <div v-else :class="$style.aliases">
 | 
			
		||||
                <span v-for="alias in emoji.aliases" :key="alias" :class="$style.alias">
 | 
			
		||||
                  {{ alias }}
 | 
			
		||||
                </span>
 | 
			
		||||
              </div>
 | 
			
		||||
            </template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
          <MkKeyValue>
 | 
			
		||||
            <template #key>{{ i18n.ts.category }}</template>
 | 
			
		||||
            <template #value>{{ emoji.category ?? i18n.ts.none }}</template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
          <MkKeyValue>
 | 
			
		||||
            <template #key>{{ i18n.ts.sensitive }}</template>
 | 
			
		||||
            <template #value>{{ emoji.isSensitive ? i18n.ts.yes : i18n.ts.no }}</template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
          <MkKeyValue>
 | 
			
		||||
            <template #key>{{ i18n.ts.localOnly }}</template>
 | 
			
		||||
            <template #value>{{ emoji.localOnly ? i18n.ts.yes : i18n.ts.no }}</template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
          <MkKeyValue>
 | 
			
		||||
            <template #key>{{ i18n.ts.license }}</template>
 | 
			
		||||
            <template #value>{{ emoji.license ?? i18n.ts.none }}</template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
          <MkKeyValue :copy="emoji.url">
 | 
			
		||||
            <template #key>{{ i18n.ts.emojiUrl }}</template>
 | 
			
		||||
            <template #value>
 | 
			
		||||
              <a :href="emoji.url" target="_blank">{{ emoji.url }}</a>
 | 
			
		||||
            </template>
 | 
			
		||||
          </MkKeyValue>
 | 
			
		||||
        </div>
 | 
			
		||||
      </MkSpacer>
 | 
			
		||||
    </template>
 | 
			
		||||
  </MkModalWindow>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import * as Misskey from 'misskey-js';
 | 
			
		||||
import { defineProps, shallowRef } from 'vue';
 | 
			
		||||
import { i18n } from '@/i18n.js';
 | 
			
		||||
import MkModalWindow from '@/components/MkModalWindow.vue';
 | 
			
		||||
import MkKeyValue from '@/components/MkKeyValue.vue';
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  emoji: Misskey.entities.EmojiDetailed,
 | 
			
		||||
}>();
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
	(ev: 'ok', cropped: Misskey.entities.DriveFile): void;
 | 
			
		||||
	(ev: 'cancel'): void;
 | 
			
		||||
	(ev: 'closed'): void;
 | 
			
		||||
}>();
 | 
			
		||||
const dialogEl = shallowRef<InstanceType<typeof MkModalWindow>>();
 | 
			
		||||
const cancel = () => {
 | 
			
		||||
	emit('cancel');
 | 
			
		||||
	dialogEl.value!.close();
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" module>
 | 
			
		||||
.emojiImgWrapper {
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  height: 40cqh;
 | 
			
		||||
  background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, var(--X5) 8px, var(--X5) 14px);
 | 
			
		||||
  border-radius: var(--radius);
 | 
			
		||||
  margin: auto;
 | 
			
		||||
  overflow-y: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.aliases {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  gap: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alias {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  padding: 3px 10px;
 | 
			
		||||
  background-color: var(--X5);
 | 
			
		||||
  border: solid 1px var(--divider);
 | 
			
		||||
  border-radius: var(--radius);
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
	class="_button"
 | 
			
		||||
	:class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: canToggle, [$style.small]: defaultStore.state.reactionsDisplaySize === 'small', [$style.large]: defaultStore.state.reactionsDisplaySize === 'large' }]"
 | 
			
		||||
	@click="toggleReaction()"
 | 
			
		||||
	@contextmenu.prevent.stop="menu"
 | 
			
		||||
>
 | 
			
		||||
	<MkReactionIcon :class="defaultStore.state.limitWidthOfReaction ? $style.limitWidth : ''" :reaction="reaction" :emojiUrl="note.reactionEmojis[reaction.substring(1, reaction.length - 1)]"/>
 | 
			
		||||
	<span :class="$style.count">{{ count }}</span>
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +22,7 @@ import { computed, inject, onMounted, shallowRef, watch } from 'vue';
 | 
			
		|||
import * as Misskey from 'misskey-js';
 | 
			
		||||
import XDetails from '@/components/MkReactionsViewer.details.vue';
 | 
			
		||||
import MkReactionIcon from '@/components/MkReactionIcon.vue';
 | 
			
		||||
import MkCustomEmojiDetailedDialog from './MkCustomEmojiDetailedDialog.vue';
 | 
			
		||||
import * as os from '@/os.js';
 | 
			
		||||
import { misskeyApi, misskeyApiGet } from '@/scripts/misskey-api.js';
 | 
			
		||||
import { useTooltip } from '@/scripts/use-tooltip.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +100,22 @@ async function toggleReaction() {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function menu(ev) {
 | 
			
		||||
	if (!canToggle.value) return;
 | 
			
		||||
	if (!props.reaction.includes(":")) return;
 | 
			
		||||
	os.popupMenu([{
 | 
			
		||||
		text: i18n.ts.info,
 | 
			
		||||
		icon: 'ti ti-info-circle',
 | 
			
		||||
		action: async () => {
 | 
			
		||||
			os.popup(MkCustomEmojiDetailedDialog, {
 | 
			
		||||
				emoji: await misskeyApiGet('emoji', {
 | 
			
		||||
					name: props.reaction.replace(/:/g, '').replace(/@\./, ''),
 | 
			
		||||
				}),
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
	}], ev.currentTarget ?? ev.target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function anime() {
 | 
			
		||||
	if (document.hidden) return;
 | 
			
		||||
	if (!defaultStore.state.animation) return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,11 @@ import { getProxiedImageUrl, getStaticImageUrl } from '@/scripts/media-proxy.js'
 | 
			
		|||
import { defaultStore } from '@/store.js';
 | 
			
		||||
import { customEmojisMap } from '@/custom-emojis.js';
 | 
			
		||||
import * as os from '@/os.js';
 | 
			
		||||
import { misskeyApiGet } from '@/scripts/misskey-api.js';
 | 
			
		||||
import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 | 
			
		||||
import * as sound from '@/scripts/sound.js';
 | 
			
		||||
import { i18n } from '@/i18n.js';
 | 
			
		||||
import MkCustomEmojiDetailedDialog from '@/components/MkCustomEmojiDetailedDialog.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	name: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +95,19 @@ function onClick(ev: MouseEvent) {
 | 
			
		|||
				react(`:${props.name}:`);
 | 
			
		||||
				sound.playMisskeySfx('reaction');
 | 
			
		||||
			},
 | 
			
		||||
		}] : [])], ev.currentTarget ?? ev.target);
 | 
			
		||||
		}] : []), {
 | 
			
		||||
			text: i18n.ts.info,
 | 
			
		||||
			icon: 'ti ti-info-circle',
 | 
			
		||||
			action: async () => {
 | 
			
		||||
				os.popup(MkCustomEmojiDetailedDialog, {
 | 
			
		||||
					emoji: await misskeyApiGet('emoji', {
 | 
			
		||||
						name: customEmojiName.value,
 | 
			
		||||
					}),
 | 
			
		||||
				}, {
 | 
			
		||||
					anchor: ev.target,
 | 
			
		||||
				});
 | 
			
		||||
			},
 | 
			
		||||
		}], ev.currentTarget ?? ev.target);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,19 +14,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { } from 'vue';
 | 
			
		||||
import * as os from '@/os.js';
 | 
			
		||||
import * as Misskey from 'misskey-js';
 | 
			
		||||
import { misskeyApiGet } from '@/scripts/misskey-api.js';
 | 
			
		||||
import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 | 
			
		||||
import { i18n } from '@/i18n.js';
 | 
			
		||||
import MkCustomEmojiDetailedDialog from '@/components/MkCustomEmojiDetailedDialog.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	emoji: {
 | 
			
		||||
		name: string;
 | 
			
		||||
		aliases: string[];
 | 
			
		||||
		category: string;
 | 
			
		||||
		url: string;
 | 
			
		||||
	};
 | 
			
		||||
  emoji: Misskey.entities.EmojiSimple;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
function menu(ev) {
 | 
			
		||||
| 
						 | 
				
			
			@ -43,12 +39,13 @@ function menu(ev) {
 | 
			
		|||
	}, {
 | 
			
		||||
		text: i18n.ts.info,
 | 
			
		||||
		icon: 'ti ti-info-circle',
 | 
			
		||||
		action: () => {
 | 
			
		||||
			misskeyApiGet('emoji', { name: props.emoji.name }).then(res => {
 | 
			
		||||
				os.alert({
 | 
			
		||||
					type: 'info',
 | 
			
		||||
					text: `Name: ${res.name}\nAliases: ${res.aliases.join(' ')}\nCategory: ${res.category}\nisSensitive: ${res.isSensitive}\nlocalOnly: ${res.localOnly}\nLicense: ${res.license}\nURL: ${res.url}`,
 | 
			
		||||
				});
 | 
			
		||||
		action: async () => {
 | 
			
		||||
			os.popup(MkCustomEmojiDetailedDialog, {
 | 
			
		||||
				emoji: await misskeyApiGet('emoji', {
 | 
			
		||||
					name: props.emoji.name,
 | 
			
		||||
				})
 | 
			
		||||
			}, {
 | 
			
		||||
				anchor: ev.target,
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
	}], ev.currentTarget ?? ev.target);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue