Migrate rest of inputs to new v-model
This commit is contained in:
parent
bf009440ff
commit
561c1d868c
|
@ -14,7 +14,7 @@
|
||||||
<inline-search-bar
|
<inline-search-bar
|
||||||
v-if="search"
|
v-if="search"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
@search="albums = []; fetchData()"
|
@search="performSearch"
|
||||||
/>
|
/>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<div class="ui app-cards cards">
|
<div class="ui app-cards cards">
|
||||||
|
@ -69,6 +69,14 @@ export default {
|
||||||
search: { type: Boolean, default: false },
|
search: { type: Boolean, default: false },
|
||||||
limit: { type: Number, default: 12 }
|
limit: { type: Number, default: 12 }
|
||||||
},
|
},
|
||||||
|
setup () {
|
||||||
|
const performSearch = () => {
|
||||||
|
this.albums.length = 0
|
||||||
|
this.fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
return { performSearch }
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
albums: [],
|
albums: [],
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<inline-search-bar
|
<inline-search-bar
|
||||||
v-if="search"
|
v-if="search"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
@search="objects = []; fetchData()"
|
@search="performSearch"
|
||||||
/>
|
/>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<div class="ui five app-cards cards">
|
<div class="ui five app-cards cards">
|
||||||
|
@ -64,6 +64,14 @@ export default {
|
||||||
header: { type: Boolean, default: true },
|
header: { type: Boolean, default: true },
|
||||||
search: { type: Boolean, default: false }
|
search: { type: Boolean, default: false }
|
||||||
},
|
},
|
||||||
|
setup () {
|
||||||
|
const performSearch = () => {
|
||||||
|
this.objects.length = 0
|
||||||
|
this.fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
return { performSearch }
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
objects: [],
|
objects: [],
|
||||||
|
|
|
@ -4,11 +4,7 @@
|
||||||
<inline-search-bar
|
<inline-search-bar
|
||||||
v-if="search"
|
v-if="search"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
@search="
|
@search="performSearch"
|
||||||
currentPage = 1;
|
|
||||||
additionalTracks = [];
|
|
||||||
fetchData('tracks/');
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Add a header if needed -->
|
<!-- Add a header if needed -->
|
||||||
|
@ -191,6 +187,16 @@ export default {
|
||||||
paginateBy: { type: Number, required: false, default: 25 }
|
paginateBy: { type: Number, required: false, default: 25 }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const performSearch = () => {
|
||||||
|
this.currentPage = 1
|
||||||
|
this.additionalTracks.length = 0
|
||||||
|
this.fetchData('tracks/')
|
||||||
|
}
|
||||||
|
|
||||||
|
return { performSearch }
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
fetchDataUrl: this.nextUrl,
|
fetchDataUrl: this.nextUrl,
|
||||||
|
|
|
@ -1,3 +1,44 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import axios from 'axios'
|
||||||
|
import { useVModel } from '@vueuse/core'
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import { Album, Channel } from '~/types'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modelValue: number
|
||||||
|
channel?: Channel
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
channel: () => ({ id: '' })
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const value = useVModel(props, 'modelValue', emit)
|
||||||
|
|
||||||
|
const albums = reactive<Album[]>([])
|
||||||
|
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const fetchData = async () => {
|
||||||
|
albums.length = 0
|
||||||
|
if (!props.channel?.artist) return
|
||||||
|
|
||||||
|
isLoading.value = true
|
||||||
|
const response = await axios.get('albums/', {
|
||||||
|
params: {
|
||||||
|
artist: props.channel?.artist.id,
|
||||||
|
include_channels: 'true'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
albums.push(...response.data.results)
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.channel, fetchData)
|
||||||
|
fetchData()
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<label for="album-dropdown">
|
<label for="album-dropdown">
|
||||||
|
@ -14,9 +55,8 @@
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="album-dropdown"
|
id="album-dropdown"
|
||||||
:value="value"
|
v-model="value"
|
||||||
class="ui search normal dropdown"
|
class="ui search normal dropdown"
|
||||||
@input="$emit('input', $event.target.value)"
|
|
||||||
>
|
>
|
||||||
<option value="">
|
<option value="">
|
||||||
<translate translate-context="*/*/*">
|
<translate translate-context="*/*/*">
|
||||||
|
@ -40,39 +80,3 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
value: { type: Number, default: null },
|
|
||||||
channel: { type: Object, default: () => ({}) }
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
albums: [],
|
|
||||||
isLoading: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
async channel () {
|
|
||||||
await this.fetchData()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async created () {
|
|
||||||
await this.fetchData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async fetchData () {
|
|
||||||
this.albums = []
|
|
||||||
if (!this.channel || !this.channel.artist) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.isLoading = true
|
|
||||||
const response = await axios.get('albums/', { params: { artist: this.channel.artist.id, include_channels: 'true' } })
|
|
||||||
this.albums = response.data.results
|
|
||||||
this.isLoading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,3 +1,49 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import axios from 'axios'
|
||||||
|
import { useVModel } from '@vueuse/core'
|
||||||
|
import { computed, reactive, ref } from 'vue'
|
||||||
|
import { License } from '~/types'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modelValue: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const value = useVModel(props, 'modelValue', emit)
|
||||||
|
|
||||||
|
const availableLicenses = reactive<License[]>([])
|
||||||
|
const featuredLicensesIds = [
|
||||||
|
'cc0-1.0',
|
||||||
|
'cc-by-4.0',
|
||||||
|
'cc-by-sa-4.0',
|
||||||
|
'cc-by-nc-4.0',
|
||||||
|
'cc-by-nc-sa-4.0',
|
||||||
|
'cc-by-nc-nd-4.0',
|
||||||
|
'cc-by-nd-4.0'
|
||||||
|
]
|
||||||
|
|
||||||
|
const featuredLicenses = computed(() => {
|
||||||
|
return availableLicenses.filter(({ code }) => featuredLicensesIds.includes(code))
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentLicense = computed(() => {
|
||||||
|
if (!value.value) return null
|
||||||
|
return availableLicenses.find(({ code }) => code === value.value) ?? null
|
||||||
|
})
|
||||||
|
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const fetchLicenses = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
const response = await axios.get('licenses/')
|
||||||
|
availableLicenses.length = 0
|
||||||
|
availableLicenses.push(...response.data.results)
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchLicenses()
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<label for="license-dropdown">
|
<label for="license-dropdown">
|
||||||
|
@ -5,9 +51,8 @@
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="license-dropdown"
|
id="license-dropdown"
|
||||||
:value="value"
|
v-model="value"
|
||||||
class="ui search normal dropdown"
|
class="ui search normal dropdown"
|
||||||
@input="$emit('input', $event.target.value)"
|
|
||||||
>
|
>
|
||||||
<option value="">
|
<option value="">
|
||||||
<translate translate-context="*/*/*">
|
<translate translate-context="*/*/*">
|
||||||
|
@ -38,53 +83,3 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: { value: { type: String, default: null } },
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
availableLicenses: [],
|
|
||||||
featuredLicensesIds: [
|
|
||||||
'cc0-1.0',
|
|
||||||
'cc-by-4.0',
|
|
||||||
'cc-by-sa-4.0',
|
|
||||||
'cc-by-nc-4.0',
|
|
||||||
'cc-by-nc-sa-4.0',
|
|
||||||
'cc-by-nc-nd-4.0',
|
|
||||||
'cc-by-nd-4.0'
|
|
||||||
],
|
|
||||||
isLoading: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
featuredLicenses () {
|
|
||||||
const self = this
|
|
||||||
return this.availableLicenses.filter((l) => {
|
|
||||||
return self.featuredLicensesIds.indexOf(l.code) > -1
|
|
||||||
})
|
|
||||||
},
|
|
||||||
currentLicense () {
|
|
||||||
const self = this
|
|
||||||
if (this.value) {
|
|
||||||
return this.availableLicenses.filter((l) => {
|
|
||||||
return l.code === self.value
|
|
||||||
})[0]
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async created () {
|
|
||||||
await this.fetchLicenses()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async fetchLicenses () {
|
|
||||||
this.isLoading = true
|
|
||||||
const response = await axios.get('licenses/')
|
|
||||||
this.availableLicenses = response.data.results
|
|
||||||
this.isLoading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
import {reactive, ref, watch, watchEffect} from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { BackendError } from '~/types'
|
import { BackendError } from '~/types'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: string
|
modelValue: string
|
||||||
|
@ -86,6 +87,10 @@ watch(value, (to, from) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const store = useStore()
|
||||||
|
const getAttachmentUrl = (uuid: string) => {
|
||||||
|
return store.getters['instance/absoluteUrl'](`api/v1/attachments/${uuid}/proxy?next=medium_square_crop`)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -119,13 +124,13 @@ watch(value, (to, from) => {
|
||||||
v-if="value && value === initialValue"
|
v-if="value && value === initialValue"
|
||||||
alt=""
|
alt=""
|
||||||
:class="['ui', imageClass, 'image']"
|
:class="['ui', imageClass, 'image']"
|
||||||
:src="$store.getters['instance/absoluteUrl'](`api/v1/attachments/${value}/proxy?next=medium_square_crop`)"
|
:src="getAttachmentUrl(value)"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-else-if="attachment"
|
v-else-if="attachment"
|
||||||
alt=""
|
alt=""
|
||||||
:class="['ui', imageClass, 'image']"
|
:class="['ui', imageClass, 'image']"
|
||||||
:src="$store.getters['instance/absoluteUrl'](`api/v1/attachments/${attachment.uuid}/proxy?next=medium_square_crop`)"
|
:src="getAttachmentUrl(attachment.uuid)"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
|
@ -141,7 +146,7 @@ watch(value, (to, from) => {
|
||||||
:id="attachmentId"
|
:id="attachmentId"
|
||||||
ref="input"
|
ref="input"
|
||||||
:name="name"
|
:name="name"
|
||||||
:required="required || null"
|
:required="required || undefined"
|
||||||
class="ui input"
|
class="ui input"
|
||||||
type="file"
|
type="file"
|
||||||
accept="image/png,image/jpeg"
|
accept="image/png,image/jpeg"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useClipboard, useVModel } from '@vueuse/core'
|
import { toRefs, useClipboard } from '@vueuse/core'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: string
|
value: string
|
||||||
buttonClasses?: string
|
buttonClasses?: string
|
||||||
id?: string
|
id?: string
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
id: 'copy-input'
|
id: 'copy-input'
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const { value } = toRefs(props)
|
||||||
const value = useVModel(props, 'modelValue', emit)
|
|
||||||
|
|
||||||
const { copy, isSupported: canCopy, copied } = useClipboard({ source: value, copiedDuring: 5000 })
|
const { copy, isSupported: canCopy, copied } = useClipboard({ source: value, copiedDuring: 5000 })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -30,7 +28,7 @@ const { copy, isSupported: canCopy, copied } = useClipboard({ source: value, cop
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input
|
||||||
:id="id"
|
:id="id"
|
||||||
v-model="value"
|
:value="value"
|
||||||
:name="id"
|
:name="id"
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
|
|
|
@ -1,9 +1,38 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useVModel } from '@vueuse/core'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useGettext } from 'vue3-gettext'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modelValue: string
|
||||||
|
placeholder?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
placeholder: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'search'])
|
||||||
|
const value = useVModel(props, 'modelValue', emit)
|
||||||
|
|
||||||
|
const { $pgettext } = useGettext()
|
||||||
|
const labels = computed(() => ({
|
||||||
|
searchPlaceholder: $pgettext('Content/Search/Input.Placeholder', 'Search…'),
|
||||||
|
clear: $pgettext('Content/Library/Button.Label', 'Clear')
|
||||||
|
}))
|
||||||
|
|
||||||
|
const search = () => {
|
||||||
|
value.value = ''
|
||||||
|
emit('search', value.value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form
|
<form
|
||||||
class="ui inline form"
|
class="ui inline form"
|
||||||
@submit.stop.prevent="$emit('search', value)"
|
@submit.stop.prevent="emit('search', value)"
|
||||||
>
|
>
|
||||||
<div :class="['ui', 'action', {icon: isClearable}, 'input']">
|
<div :class="['ui', 'action', {icon: value}, 'input']">
|
||||||
<label
|
<label
|
||||||
for="search-query"
|
for="search-query"
|
||||||
class="hidden"
|
class="hidden"
|
||||||
|
@ -12,17 +41,16 @@
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="search-query"
|
id="search-query"
|
||||||
|
v-model="value"
|
||||||
name="search-query"
|
name="search-query"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="placeholder || labels.searchPlaceholder"
|
:placeholder="placeholder || labels.searchPlaceholder"
|
||||||
:value="value"
|
|
||||||
@input="$emit('input', $event.target.value)"
|
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
v-if="isClearable"
|
v-if="value"
|
||||||
class="x link icon"
|
class="x link icon"
|
||||||
:title="labels.clear"
|
:title="labels.clear"
|
||||||
@click.stop.prevent="$emit('input', ''); $emit('search', value)"
|
@click.stop.prevent="search"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -33,22 +61,3 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
value: { type: String, required: true },
|
|
||||||
placeholder: { type: String, required: false, default: '' }
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
labels () {
|
|
||||||
return {
|
|
||||||
searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search…'),
|
|
||||||
clear: this.$pgettext('Content/Library/Button.Label', 'Clear')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isClearable () {
|
|
||||||
return !!this.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ const allCategories = computed(() => {
|
||||||
<select
|
<select
|
||||||
v-model="value"
|
v-model="value"
|
||||||
class="ui dropdown"
|
class="ui dropdown"
|
||||||
:required="required || null"
|
:required="required || undefined"
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
v-if="empty"
|
v-if="empty"
|
||||||
|
|
|
@ -55,7 +55,7 @@ Promise.all(modules).finally(() => {
|
||||||
// TODO (wvffle): Replace $set and $delete with reactive()
|
// TODO (wvffle): Replace $set and $delete with reactive()
|
||||||
// TODO (wvffle): Check for mixin merging: https://v3-migration.vuejs.org/breaking-changes/data-option.html#mixin-merge-behavior-change=
|
// TODO (wvffle): Check for mixin merging: https://v3-migration.vuejs.org/breaking-changes/data-option.html#mixin-merge-behavior-change=
|
||||||
// TODO (wvffle): Use emits options: https://v3-migration.vuejs.org/breaking-changes/emits-option.html
|
// TODO (wvffle): Use emits options: https://v3-migration.vuejs.org/breaking-changes/emits-option.html
|
||||||
// TODO (wvffle): Migrate to new v-model: https://v3-migration.vuejs.org/breaking-changes/v-model.html
|
// TODO (wvffle): Find all array watchers and make them deep
|
||||||
// TODO (wvffle): Migrate to <script setup>
|
// TODO (wvffle): Migrate to <script setup>
|
||||||
// TODO (wvffle): Replace `from '(../)+` with `from '~/`
|
// TODO (wvffle): Replace `from '(../)+` with `from '~/`
|
||||||
// TODO (wvffle): Remove `allowJs` from tsconfig.json
|
// TODO (wvffle): Remove `allowJs` from tsconfig.json
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type { App } from 'vue'
|
import type { App } from 'vue'
|
||||||
import type { Store } from 'vuex'
|
import type { Store } from 'vuex'
|
||||||
import { Router } from 'vue-router'
|
import { Router } from 'vue-router'
|
||||||
import {AxiosError} from "axios";
|
import { AxiosError } from 'axios'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -29,20 +29,33 @@ export interface ThemeEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track stuff
|
// Track stuff
|
||||||
|
export type ContentCategory = 'podcast'
|
||||||
|
|
||||||
export interface Artist {
|
export interface Artist {
|
||||||
|
id: string
|
||||||
name: string
|
name: string
|
||||||
|
content_category: ContentCategory
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Album {
|
export interface Album {
|
||||||
|
id: string
|
||||||
artist: Artist
|
artist: Artist
|
||||||
|
tracks_count: number
|
||||||
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Track {
|
export interface Track {
|
||||||
|
id: string
|
||||||
title: string
|
title: string
|
||||||
album?: Album
|
album?: Album
|
||||||
artist?: Artist
|
artist?: Artist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Channel {
|
||||||
|
id: string
|
||||||
|
artist?: Artist
|
||||||
|
}
|
||||||
|
|
||||||
// API stuff
|
// API stuff
|
||||||
export interface APIErrorResponse {
|
export interface APIErrorResponse {
|
||||||
[key: string]: APIErrorResponse | string[]
|
[key: string]: APIErrorResponse | string[]
|
||||||
|
@ -122,3 +135,9 @@ export interface Actor {
|
||||||
is_local: boolean
|
is_local: boolean
|
||||||
domain: string
|
domain: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface License {
|
||||||
|
code: string
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
|
@ -138,7 +138,10 @@
|
||||||
If you're using Mastodon or other fediverse applications, you can subscribe to this account:
|
If you're using Mastodon or other fediverse applications, you can subscribe to this account:
|
||||||
</translate>
|
</translate>
|
||||||
</p>
|
</p>
|
||||||
<copy-input :value="`@${object.actor.full_username}`" />
|
<copy-input
|
||||||
|
id="copy-tag"
|
||||||
|
:value="`@${object.actor.full_username}`"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue