Merge branch 'chat-refactor' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2026-08-04 14:52:47 +03:00
commit 1a9d4e4dd5
13 changed files with 96 additions and 66 deletions

1
changelog.d/chat_vew.add Normal file
View file

@ -0,0 +1 @@
Chat view for threads

View file

@ -186,7 +186,11 @@ export default {
return useShoutStore().joined return useShoutStore().joined
}, },
isChats() { isChats() {
return this.$route.name === 'chat' || this.$route.name === 'chats' || this.$route.name === 'conversation2' return (
this.$route.name === 'chat' ||
this.$route.name === 'chats' ||
this.$route.name === 'conversation2'
)
}, },
isListEdit() { isListEdit() {
return this.$route.name === 'lists-edit' return this.$route.name === 'lists-edit'

View file

@ -367,7 +367,6 @@ const Chat = {
} }
}, },
async startFetching() { async startFetching() {
console.log(this.statusId, this.chatUserId)
if (!this.isConversation) { if (!this.isConversation) {
try { try {
const { data } = await getOrCreateChat({ const { data } = await getOrCreateChat({

View file

@ -21,8 +21,9 @@
<div class="title"> <div class="title">
<template v-if="isConversation"> <template v-if="isConversation">
<RichContent <RichContent
v-if="messages[0]?.summary" v-if="messages[0]?.summary_raw_html"
:html="messages[0].summary" :html="messages[0].summary_raw_html"
:emoji="messages[0].emojis"
/> />
<template v-else> <template v-else>
{{ $t('timeline.conversation') }} {{ $t('timeline.conversation') }}

View file

@ -11,8 +11,9 @@
> >
<h1 class="title"> <h1 class="title">
<RichContent <RichContent
v-if="conversation[0]?.summary" v-if="conversation[0]?.summary_raw_html"
:html="conversation[0].summary" :html="conversation[0].summary_raw_html"
:emoji="conversation[0].emojis"
/> />
<template v-else> <template v-else>
{{ $t('timeline.conversation') }} {{ $t('timeline.conversation') }}

View file

@ -43,7 +43,7 @@ const Draft = {
return { statusId: this.draft.refId } return { statusId: this.draft.refId }
} else if (this.draft.type === 'reply') { } else if (this.draft.type === 'reply') {
return { return {
repliedStatus: this.refStatus repliedStatus: this.refStatus,
} }
} else { } else {
return {} return {}

View file

@ -351,17 +351,14 @@ const PostStatusForm = {
return this.newStatus.quote !== null return this.newStatus.quote !== null
}, },
quotable() { quotable() {
if ( if (!this.quotingAvailable || !this.isReply) {
!this.quotingAvailable ||
!this.isReply
) {
return false return false
} }
if ( if (
this.repliedStatus.visibility === 'public' || this.repliedStatus.visibility === 'public' ||
this.repliedStatus.visibility === 'unlisted' || this.repliedStatus.visibility === 'unlisted' ||
this.repliedStatus.visibility === 'local' this.repliedStatus.visibility === 'local'
) { ) {
return true return true
} else if (this.repliedStatus.visibility === 'private') { } else if (this.repliedStatus.visibility === 'private') {
@ -703,7 +700,6 @@ const PostStatusForm = {
this.previewLoading = false this.previewLoading = false
return return
} }
const newStatus = this.newStatus
this.previewLoading = true this.previewLoading = true
statusPoster statusPoster
@ -961,7 +957,8 @@ const PostStatusForm = {
}, },
// Quote // Quote
toggleQuoteForm() { // This is for the "attach quote" button toggleQuoteForm() {
// This is for the "attach quote" button
if (!this.hasQuote) { if (!this.hasQuote) {
this.newStatus.quote = {} this.newStatus.quote = {}
this.newStatus.quote.thread = false this.newStatus.quote.thread = false
@ -983,14 +980,13 @@ const PostStatusForm = {
saveDraft() { saveDraft() {
if (!this.disableDraft && !this.saveInhibited) { if (!this.disableDraft && !this.saveInhibited) {
if (this.safeToSaveDraft) { if (this.safeToSaveDraft) {
return this return this.$store
.$store
.dispatch('addOrSaveDraft', { .dispatch('addOrSaveDraft', {
draft: { draft: {
type: this.statusType, type: this.statusType,
refId: this.refId, refId: this.refId,
...this.newStatus ...this.newStatus,
} },
}) })
.then((id) => { .then((id) => {
if (this.newStatus.id !== id) { if (this.newStatus.id !== id) {

View file

@ -200,7 +200,6 @@ const Status = {
) )
}, },
status() { status() {
console.log('s', this.statusoid)
if (this.retweet) { if (this.retweet) {
return this.statusoid.retweeted_status return this.statusoid.retweeted_status
} else { } else {

View file

@ -18,11 +18,11 @@ import {
faChevronDown, faChevronDown,
faChevronRight, faChevronRight,
faComments, faComments,
faList,
faExternalLinkAlt, faExternalLinkAlt,
faEye, faEye,
faEyeSlash, faEyeSlash,
faHistory, faHistory,
faList,
faMinus, faMinus,
faPencil, faPencil,
faPlus, faPlus,

View file

@ -5,6 +5,8 @@ import ActionButton from './action_button.vue'
import { useAdminSettingsStore } from 'src/stores/admin_settings.js' import { useAdminSettingsStore } from 'src/stores/admin_settings.js'
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faEnvelope, faEnvelope,
@ -49,6 +51,11 @@ export default {
this.$store.dispatch('fetchDomainMutes') this.$store.dispatch('fetchDomainMutes')
} }
}, },
data() {
return {
randomSeed: genRandomSeed(),
}
},
computed: { computed: {
buttonClass() { buttonClass() {
return [ return [

View file

@ -188,7 +188,6 @@ export const useInterfaceStore = defineStore('interface', {
this.globalNotices = this.globalNotices.filter((n) => n !== notice) this.globalNotices = this.globalNotices.filter((n) => n !== notice)
}, },
setGlobalError({ error, instance, info }) { setGlobalError({ error, instance, info }) {
console.log(info)
switch (info) { switch (info) {
case 'https://vuejs.org/error-reference/#runtime-13': { case 'https://vuejs.org/error-reference/#runtime-13': {
this.globalError = { this.globalError = {
@ -206,7 +205,6 @@ export const useInterfaceStore = defineStore('interface', {
break break
} }
} }
console.log(this.globalError)
}, },
clearGlobalError() { clearGlobalError() {
this.globalError = null this.globalError = null

View file

@ -34,8 +34,7 @@ const global = {
api: {}, api: {},
users: {}, users: {},
statuses: { statuses: {
allStatusesObject: { allStatusesObject: {},
},
}, },
}, },
}, },

View file

@ -1,8 +1,5 @@
import { vi } from 'vitest'
import { createTestingPinia } from '@pinia/testing'
import { mount } from '@vue/test-utils' import { mount } from '@vue/test-utils'
import { setActivePinia } from 'pinia' import { vi } from 'vitest'
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import { mountOpts } from '../../../fixtures/setup_test' import { mountOpts } from '../../../fixtures/setup_test'
@ -69,9 +66,12 @@ describe('PostStatusForm', () => {
}) })
it('Initializes a reply form', () => { it('Initializes a reply form', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
repliedStatus: repliedStatus, PostStatusForm,
})) replyMountOpts({
repliedStatus: repliedStatus,
}),
)
useInstanceCapabilitiesStore().quotingAvailable = true useInstanceCapabilitiesStore().quotingAvailable = true
@ -89,9 +89,12 @@ describe('PostStatusForm', () => {
}) })
it('Copies scope and subject line, disables quoting for locked posts', () => { it('Copies scope and subject line, disables quoting for locked posts', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
repliedStatus: repliedStatus2, PostStatusForm,
})) replyMountOpts({
repliedStatus: repliedStatus2,
}),
)
useInstanceCapabilitiesStore().quotingAvailable = true useInstanceCapabilitiesStore().quotingAvailable = true
@ -125,7 +128,7 @@ describe('PostStatusForm', () => {
// ...set our settings... // ...set our settings...
useMergedConfigStore().mergedConfig = { useMergedConfigStore().mergedConfig = {
...useMergedConfigStore().mergedConfig, ...useMergedConfigStore().mergedConfig,
subjectLineBehavior: 'masto' subjectLineBehavior: 'masto',
} }
// ...and only then mount our component // ...and only then mount our component
@ -145,11 +148,14 @@ describe('PostStatusForm', () => {
}) })
it('Sets status to statusText without mentions if mentions line is enabled', () => { it('Sets status to statusText without mentions if mentions line is enabled', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
repliedStatus: repliedStatus2, PostStatusForm,
statusText: 'testing', replyMountOpts({
mentionsLine: true, repliedStatus: repliedStatus2,
})) statusText: 'testing',
mentionsLine: true,
}),
)
expect(wrapper.vm.statusType).to.equal('reply') expect(wrapper.vm.statusType).to.equal('reply')
expect(wrapper.vm.isReply).to.equal(true) expect(wrapper.vm.isReply).to.equal(true)
@ -158,9 +164,12 @@ describe('PostStatusForm', () => {
}) })
it('Sets mention when asked for it', () => { it('Sets mention when asked for it', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
profileMention: repliedUser, PostStatusForm,
})) replyMountOpts({
profileMention: repliedUser,
}),
)
expect(wrapper.vm.statusType).to.equal('mention') expect(wrapper.vm.statusType).to.equal('mention')
expect(wrapper.vm.isReply).to.equal(false) expect(wrapper.vm.isReply).to.equal(false)
@ -169,9 +178,12 @@ describe('PostStatusForm', () => {
}) })
it('Initializes quote when reply/quote toggled to quote', () => { it('Initializes quote when reply/quote toggled to quote', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
repliedStatus: repliedStatus2, PostStatusForm,
})) replyMountOpts({
repliedStatus: repliedStatus2,
}),
)
expect(wrapper.vm.statusType).to.equal('reply') expect(wrapper.vm.statusType).to.equal('reply')
expect(wrapper.vm.isReply).to.equal(true) expect(wrapper.vm.isReply).to.equal(true)
@ -182,9 +194,12 @@ describe('PostStatusForm', () => {
}) })
it('Resets quote when reply/quote toggled to reply', () => { it('Resets quote when reply/quote toggled to reply', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
repliedStatus: repliedStatus2, PostStatusForm,
})) replyMountOpts({
repliedStatus: repliedStatus2,
}),
)
expect(wrapper.vm.statusType).to.equal('reply') expect(wrapper.vm.statusType).to.equal('reply')
expect(wrapper.vm.isReply).to.equal(true) expect(wrapper.vm.isReply).to.equal(true)
@ -196,32 +211,42 @@ describe('PostStatusForm', () => {
}) })
it('Initializes and reset quote when toggling quote attachment', () => { it('Initializes and reset quote when toggling quote attachment', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
repliedStatus: repliedStatus2, PostStatusForm,
})) replyMountOpts({
repliedStatus: repliedStatus2,
}),
)
expect(wrapper.vm.statusType).to.equal('reply') expect(wrapper.vm.statusType).to.equal('reply')
expect(wrapper.vm.isReply).to.equal(true) expect(wrapper.vm.isReply).to.equal(true)
wrapper.vm.toggleQuoteForm() wrapper.vm.toggleQuoteForm()
expect(wrapper.vm.newStatus.quote).to.eql({ thread: false, id: null, url: '' }) expect(wrapper.vm.newStatus.quote).to.eql({
thread: false,
id: null,
url: '',
})
wrapper.vm.toggleQuoteForm() wrapper.vm.toggleQuoteForm()
expect(wrapper.vm.newStatus.quote).to.eql(null) expect(wrapper.vm.newStatus.quote).to.eql(null)
}) })
it('Status editing', () => { it('Status editing', () => {
const wrapper = mount(PostStatusForm, replyMountOpts({ const wrapper = mount(
statusId: 'edited', PostStatusForm,
statusText: 'text', replyMountOpts({
statusSubject: 'heading', statusId: 'edited',
statusIsSensitive: true, statusText: 'text',
statusPoll: {}, statusSubject: 'heading',
statusQuote: {}, statusIsSensitive: true,
statusFiles: [], statusPoll: {},
statusMediaDescriptions: {}, statusQuote: {},
statusVisibility: 'unlisted', statusFiles: [],
statusContentType: 'text/markdown', statusMediaDescriptions: {},
})) statusVisibility: 'unlisted',
statusContentType: 'text/markdown',
}),
)
expect(wrapper.vm.statusType).to.equal('edit') expect(wrapper.vm.statusType).to.equal('edit')
expect(wrapper.vm.isReply).to.equal(false) // edits don't support changing reply-to so it's pretty much ignored expect(wrapper.vm.isReply).to.equal(false) // edits don't support changing reply-to so it's pretty much ignored