move reblog/fav counts from details to toolbar, making them visible on the timeline

This commit is contained in:
Osma Ahvenlampi 2023-01-24 14:26:15 +02:00
parent 84ea7b2828
commit b7fc840e77
5 changed files with 137 additions and 90 deletions

View File

@ -397,6 +397,7 @@ export default {
enableAll: 'Enable all',
metrics: 'Metrics',
hideFollowerCount: 'Hide follower counts (capped at 10)',
hideReplyCount: 'Hide reply counts',
hideReblogCount: 'Hide boost counts',
hideFavoriteCount: 'Hide favorite counts',
hideUnread: 'Hide unread notifications count (i.e. the red dot)',
@ -498,8 +499,13 @@ export default {
accountSignedUp: '{name} signed up, {account}',
accountRequestedFollow: '{name} requested to follow you, {account}',
accountReported: '{name} filed a report, {account}',
replyCountsHidden: 'Reply counts hidden',
reblogCountsHidden: 'Boost counts hidden',
favoriteCountsHidden: 'Favorite counts hidden',
replyCount: `{count, plural,
one {1 reply}
other {{count} replies}
}`,
rebloggedTimes: `Boosted {count, plural,
one {1 time}
other {{count} times}
@ -579,6 +585,7 @@ export default {
cannotReblogFollowersOnly: 'Cannot be boosted because this is followers-only',
cannotReblogDirectMessage: 'Cannot be boosted because this is a direct message',
reblog: 'Boost',
unreblog: 'Unboost',
reply: 'Reply',
replyToThread: 'Reply to thread',
favorite: 'Favorite',

View File

@ -12,7 +12,7 @@
{/if}
<StatusAuthorName {...params} />
<StatusAuthorHandle {...params} />
{#if !isStatusInOwnThread}
{#if true || !isStatusInOwnThread}
<StatusRelativeDate {...params} {...timestampParams} />
{/if}
<StatusSidebar {...params} />
@ -87,19 +87,19 @@
.status-article.status-in-own-thread {
grid-template-areas:
"sidebar author-name"
"sidebar author-handle"
"spoiler spoiler"
"spoiler-btn spoiler-btn"
"mentions mentions"
"content content"
"card card"
"media-grp media-grp"
"media media"
"poll poll"
"details details"
"toolbar toolbar"
"compose compose";
"sidebar author-name relative-date"
"sidebar author-handle author-handle"
"spoiler spoiler spoiler"
"spoiler-btn spoiler-btn spoiler-btn"
"mentions mentions mentions"
"content content content"
"card card card"
"media-grp media-grp media-grp"
"media media media"
"poll poll poll"
"details details details"
"toolbar toolbar toolbar"
"compose compose compose";
grid-template-columns: min-content 1fr;
grid-template-rows: repeat(7, max-content);
}

View File

@ -27,20 +27,6 @@
</span>
{/if}
{/if}
<a class="status-favs-reblogs status-reblogs"
rel="prefetch"
href="/statuses/{originalStatusId}/reblogs"
aria-label={reblogsLabel}>
<SvgIcon className="status-favs-reblogs-svg" href="#fa-retweet" />
<span>{numReblogs}</span>
</a>
<a class="status-favs-reblogs status-favs"
rel="prefetch"
href="/statuses/{originalStatusId}/favorites"
aria-label={favoritesLabel}>
<SvgIcon className="status-favs-reblogs-svg" href="#fa-star" />
<span>{numFavs}</span>
</a>
</div>
<style>
.status-details {
@ -87,29 +73,6 @@
text-overflow: ellipsis;
}
.status-favs-reblogs {
font-size: 1.1em;
display: flex;
flex-direction: row;
align-items: center;
}
.status-favs-reblogs span {
margin-left: 5px;
}
.status-favs-reblogs,
.status-favs-reblogs:hover,
.status-favs-reblogs:visited {
color: var(--deemphasized-text-color);
}
:global(.status-favs-reblogs-svg) {
fill: var(--deemphasized-text-color);
width: 18px;
height: 18px;
}
:global(.status-absolute-date, .status-absolute-date:hover, .status-absolute-date:visited) {
color: var(--deemphasized-text-color);
}
@ -118,9 +81,6 @@
:global(.status-absolute-date) {
font-size: 1em;
}
.status-favs-reblogs {
font-size: 1em;
}
:global(.status-application) {
font-size: 1em;
}
@ -147,7 +107,8 @@
if (status.id === originalStatusId) {
this.set({
overrideNumReblogs: status.reblogs_count || 0,
overrideNumFavs: status.favourites_count || 0
overrideNumFavs: status.favourites_count || 0,
overrideNumReplies: status.replies_count || 0
})
}
})
@ -155,7 +116,8 @@
store: () => store,
data: () => ({
overrideNumReblogs: undefined,
overrideNumFavs: undefined
overrideNumFavs: undefined,
overrideNumReplies: undefined
}),
computed: {
editedAt: ({ originalStatus }) => originalStatus.edited_at,
@ -163,39 +125,9 @@
application: ({ originalStatus }) => originalStatus.application,
applicationName: ({ application }) => (application && application.name),
applicationWebsite: ({ application }) => (application && application.website),
numReblogs: ({ $disableReblogCounts, overrideNumReblogs, originalStatus }) => {
if ($disableReblogCounts) {
return 0
}
if (typeof overrideNumReblogs === 'number') {
return overrideNumReblogs
}
return originalStatus.reblogs_count || 0
},
numFavs: ({ $disableFavCounts, overrideNumFavs, originalStatus }) => {
if ($disableFavCounts) {
return 0
}
if (typeof overrideNumFavs === 'number') {
return overrideNumFavs
}
return originalStatus.favourites_count || 0
},
displayAbsoluteFormattedDate: ({ createdAtDateTS, $isMobileSize }) => (
($isMobileSize ? shortAbsoluteDateFormatter : absoluteDateFormatter)().format(createdAtDateTS)
),
reblogsLabel: ({ $disableReblogCounts, numReblogs }) => {
if ($disableReblogCounts) {
return 'intl.reblogCountsHidden'
}
return formatIntl('intl.rebloggedTimes', { count: numReblogs })
},
favoritesLabel: ({ $disableFavCounts, numFavs }) => {
if ($disableFavCounts) {
return 'intl.favoriteCountsHidden'
}
return formatIntl('intl.favoritedTimes', { count: numFavs })
},
externalLinkLabel: ({ displayAbsoluteFormattedDate }) => (
formatIntl('intl.opensInNewWindow', { label: displayAbsoluteFormattedDate })
),
@ -204,8 +136,7 @@
)
},
components: {
ExternalLink,
SvgIcon
ExternalLink
}
}
</script>

View File

@ -1,3 +1,5 @@
<!-- LOCAL: this is the main toolbar underneath each toot in every view.
TODO: add reblog and favorite counts here, remove them from StatusDetails.html -->
<div class="status-toolbar {isStatusInOwnThread ? 'status-in-own-thread' : ''}" ref:node>
<IconButton
className="status-toolbar-reply-button"
@ -9,9 +11,15 @@
clickListener={false}
elementId={replyKey}
/>
<a class="status-favs-reblogs status-replies"
rel="prefetch"
href="/statuses/{originalStatusId}"
aria-label={repliesLabel}>
<span>{numReplies}</span>
</a>
<IconButton
label={reblogLabel}
pressedLabel="Unboost"
pressedLabel="{intl.unreblog}"
pressable={!reblogDisabled}
pressed={reblogged}
checked={reblogged}
@ -21,6 +29,12 @@
elementId={reblogKey}
ref:reblogIcon
/>
<a class="status-favs-reblogs status-reblogs"
rel="prefetch"
href="/statuses/{originalStatusId}/reblogs"
aria-label={reblogsLabel}>
<span>{numReblogs}</span>
</a>
<IconButton
label="{intl.favorite}"
pressedLabel="{intl.unfavorite}"
@ -32,6 +46,12 @@
elementId={favoriteKey}
ref:favoriteIcon
/>
<a class="status-favs-reblogs status-favs"
rel="prefetch"
href="/statuses/{originalStatusId}/favorites"
aria-label={favoritesLabel}>
<span>{numFavs}</span>
</a>
<IconButton
label="{intl.moreOptions}"
href="#fa-ellipsis-h"
@ -57,12 +77,43 @@
margin-left: 63px; /* offset to align all toolbar items: 48px avatar + 15px margin-right */
}
.status-favs-reblogs {
font-size: 1.1em;
display: flex;
flex-direction: row;
align-items: center;
width: 100%; /* easiest way to move the counts next to the icon button */
pointer-events: auto;
}
.status-favs-reblogs span {
margin-left: 5px;
}
.status-favs-reblogs,
.status-favs-reblogs:hover,
.status-favs-reblogs:visited {
color: var(--deemphasized-text-color);
}
:global(.status-favs-reblogs-svg) {
fill: var(--deemphasized-text-color);
width: 18px;
height: 18px;
}
@media (max-width: 767px) {
.status-toolbar.status-in-own-thread {
margin-left: 53px; /* offset to align all toolbar items: 48px avatar + 5px margin-right */
}
}
@media (max-width: 479px) {
.status-favs-reblogs {
font-size: 1em;
}
}
@media (max-width: 240px) {
:global(.status-toolbar .icon-button-svg) {
width: 20px;
@ -83,6 +134,7 @@
import { on } from '../../_utils/eventBus.js'
import { announceAriaLivePolite } from '../../_utils/announceAriaLivePolite.js'
import { setStatusBookmarkedOrUnbookmarked } from '../../_actions/bookmark.js'
import { formatIntl } from '../../_utils/formatIntl.js'
export default {
oncreate () {
@ -184,13 +236,32 @@
},
data: () => ({
favoriteAnimation: FAVORITE_ANIMATION,
reblogAnimation: REBLOG_ANIMATION
reblogAnimation: REBLOG_ANIMATION,
overrideNumReblogs: undefined,
overrideNumFavs: undefined,
overrideNumReplies: undefined
}),
computed: {
replyLabel: ({ inReplyToId }) => (
inReplyToId ? 'intl.replyToThread' : 'intl.reply'
),
replyIcon: ({ inReplyToId }) => inReplyToId ? '#fa-reply-all' : '#fa-reply',
numReplies: ({ $disableReplyCounts, overrideNumReplies, originalStatus }) => {
if ($disableReplyCounts) {
return ''
}
if (typeof overrideNumReplies === 'number') {
return overrideNumReplies
}
return originalStatus.replies_count || ''
},
repliesLabel: ({ $disableReplyCounts, numReplies }) => {
if ($disableReplyCounts) {
return 'intl.replyCountsHidden'
}
if (numReplies > 0)
return formatIntl('intl.replyCount', { count: numReplies })
},
reblogLabel: ({ visibility }) => {
switch (visibility) {
case 'private':
@ -220,12 +291,42 @@
}
return originalStatus.reblogged
},
numReblogs: ({ $disableReblogCounts, overrideNumReblogs, originalStatus }) => {
if ($disableReblogCounts) {
return ''
}
if (typeof overrideNumReblogs === 'number') {
return overrideNumReblogs
}
return originalStatus.reblogs_count || ''
},
reblogsLabel: ({ $disableReblogCounts, numReblogs }) => {
if ($disableReblogCounts) {
return 'intl.reblogCountsHidden'
}
return formatIntl('intl.rebloggedTimes', { count: numReblogs })
},
favorited: ({ originalStatusId, $currentStatusModifications, originalStatus }) => {
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.favorites) {
return $currentStatusModifications.favorites[originalStatusId]
}
return originalStatus.favourited
},
numFavs: ({ $disableFavCounts, overrideNumFavs, originalStatus }) => {
if ($disableFavCounts) {
return ''
}
if (typeof overrideNumFavs === 'number') {
return overrideNumFavs
}
return originalStatus.favourites_count || ''
},
favoritesLabel: ({ $disableFavCounts, numFavs }) => {
if ($disableFavCounts) {
return 'intl.favoriteCountsHidden'
}
return formatIntl('intl.favoritedTimes', { count: numFavs })
},
favoriteKey: ({ uuid }) => `fav-${uuid}`,
reblogKey: ({ uuid }) => `reblog-${uuid}`,
replyKey: ({ uuid }) => `reply-${uuid}`,

View File

@ -21,6 +21,11 @@
bind:checked="$disableFollowerCounts" on:change="onChange(event)">
{intl.hideFollowerCount}
</label>
<label class="setting-group">
<input type="checkbox" id="choice-disable-reply-counts"
bind:checked="$disableReplyCounts" on:change="onChange(event)">
{intl.hideReplyCount}
</label>
<label class="setting-group">
<input type="checkbox" id="choice-disable-reblog-counts"
bind:checked="$disableReblogCounts" on:change="onChange(event)">
@ -92,6 +97,7 @@
flushChangesToCheckAll () {
const {
disableFollowerCounts,
disableReplyCounts,
disableReblogCounts,
disableFavCounts,
disableNotificationBadge,
@ -99,6 +105,7 @@
enableGrayscale
} = this.store.get()
document.querySelector('#choice-check-all').checked = disableFollowerCounts &&
disableReplyCounts &&
disableReblogCounts &&
disableFavCounts &&
disableNotificationBadge &&
@ -109,6 +116,7 @@
const { checked } = e.target
this.store.set({
disableFollowerCounts: checked,
disableReplyCounts: checked,
disableReblogCounts: checked,
disableFavCounts: checked,
disableNotificationBadge: checked,