Compare commits
No commits in common. "develop" and "develop" have entirely different histories.
18 changed files with 75 additions and 141 deletions
22
CHANGELOG.md
22
CHANGELOG.md
|
|
@ -3,28 +3,12 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## Unreleased (3.18)
|
||||
### REMOVED
|
||||
- dropped obsolete and buggy dm timeline
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
- UI for conversations API, replacing the DM timeline.
|
||||
Here each thread (conversation) has it’s own timeline and read markers instead of mixing everything together.
|
||||
- Boosts now show when and with which visibility they were boosted
|
||||
- bookmarks are now accessible via the narrow/mobile UI
|
||||
|
||||
### Fixed
|
||||
- fixed saving fallback cop yof settings to local browser storage
|
||||
- improve image animation detection further
|
||||
- fix status content parsing for mention and hashtag detection; this could lock the UI until reload
|
||||
- fix display of nsfw attachment overlays on webkit
|
||||
|
||||
## Between 2022.09 (3.2.0) and 2025.12 (3.17.0)
|
||||
A whole lot of stuff, but we forgot to update the changelog besides the one entry below, oopsi
|
||||
|
||||
- Implemented remote interaction with statuses
|
||||
|
||||
## 2022.09 (3.2.0) - 2022-09-10
|
||||
|
||||
## 2022.09 - 2022-09-10
|
||||
### Added
|
||||
- Automatic post translations. Must be configured on the backend in order to work.
|
||||
- Post editing, including a log of previous edits.
|
||||
|
|
|
|||
|
|
@ -26,12 +26,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.-nsfw-placeholder {
|
||||
.attachment-wrapper {
|
||||
align-content: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.description-container {
|
||||
flex: 0 1 0;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@
|
|||
<div class="heading">
|
||||
<div class="title-bar">
|
||||
<div class="title-bar-left">
|
||||
<div
|
||||
<div class="unread"
|
||||
v-if="conversation.unread"
|
||||
class="unread"
|
||||
>
|
||||
<span
|
||||
class="badge badge-notification"
|
||||
|
|
@ -30,7 +29,7 @@
|
|||
</button>
|
||||
|
||||
</div>
|
||||
<h4>{{ $t('dm_conv.default_name', {id: conversation.id}) }}</h4>
|
||||
<h4>{{ $t('dm_conv.default_name', {id: this.conversation.id}) }}</h4>
|
||||
</div>
|
||||
<div class="title-bar-right">
|
||||
<button
|
||||
|
|
@ -49,21 +48,17 @@
|
|||
<div class="members">
|
||||
<UserAvatar
|
||||
v-for="user in membersTruncated.users"
|
||||
:key="user.id"
|
||||
:user="user"
|
||||
:compact="compact"
|
||||
/>
|
||||
<div
|
||||
v-if="membersTruncated.truncated"
|
||||
class="ellipsis"
|
||||
>
|
||||
<div v-if="membersTruncated.truncated" class="ellipsis">
|
||||
...
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
<div
|
||||
v-if="showLastStatus"
|
||||
class="last-message"
|
||||
v-if="showLastStatus"
|
||||
>
|
||||
<div class="last-message-title">
|
||||
{{ $t('dm_conv.last_message_title') }}:
|
||||
|
|
@ -81,7 +76,7 @@
|
|||
<button
|
||||
class="btn button-default"
|
||||
:title="$t('dm_conv.recipients_edit_mode_button_tooltip')"
|
||||
@click.once="$router.push({ name: 'dm-conversation-recipients', params: { id: conversation.id }})"
|
||||
@click.once="$router.push({ name: 'dm-conversation-recipients', params: { id: this.conversation.id }})"
|
||||
>
|
||||
{{ $t('dm_conv.recipients_edit_mode_button') }}
|
||||
</button>
|
||||
|
|
@ -95,7 +90,7 @@
|
|||
@accepted="doDeleteConversation"
|
||||
@cancelled="hideDeleteConfirmModal"
|
||||
>
|
||||
{{ $t('dm_conv.delete_confirm', { identifier: conversation.id }) }}
|
||||
{{ $t('dm_conv.delete_confirm', { identifier: this.conversation.id }) }}
|
||||
</confirm-modal>
|
||||
</teleport>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@
|
|||
timeline-name="dmConv"
|
||||
>
|
||||
<template
|
||||
#extraHeading
|
||||
v-slot:extraHeading
|
||||
>
|
||||
<DMConvCard
|
||||
v-if="conversation"
|
||||
:conversation="conversation"
|
||||
:compact="false"
|
||||
:show-full-controls="true"
|
||||
:show-last-status="false"
|
||||
:link-to-timeline="false"
|
||||
:showFullControls="true"
|
||||
:showLastStatus="false"
|
||||
:linkToTimeline="false"
|
||||
@deleted="forceLeave"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
<StillImage
|
||||
v-else
|
||||
:src="item.emoji.imageUrl"
|
||||
no-stop-gifs="true"
|
||||
noStopGifs="true"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
<StillImage
|
||||
v-if="suggestion.img"
|
||||
:src="suggestion.img"
|
||||
no-stop-gifs="true"
|
||||
noStopGifs="true"
|
||||
/>
|
||||
<span v-else>{{ suggestion.replacement }}</span>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<StillImage
|
||||
v-else
|
||||
:src="group.first.imageUrl"
|
||||
no-stop-gifs="true"
|
||||
noStopGifs="true"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
:alt="currentMedia.description"
|
||||
:title="currentMedia.description"
|
||||
:image-load-handler="onImageLoaded"
|
||||
no-stop-gifs="true"
|
||||
noStopGifs="true"
|
||||
/>
|
||||
</PinchZoom>
|
||||
</SwipeClick>
|
||||
|
|
|
|||
|
|
@ -195,8 +195,8 @@
|
|||
:class="{ 'visibility-tray-edit': isEdit }"
|
||||
>
|
||||
<scope-selector
|
||||
v-if="!disableVisibilitySelector"
|
||||
ref="scopeselector"
|
||||
v-if="!disableVisibilitySelector"
|
||||
:user-default="userDefaultScope"
|
||||
:original-scope="copyMessageScope"
|
||||
:initial-scope="newStatus.visibility"
|
||||
|
|
@ -204,11 +204,10 @@
|
|||
/>
|
||||
|
||||
<div
|
||||
class="format-selector-container"
|
||||
>
|
||||
class="format-selector-container">
|
||||
<div
|
||||
class="format-selector"
|
||||
>
|
||||
>
|
||||
<Select
|
||||
id="post-language"
|
||||
v-model="newStatus.language"
|
||||
|
|
|
|||
|
|
@ -7,16 +7,8 @@ const QuoteButton = {
|
|||
name: 'QuoteButton',
|
||||
props: ['status', 'quoting', 'visibility'],
|
||||
computed: {
|
||||
showButton () {
|
||||
const currentUserId = this.$store.state.users.currentUser?.id
|
||||
|
||||
if (!currentUserId)
|
||||
return false
|
||||
|
||||
if (['public', 'unlisted', 'local'].includes(this.visibility))
|
||||
return true
|
||||
|
||||
return (this.visibility === 'private' && currentUserId == this.status.user.id)
|
||||
loggedIn () {
|
||||
return !!this.$store.state.users.currentUser
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="showButton"
|
||||
v-if="(visibility === 'public' || visibility === 'unlisted') && loggedIn"
|
||||
class="QuoteButton"
|
||||
>
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import {
|
|||
faHome,
|
||||
faComments,
|
||||
faBolt,
|
||||
faBookmark,
|
||||
faUserPlus,
|
||||
faBullhorn,
|
||||
faSearch,
|
||||
|
|
@ -26,7 +25,6 @@ library.add(
|
|||
faHome,
|
||||
faComments,
|
||||
faBolt,
|
||||
faBookmark,
|
||||
faUserPlus,
|
||||
faBullhorn,
|
||||
faSearch,
|
||||
|
|
|
|||
|
|
@ -85,18 +85,6 @@
|
|||
/> {{ $t("nav.lists") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link :to="{ name: 'bookmarks' }">
|
||||
<FAIcon
|
||||
fixed-width
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="bookmark"
|
||||
/> {{ $t("nav.bookmarks") }}
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-if="currentUser">
|
||||
<li @click="toggleDrawer">
|
||||
|
|
|
|||
|
|
@ -99,21 +99,19 @@
|
|||
<router-link
|
||||
v-else
|
||||
:to="retweeterProfileLink"
|
||||
>
|
||||
{{ retweeter }}
|
||||
</router-link>
|
||||
>{{ retweeter }}</router-link>
|
||||
</div>
|
||||
{{ ' ' }}
|
||||
|
||||
<div
|
||||
class="repeat-tooltip"
|
||||
>
|
||||
<FAIcon
|
||||
icon="retweet"
|
||||
class="repeat-icon"
|
||||
:title="$t('tool_tip.repeat')"
|
||||
/>
|
||||
{{ $t('timeline.repeated') }}
|
||||
<FAIcon
|
||||
icon="retweet"
|
||||
class="repeat-icon"
|
||||
:title="$t('tool_tip.repeat')"
|
||||
/>
|
||||
{{ $t('timeline.repeated') }}
|
||||
</div>
|
||||
|
||||
<span
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
v-if="$slots.extraHeading"
|
||||
class="timeline-extra-heading"
|
||||
>
|
||||
<slot name="extraHeading" />
|
||||
<slot name="extraHeading"></slot>
|
||||
</div>
|
||||
<div :class="classes.body">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="panel-heading -flexible-height">
|
||||
<div
|
||||
class="user-info"
|
||||
:class="{ '-compact': compactUserInfo }"
|
||||
:class="{ '-compact': this.compactUserInfo }"
|
||||
>
|
||||
<div class="container">
|
||||
<a
|
||||
|
|
@ -54,10 +54,7 @@
|
|||
>
|
||||
@{{ user.screen_name_ui }}
|
||||
</router-link>
|
||||
<span
|
||||
v-if="!hideBio && (user.deactivated || !!visibleRole || user.bot)"
|
||||
class="user-roles"
|
||||
>
|
||||
<span class="user-roles" v-if="!hideBio && (user.deactivated || !!visibleRole || user.bot)">
|
||||
<span
|
||||
v-if="user.deactivated"
|
||||
class="alert user-role"
|
||||
|
|
@ -77,10 +74,7 @@
|
|||
{{ $t('user_card.bot') }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="user.locked"
|
||||
class="user-locked"
|
||||
>
|
||||
<span class="user-locked" v-if="user.locked">
|
||||
<FAIcon
|
||||
class="lock-icon"
|
||||
icon="lock"
|
||||
|
|
@ -120,44 +114,44 @@
|
|||
</div>
|
||||
<div class="user-buttons">
|
||||
<button
|
||||
v-if="!isOtherUser && user.is_local"
|
||||
class="button-unstyled edit-profile-button"
|
||||
@click.stop="openProfileTab"
|
||||
>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
class="icon"
|
||||
icon="edit"
|
||||
:title="$t('user_card.edit_profile')"
|
||||
v-if="!isOtherUser && user.is_local"
|
||||
class="button-unstyled edit-profile-button"
|
||||
@click.stop="openProfileTab"
|
||||
>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
class="icon"
|
||||
icon="edit"
|
||||
:title="$t('user_card.edit_profile')"
|
||||
/>
|
||||
</button>
|
||||
<a
|
||||
v-if="isOtherUser && !user.is_local"
|
||||
:href="user.statusnet_profile_url"
|
||||
target="_blank"
|
||||
class="button-unstyled external-link-button"
|
||||
>
|
||||
<FAIcon
|
||||
class="icon"
|
||||
icon="external-link-alt"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
v-if="isOtherUser"
|
||||
:href="user.statusnet_profile_url + '.rss'"
|
||||
target="_blank"
|
||||
class="button-unstyled external-link-button"
|
||||
>
|
||||
<FAIcon
|
||||
class="icon"
|
||||
icon="rss"
|
||||
/>
|
||||
</a>
|
||||
<AccountActions
|
||||
v-if="isOtherUser && loggedIn"
|
||||
:user="user"
|
||||
:relationship="relationship"
|
||||
/>
|
||||
</button>
|
||||
<a
|
||||
v-if="isOtherUser && !user.is_local"
|
||||
:href="user.statusnet_profile_url"
|
||||
target="_blank"
|
||||
class="button-unstyled external-link-button"
|
||||
>
|
||||
<FAIcon
|
||||
class="icon"
|
||||
icon="external-link-alt"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
v-if="isOtherUser"
|
||||
:href="user.statusnet_profile_url + '.rss'"
|
||||
target="_blank"
|
||||
class="button-unstyled external-link-button"
|
||||
>
|
||||
<FAIcon
|
||||
class="icon"
|
||||
icon="rss"
|
||||
/>
|
||||
</a>
|
||||
<AccountActions
|
||||
v-if="isOtherUser && loggedIn"
|
||||
:user="user"
|
||||
:relationship="relationship"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-meta">
|
||||
|
|
@ -309,7 +303,7 @@
|
|||
:html="user.description_html"
|
||||
:emoji="user.emoji"
|
||||
:handle-links="true"
|
||||
:style='{"text-align": $store.getters.mergedConfig.centerAlignBio ? "center" : "start"}'
|
||||
:style='{"text-align": this.$store.getters.mergedConfig.centerAlignBio ? "center" : "start"}'
|
||||
/>
|
||||
</div>
|
||||
<teleport to="#modal">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { merge } from 'lodash'
|
||||
|
||||
const POLL_UPDATE_FREQUENCY = 150_000;
|
||||
|
||||
const polls = {
|
||||
state: {
|
||||
// Contains key = id, value = number of trackers for this poll
|
||||
|
|
@ -14,9 +12,6 @@ const polls = {
|
|||
// Make expired-state change trigger re-renders properly
|
||||
poll.expired = Date.now() > Date.parse(poll.expires_at)
|
||||
if (existingPoll) {
|
||||
if (poll.expired) {
|
||||
state.trackedPolls[poll.id] = 0
|
||||
}
|
||||
state.pollsObject[poll.id] = merge(existingPoll, poll)
|
||||
} else {
|
||||
state.pollsObject[poll.id] = poll
|
||||
|
|
@ -49,16 +44,13 @@ const polls = {
|
|||
if (rootState.polls.trackedPolls[pollId]) {
|
||||
dispatch('updateTrackedPoll', pollId)
|
||||
}
|
||||
}, POLL_UPDATE_FREQUENCY)
|
||||
}, 30 * 1000)
|
||||
commit('mergeOrAddPoll', poll)
|
||||
})
|
||||
},
|
||||
trackPoll ({ rootState, commit, dispatch }, pollId) {
|
||||
if (rootState.polls.pollsObject[pollId]?.expired)
|
||||
return;
|
||||
|
||||
if (!rootState.polls.trackedPolls[pollId]) {
|
||||
setTimeout(() => dispatch('updateTrackedPoll', pollId), POLL_UPDATE_FREQUENCY)
|
||||
setTimeout(() => dispatch('updateTrackedPoll', pollId), 30 * 1000)
|
||||
}
|
||||
commit('trackPoll', pollId)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const getAttrs = tag => {
|
|||
.replace(new RegExp('^' + getTagName(tag)), '')
|
||||
.replace(/\/?$/, '')
|
||||
.trim()
|
||||
const attrs = Array.from(innertag.matchAll(/([a-z]+[a-z0-9-]*)(?:=((?:"(?:\\.|[^"\\])*")|(?:'(?:\\.|[^'\\])*')))?/gi))
|
||||
const attrs = Array.from(innertag.matchAll(/([a-z0-9-]+)(?:=("[^"]+?"|'[^']+?'))?/gi))
|
||||
.map(([trash, key, value]) => [key, value])
|
||||
.map(([k, v]) => {
|
||||
if (!v) return [k, true]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue