mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:12:25 -05:00 
			
		
		
		
	[feature/frontend] Hide "engagement" stats, edits, and other info under a little drop down to unclutter status info bar (#4021)
* dick about with stats a bit * more dicking abuot * lil tweaks * more about-dicking * weee * comments * fixie uppie
This commit is contained in:
		
					parent
					
						
							
								d694666436
							
						
					
				
			
			
				commit
				
					
						2fce027808
					
				
			
		
					 14 changed files with 453 additions and 143 deletions
				
			
		|  | @ -166,6 +166,12 @@ type WebStatus struct { | ||||||
| 	// after the "main" thread, so it and everything | 	// after the "main" thread, so it and everything | ||||||
| 	// below it can be considered "replies". | 	// below it can be considered "replies". | ||||||
| 	ThreadFirstReply bool | 	ThreadFirstReply bool | ||||||
|  | 
 | ||||||
|  | 	// Sorted slice of StatusEdit times for | ||||||
|  | 	// this status, from latest to oldest. | ||||||
|  | 	// Only set if status has been edited. | ||||||
|  | 	// Last entry is always creation time. | ||||||
|  | 	EditTimeline []string `json:"-"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  |  | ||||||
|  | @ -1217,6 +1217,45 @@ func (c *Converter) StatusToWebStatus( | ||||||
| 	// Mark local. | 	// Mark local. | ||||||
| 	webStatus.Local = *s.Local | 	webStatus.Local = *s.Local | ||||||
| 
 | 
 | ||||||
|  | 	// Get edit history for this | ||||||
|  | 	// status, if it's been edited. | ||||||
|  | 	if webStatus.EditedAt != nil { | ||||||
|  | 		// Make sure edits are populated. | ||||||
|  | 		if len(s.Edits) != len(s.EditIDs) { | ||||||
|  | 			s.Edits, err = c.state.DB.GetStatusEditsByIDs(ctx, s.EditIDs) | ||||||
|  | 			if err != nil && !errors.Is(err, db.ErrNoEntries) { | ||||||
|  | 				err := gtserror.Newf("db error getting status edits: %w", err) | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Include each historical entry | ||||||
|  | 		// (this includes the created date). | ||||||
|  | 		for _, edit := range s.Edits { | ||||||
|  | 			webStatus.EditTimeline = append( | ||||||
|  | 				webStatus.EditTimeline, | ||||||
|  | 				util.FormatISO8601(edit.CreatedAt), | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Make sure to include latest revision. | ||||||
|  | 		webStatus.EditTimeline = append( | ||||||
|  | 			webStatus.EditTimeline, | ||||||
|  | 			*webStatus.EditedAt, | ||||||
|  | 		) | ||||||
|  | 
 | ||||||
|  | 		// Sort the slice so it goes from | ||||||
|  | 		// newest -> oldest, like a timeline. | ||||||
|  | 		// | ||||||
|  | 		// It'll look something like: | ||||||
|  | 		// | ||||||
|  | 		//	- edit3 date (ie., latest version) | ||||||
|  | 		//	- edit2 date (if we have it) | ||||||
|  | 		//	- edit1 date (if we have it) | ||||||
|  | 		//	- created date | ||||||
|  | 		slices.Reverse(webStatus.EditTimeline) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	// Set additional templating | 	// Set additional templating | ||||||
| 	// variables on media attachments. | 	// variables on media attachments. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -238,6 +238,31 @@ blockquote { | ||||||
|   border-right: 1px solid #001ea0; |   border-right: 1px solid #001ea0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Status info dropdown button */ | ||||||
|  | .status .status-info .status-stats details.stats-more-info > summary { | ||||||
|  |   color: var(--button-fg); | ||||||
|  |   background: var(--ecks-pee-start-button); | ||||||
|  |   border-left: 1px solid var(--ecks-pee-darkest-green); | ||||||
|  |   border-right: 1px solid var(--ecks-pee-darkest-green); | ||||||
|  | } | ||||||
|  | .status .status-info .status-stats details.stats-more-info > summary:hover { | ||||||
|  |   outline: 0; | ||||||
|  |   background: var(--ecks-pee-light-green); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Status info dropdown content */ | ||||||
|  | .status .status-info .status-stats .stats-more-info-content, | ||||||
|  | .status.expanded .status-info .status-stats .stats-more-info-content { | ||||||
|  |   color: black; | ||||||
|  |   text-shadow: none; | ||||||
|  |   background: var(--ecks-pee-beige); | ||||||
|  |   border: 0.2rem outset var(--ecks-pee-darker-beige); | ||||||
|  |   border-radius: 0; | ||||||
|  | } | ||||||
|  | .status .status-info .status-stats .stats-item.edit-timeline { | ||||||
|  |   border-top: var(--ecks-pee-dotted-trim); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Button stuff */ | /* Button stuff */ | ||||||
| button, .button { | button, .button { | ||||||
|   border-left: 1px solid var(--ecks-pee-darkest-green); |   border-left: 1px solid var(--ecks-pee-darkest-green); | ||||||
|  |  | ||||||
|  | @ -129,6 +129,16 @@ html, body { | ||||||
|   background: black; |   background: black; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Status info dropdown content */ | ||||||
|  | .status.expanded .status-info .status-stats .stats-more-info-content, | ||||||
|  | .status .status-info .status-stats .stats-more-info-content { | ||||||
|  |   background-color: black; | ||||||
|  |   border: 0.25rem solid var(--magenta); | ||||||
|  | } | ||||||
|  | .status .status-info .status-stats .stats-item.edit-timeline { | ||||||
|  |   border-top: 0.15rem dotted var(--acid-green); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Back + next links */ | /* Back + next links */ | ||||||
| .backnextlinks { | .backnextlinks { | ||||||
|   background: var(--gray1); |   background: var(--gray1); | ||||||
|  |  | ||||||
|  | @ -143,6 +143,12 @@ blockquote { | ||||||
|   background: var(--outer-space); |   background: var(--outer-space); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Status info dropdown content */ | ||||||
|  | .status.expanded .status-info .status-stats .stats-more-info-content, | ||||||
|  | .status .status-info .status-stats .stats-more-info-content { | ||||||
|  |   background: var(--outer-space); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Make show more/less buttons more legible */ | /* Make show more/less buttons more legible */ | ||||||
| .status .button { | .status .button { | ||||||
|   border: 1px solid var(--feral-orange); |   border: 1px solid var(--feral-orange); | ||||||
|  |  | ||||||
|  | @ -142,3 +142,9 @@ code, code[class*="language-"] { | ||||||
| blockquote { | blockquote { | ||||||
| 	background-color: var(--soft-lilac-translucent); | 	background-color: var(--soft-lilac-translucent); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /* Status info dropdown content */ | ||||||
|  | .status.expanded .status-info .status-stats .stats-more-info-content, | ||||||
|  | .status .status-info .status-stats .stats-more-info-content { | ||||||
|  |   background: var(--soft-pink); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -29,7 +29,6 @@ | ||||||
| 	border-radius: $br; | 	border-radius: $br; | ||||||
| 	position: relative; | 	position: relative; | ||||||
| 	overflow: hidden; | 	overflow: hidden; | ||||||
| 	z-index: 2; |  | ||||||
| 
 | 
 | ||||||
| 	img { | 	img { | ||||||
| 		width: 100%; | 		width: 100%; | ||||||
|  | @ -59,8 +58,8 @@ | ||||||
| 			position: absolute; | 			position: absolute; | ||||||
| 			height: 100%; | 			height: 100%; | ||||||
| 			width: 100%; | 			width: 100%; | ||||||
| 			z-index: 3; |  | ||||||
| 			overflow: hidden; | 			overflow: hidden; | ||||||
|  | 			z-index: 1; | ||||||
| 
 | 
 | ||||||
| 			display: grid; | 			display: grid; | ||||||
| 			padding: 1rem; | 			padding: 1rem; | ||||||
|  |  | ||||||
|  | @ -28,8 +28,6 @@ | ||||||
| 	padding-top: 0.75rem; | 	padding-top: 0.75rem; | ||||||
| 
 | 
 | ||||||
| 	a { | 	a { | ||||||
| 		position: relative; |  | ||||||
| 		z-index: 1; |  | ||||||
| 		color: inherit; | 		color: inherit; | ||||||
| 		text-decoration: none; | 		text-decoration: none; | ||||||
| 	} | 	} | ||||||
|  | @ -109,11 +107,6 @@ | ||||||
| 		gap: 0.5rem; | 		gap: 0.5rem; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	.text-spoiler > summary, .text { |  | ||||||
| 		position: relative; |  | ||||||
| 		z-index: 2; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.text-spoiler > summary { | 	.text-spoiler > summary { | ||||||
| 		list-style: none; | 		list-style: none; | ||||||
| 		display: flex; | 		display: flex; | ||||||
|  | @ -193,7 +186,6 @@ | ||||||
| 
 | 
 | ||||||
| 		.poll { | 		.poll { | ||||||
| 			background-color: $gray2; | 			background-color: $gray2; | ||||||
| 			z-index: 2; |  | ||||||
| 			 | 			 | ||||||
| 			display: flex; | 			display: flex; | ||||||
| 			flex-direction: column; | 			flex-direction: column; | ||||||
|  | @ -260,59 +252,150 @@ | ||||||
| 			display: flex; | 			display: flex; | ||||||
| 			gap: 1rem; | 			gap: 1rem; | ||||||
| 
 | 
 | ||||||
| 			.stats-grouping { | 			.stats-grouping, | ||||||
|  | 			.stats-more-info-content { | ||||||
| 				display: flex; | 				display: flex; | ||||||
| 				flex-wrap: wrap; | 				flex-wrap: wrap; | ||||||
| 				column-gap: 1rem; |  | ||||||
| 
 |  | ||||||
| 				.edited-at { |  | ||||||
| 					font-size: smaller; |  | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			.stats-grouping { | ||||||
|  | 				column-gap: 1rem; | ||||||
|  | 				row-gap: 0.25rem; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			.stats-item { | 			.stats-item { | ||||||
| 				display: flex; | 				display: flex; | ||||||
| 				gap: 0.4rem; | 				gap: 0.4rem; | ||||||
|  | 				width: fit-content; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			.stats-item.published-at { | 			details.stats-more-info { | ||||||
|  | 				margin-left: auto; | ||||||
|  | 				 | ||||||
|  | 				& > summary { | ||||||
|  | 					display: flex; | ||||||
|  | 
 | ||||||
|  | 					/* | ||||||
|  | 						Make it easy to touch. | ||||||
|  | 					*/ | ||||||
|  | 					width: 3rem; | ||||||
|  | 					height: 2rem; | ||||||
|  | 					margin: -0.25rem -0.5rem; | ||||||
|  | 
 | ||||||
|  | 					/* | ||||||
|  | 						Remove details/summary | ||||||
|  | 						arrow and use our own. | ||||||
|  | 					*/ | ||||||
|  | 					list-style: none; | ||||||
|  | 					&::-webkit-details-marker { | ||||||
|  | 						display: none; /* Safari */ | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					/* | ||||||
|  | 						Don't display the | ||||||
|  | 						"hide" button initially. | ||||||
|  | 					*/ | ||||||
|  | 					i.hide { | ||||||
|  | 						display: none; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					/* | ||||||
|  | 						Normalize fa | ||||||
|  | 						icon alignment. | ||||||
|  | 					*/ | ||||||
|  | 					align-items: center; | ||||||
|  | 					i.fa { | ||||||
|  | 						text-align: center; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					cursor: pointer; | ||||||
|  | 					border-radius: $br-inner; | ||||||
|  | 					&:focus-visible { | ||||||
|  | 						outline: $button-focus-outline; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					&:hover { | ||||||
|  | 						outline: 0.1rem solid $fg-reduced; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				@keyframes fade-in { | ||||||
|  | 					0%    {opacity: 0} | ||||||
|  | 					100%  {opacity: 1} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				&[open] { | ||||||
|  | 					.stats-more-info-content { | ||||||
|  | 						animation: fade-in .1s; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					& > summary i.show { | ||||||
|  | 						display: none; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					& > summary i.hide { | ||||||
|  | 						display: block; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			.stats-more-info-content { | ||||||
|  | 				position: absolute; | ||||||
|  | 				right: 0; | ||||||
|  | 				z-index: 2; | ||||||
|  | 				 | ||||||
|  | 				flex-direction: column; | ||||||
|  | 				max-width: 100%; | ||||||
|  | 				row-gap: 0.5rem; | ||||||
|  | 
 | ||||||
|  | 				background: $status-info-bg; | ||||||
|  | 				padding: 0.5rem 0.75rem; | ||||||
|  | 				border: $boxshadow-border; | ||||||
|  | 				box-shadow: $boxshadow; | ||||||
|  | 
 | ||||||
|  | 				opacity: 1; | ||||||
|  | 
 | ||||||
|  | 				.stats-grouping { | ||||||
|  | 					width: 100%; | ||||||
|  | 					justify-content: space-between; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			.stats-item.published-at dd a { | ||||||
|  | 				time.dt-published { | ||||||
| 					text-decoration: underline; | 					text-decoration: underline; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 			.stats-item:not(.published-at):not(.edited-at) { | 				&:focus-visible { | ||||||
| 				z-index: 1; | 					outline: 0; | ||||||
|  | 					time.dt-published { | ||||||
|  | 						outline: $link-focus-outline; | ||||||
|  | 						outline-offset: -0.25rem; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			.stats-item:not(.published-at):not(.edit-timeline) { | ||||||
| 				user-select: none; | 				user-select: none; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			.language { | 			.stats-item.edit-timeline { | ||||||
| 				margin-left: auto; | 				flex-direction: column; | ||||||
|  | 				width: 100%; | ||||||
|  | 				border-top: $boxshadow-border; | ||||||
|  | 				padding-top: 0.4rem; | ||||||
|  | 				 | ||||||
|  | 				dd { | ||||||
|  | 					display: flex; | ||||||
|  | 					align-items: center; | ||||||
|  | 					gap: 0.4rem; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		grid-column: span 3; | 		grid-column: span 3; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	.status-link { |  | ||||||
| 		top: 0; |  | ||||||
| 		right: 0; |  | ||||||
| 		bottom: 0; |  | ||||||
| 		left: 0; |  | ||||||
| 		overflow: hidden; |  | ||||||
| 		text-indent: 100%; |  | ||||||
| 		white-space: nowrap; |  | ||||||
| 
 |  | ||||||
| 		position: absolute; |  | ||||||
| 		z-index: 0; |  | ||||||
| 
 |  | ||||||
| 		&:focus-visible { |  | ||||||
| 			/* |  | ||||||
| 				Inset focus to compensate for themes where |  | ||||||
| 				statuses have a really thick border. |  | ||||||
| 			*/ |  | ||||||
| 			outline-offset: -0.25rem; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	&:first-child { | 	&:first-child { | ||||||
| 		/* top left, top right */ | 		/* top left, top right */ | ||||||
| 		border-top-left-radius: $br; | 		border-top-left-radius: $br; | ||||||
|  | @ -327,7 +410,8 @@ | ||||||
| 
 | 
 | ||||||
| 	&.expanded { | 	&.expanded { | ||||||
| 		background: $status-focus-bg; | 		background: $status-focus-bg; | ||||||
| 		.status-info { | 		.status-info, | ||||||
|  | 		.status-info .status-stats .stats-more-info-content { | ||||||
| 			background: $status-focus-info-bg; | 			background: $status-focus-info-bg; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -79,9 +79,18 @@ | ||||||
| 		&.indent-3, | 		&.indent-3, | ||||||
| 		&.indent-4, | 		&.indent-4, | ||||||
| 		&.indent-5 { | 		&.indent-5 { | ||||||
| 			.status-link { | 			/* | ||||||
| 				margin-left: -0.5rem; | 				Show a stripey line to the left of | ||||||
|  | 				indented statuses for better legibility. | ||||||
|  | 			*/ | ||||||
|  | 			&::before { | ||||||
|  | 				content: ""; | ||||||
|  | 				position: absolute; | ||||||
|  | 				left: 0; | ||||||
|  | 				top: 0; | ||||||
|  | 				height: 100%; | ||||||
| 				border-left: 0.15rem dashed $border-accent; | 				border-left: 0.15rem dashed $border-accent; | ||||||
|  | 				margin-left: -0.5rem; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -338,3 +338,25 @@ Array.from(document.getElementsByTagName('time')).forEach(timeTag => { | ||||||
| 		timeTag.textContent = dateTimeFormat.format(date); | 		timeTag.textContent = dateTimeFormat.format(date); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | // When clicking anywhere that's not an open
 | ||||||
|  | // stats-info-more-content details dropdown,
 | ||||||
|  | // close that open dropdown.
 | ||||||
|  | document.body.addEventListener("click", (e) => { | ||||||
|  | 	const openStats = document.querySelector("details.stats-more-info[open]"); | ||||||
|  | 	if (!openStats) { | ||||||
|  | 		// No open stats
 | ||||||
|  | 		// details element.
 | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (openStats.contains(e.target)) { | ||||||
|  | 		// Click is within stats
 | ||||||
|  | 		// element, leave it alone.
 | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Click was outside of
 | ||||||
|  | 	// stats elements, close it. 
 | ||||||
|  | 	openStats.removeAttribute("open"); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ | ||||||
| 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| import React, { useState } from "react"; | import React, { useMemo, useState } from "react"; | ||||||
| import { useVerifyCredentialsQuery } from "../lib/query/login"; | import { useVerifyCredentialsQuery } from "../lib/query/login"; | ||||||
| import { MediaAttachment, Status as StatusType } from "../lib/types/status"; | import { MediaAttachment, Status as StatusType } from "../lib/types/status"; | ||||||
| import sanitize from "sanitize-html"; | import sanitize from "sanitize-html"; | ||||||
|  | @ -68,15 +68,6 @@ export function Status({ status }: { status: StatusType }) { | ||||||
| 			<StatusHeader status={status} /> | 			<StatusHeader status={status} /> | ||||||
| 			<StatusBody status={status} /> | 			<StatusBody status={status} /> | ||||||
| 			<StatusFooter status={status} /> | 			<StatusFooter status={status} /> | ||||||
| 			<a |  | ||||||
| 				href={status.url} |  | ||||||
| 				target="_blank" |  | ||||||
| 				className="status-link" |  | ||||||
| 				data-nosnippet |  | ||||||
| 				title="Open this status (opens in new tab)" |  | ||||||
| 			> |  | ||||||
| 				Open this status (opens in new tab) |  | ||||||
| 			</a> |  | ||||||
| 		</article> | 		</article> | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
|  | @ -266,25 +257,103 @@ function StatusMediaEntry({ media }: { media: MediaAttachment }) { | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function useVisibilityIcon(visibility: string): string { | ||||||
|  | 	return useMemo(() => { | ||||||
|  | 		switch (true) { | ||||||
|  | 			case visibility === "direct": | ||||||
|  | 				return "fa-envelope"; | ||||||
|  | 			case visibility === "followers_only": | ||||||
|  | 				return "fa-lock"; | ||||||
|  | 			case visibility === "unlisted": | ||||||
|  | 				return "fa-unlock"; | ||||||
|  | 			case visibility === "public": | ||||||
|  | 				return "fa-globe"; | ||||||
|  | 			default: | ||||||
|  | 				return "fa-question"; | ||||||
|  | 		} | ||||||
|  | 	}, [visibility]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function StatusFooter({ status }: { status: StatusType }) { | function StatusFooter({ status }: { status: StatusType }) { | ||||||
|  | 	const visibilityIcon = useVisibilityIcon(status.visibility);	 | ||||||
| 	return ( | 	return ( | ||||||
| 		<aside className="status-info"> | 		<aside className="status-info"> | ||||||
| 			<dl className="status-stats"> | 			<div className="status-stats"> | ||||||
| 				<div className="stats-grouping"> | 				<dl className="stats-grouping text-cutoff"> | ||||||
| 					<div className="stats-item published-at text-cutoff"> | 					<div className="stats-item published-at text-cutoff"> | ||||||
| 						<dt className="sr-only">Published</dt> | 						<dt className="sr-only">Published</dt> | ||||||
| 						<dd> | 						<dd className="text-cutoff"> | ||||||
| 							<time dateTime={status.created_at}> | 							<a | ||||||
| 								{ new Date(status.created_at).toLocaleString() } | 								href={status.url} | ||||||
|  | 								className="u-url text-cutoff" | ||||||
|  | 							> | ||||||
|  | 								<time | ||||||
|  | 									className="dt-published text-cutoff" | ||||||
|  | 									dateTime={status.created_at} | ||||||
|  | 								> | ||||||
|  | 									{new Date(status.created_at).toLocaleString(undefined, { | ||||||
|  | 										year: 'numeric', | ||||||
|  | 										month: 'short', | ||||||
|  | 										day: '2-digit', | ||||||
|  | 										hour: '2-digit', | ||||||
|  | 										minute: '2-digit', | ||||||
|  | 										hour12: false | ||||||
|  | 									})} | ||||||
| 								</time> | 								</time> | ||||||
|  | 							</a> | ||||||
|  | 						</dd> | ||||||
|  | 					</div> | ||||||
|  | 					<div className="stats-grouping"> | ||||||
|  | 						<div className="stats-item visibility-level" title={status.visibility}> | ||||||
|  | 							<dt className="sr-only">Visibility</dt> | ||||||
|  | 							<dd> | ||||||
|  | 								<i className={`fa ${visibilityIcon}`} aria-hidden="true"></i> | ||||||
|  | 								<span className="sr-only">{status.visibility}</span> | ||||||
| 							</dd> | 							</dd> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 				<div className="stats-item language"> | 				</dl> | ||||||
| 					<dt className="sr-only">Language</dt> | 				<details className="stats-more-info"> | ||||||
|  | 					<summary title="More info"> | ||||||
|  | 						<i className="fa fa-fw fa-info" aria-hidden="true"></i> | ||||||
|  | 						<span className="sr-only">More info</span> | ||||||
|  | 						<i className="fa fa-fw fa-chevron-right show" aria-hidden="true"></i> | ||||||
|  | 						<i className="fa fa-fw fa-chevron-down hide" aria-hidden="true"></i> | ||||||
|  | 					</summary> | ||||||
|  | 					<dl className="stats-more-info-content"> | ||||||
|  | 						<div className="stats-grouping"> | ||||||
|  | 							<div className="stats-item" title="Language"> | ||||||
|  | 								<dt> | ||||||
|  | 									<span className="sr-only">Language</span> | ||||||
|  | 									<i className="fa fa-language" aria-hidden="true"></i> | ||||||
|  | 								</dt> | ||||||
| 								<dd>{status.language}</dd> | 								<dd>{status.language}</dd> | ||||||
| 							</div> | 							</div> | ||||||
|  | 							<div className="stats-item" title="Replies"> | ||||||
|  | 								<dt> | ||||||
|  | 									<span className="sr-only">Replies</span> | ||||||
|  | 									<i className="fa fa-reply-all" aria-hidden="true"></i> | ||||||
|  | 								</dt> | ||||||
|  | 								<dd>{status.replies_count}</dd> | ||||||
|  | 							</div> | ||||||
|  | 							<div className="stats-item" title="Faves"> | ||||||
|  | 								<dt> | ||||||
|  | 									<span className="sr-only">Favourites</span> | ||||||
|  | 									<i className="fa fa-star" aria-hidden="true"></i> | ||||||
|  | 								</dt> | ||||||
|  | 								<dd>{status.favourites_count}</dd> | ||||||
|  | 							</div> | ||||||
|  | 							<div className="stats-item" title="Boosts"> | ||||||
|  | 								<dt> | ||||||
|  | 									<span className="sr-only">Reblogs</span> | ||||||
|  | 									<i className="fa fa-retweet" aria-hidden="true"></i> | ||||||
|  | 								</dt> | ||||||
|  | 								<dd>{status.reblogs_count}</dd> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
| 					</dl> | 					</dl> | ||||||
|  | 				</details> | ||||||
|  | 			</div> | ||||||
| 		</aside> | 		</aside> | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -90,27 +90,7 @@ media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{ | ||||||
|     </div> |     </div> | ||||||
|     {{- end }} |     {{- end }} | ||||||
| </div> | </div> | ||||||
| <aside class="status-info" aria-hidden="true"> | <aside class="status-info"> | ||||||
|     {{- include "status_info.tmpl" . | indent 1 }} |     {{- include "status_info.tmpl" . | indent 1 }} | ||||||
| </aside> | </aside> | ||||||
| {{- if .Local }} |  | ||||||
| <a |  | ||||||
|     href="{{- .URL -}}" |  | ||||||
|     class="status-link u-url" |  | ||||||
|     data-nosnippet |  | ||||||
|     title="Open thread at this post" |  | ||||||
| > |  | ||||||
|     Open thread at this post |  | ||||||
| </a> |  | ||||||
| {{- else }} |  | ||||||
| <a |  | ||||||
|     href="{{- .URL -}}" |  | ||||||
|     class="status-link u-url" |  | ||||||
|     data-nosnippet |  | ||||||
|     rel="nofollow noreferrer noopener" target="_blank" |  | ||||||
|     title="Open remote post (opens in a new window)" |  | ||||||
| > |  | ||||||
|     Open remote post (opens in a new window) |  | ||||||
| </a> |  | ||||||
| {{- end }} |  | ||||||
| {{- end }} | {{- end }} | ||||||
|  | @ -38,7 +38,33 @@ | ||||||
| {{- end -}} | {{- end -}} | ||||||
| 
 | 
 | ||||||
| {{- with . }} | {{- with . }} | ||||||
| <dl class="status-stats"> | <div class="status-stats"> | ||||||
|  |     <dl class="stats-grouping text-cutoff"> | ||||||
|  |         <div class="stats-item published-at text-cutoff"> | ||||||
|  |             <dt class="sr-only">Published</dt> | ||||||
|  |             <dd class="text-cutoff"> | ||||||
|  |                 {{- if .Local }} | ||||||
|  |                 <a | ||||||
|  |                     href="{{- .URL -}}" | ||||||
|  |                     class="u-url text-cutoff" | ||||||
|  |                     data-nosnippet | ||||||
|  |                     title="Open thread at this post" | ||||||
|  |                 > | ||||||
|  |                     <time class="dt-published text-cutoff" datetime="{{- .CreatedAt -}}">{{- .CreatedAt | timestampPrecise -}}</time>{{- if .EditedAt }}*{{- end }} | ||||||
|  |                 </a> | ||||||
|  |                 {{- else }} | ||||||
|  |                 <a | ||||||
|  |                     href="{{- .URL -}}" | ||||||
|  |                     class="u-url text-cutoff" | ||||||
|  |                     data-nosnippet | ||||||
|  |                     rel="nofollow noreferrer noopener" target="_blank" | ||||||
|  |                     title="Open remote post (opens in a new window)" | ||||||
|  |                 > | ||||||
|  |                     <time class="dt-published text-cutoff" datetime="{{- .CreatedAt -}}">{{- .CreatedAt | timestampPrecise -}}</time>{{- if .EditedAt }}*{{- end }} | ||||||
|  |                 </a> | ||||||
|  |                 {{- end }} | ||||||
|  |             </dd> | ||||||
|  |         </div> | ||||||
|         <div class="stats-grouping"> |         <div class="stats-grouping"> | ||||||
|             <div class="stats-item visibility-level" title="{{- template "visibility_title" . -}}"> |             <div class="stats-item visibility-level" title="{{- template "visibility_title" . -}}"> | ||||||
|                 <dt class="sr-only">Visibility</dt> |                 <dt class="sr-only">Visibility</dt> | ||||||
|  | @ -47,21 +73,17 @@ | ||||||
|                     <span class="sr-only">{{- template "visibility_title" . -}}</span> |                     <span class="sr-only">{{- template "visibility_title" . -}}</span> | ||||||
|                 </dd> |                 </dd> | ||||||
|             </div> |             </div> | ||||||
|         <div class="stats-item published-at text-cutoff"> |             {{- if .Pinned }} | ||||||
|             <dt class="sr-only">Published</dt> |             <div class="stats-item" title="Pinned"> | ||||||
|             <dd> |                 <dt> | ||||||
|                 <time class="dt-published" datetime="{{- .CreatedAt -}}">{{- .CreatedAt | timestampPrecise -}}</time> |                     <span class="sr-only">Pinned</span> | ||||||
|             </dd> |                     <i class="fa fa-thumb-tack" aria-hidden="true"></i> | ||||||
|  |                 </dt> | ||||||
|  |                 <dd class="sr-only">{{- .Pinned -}}</dd> | ||||||
|             </div> |             </div> | ||||||
|         {{- if .EditedAt -}} |             {{- else }} | ||||||
|         <div class="stats-item edited-at text-cutoff"> |             {{- end }} | ||||||
|             <dt class="sr-only">Edited</dt> |             {{- if .RepliesCount }} | ||||||
|             <dd> |  | ||||||
|                 edited <time class="dt-updated" datetime="{{- .EditedAt -}}">{{- .EditedAt | timestampPrecise -}}</time> |  | ||||||
|             </dd> |  | ||||||
|         </div> |  | ||||||
|         {{ end }} |  | ||||||
|         <div class="stats-grouping"> |  | ||||||
|             <div class="stats-item" title="Replies"> |             <div class="stats-item" title="Replies"> | ||||||
|                 <dt> |                 <dt> | ||||||
|                     <span class="sr-only">Replies</span> |                     <span class="sr-only">Replies</span> | ||||||
|  | @ -69,6 +91,42 @@ | ||||||
|                 </dt> |                 </dt> | ||||||
|                 <dd>{{- .RepliesCount -}}</dd> |                 <dd>{{- .RepliesCount -}}</dd> | ||||||
|             </div> |             </div> | ||||||
|  |             {{- else }} | ||||||
|  |             {{- end }} | ||||||
|  |         </div> | ||||||
|  |     </dl> | ||||||
|  |     <details class="stats-more-info" name="stats-more-info"> | ||||||
|  |         <summary title="More info"> | ||||||
|  |             <i class="fa fa-fw fa-info" aria-hidden="true"></i> | ||||||
|  |             <span class="sr-only">More info</span> | ||||||
|  |             <i class="fa fa-fw fa-chevron-right show" aria-hidden="true"></i> | ||||||
|  |             <i class="fa fa-fw fa-chevron-down hide" aria-hidden="true"></i> | ||||||
|  |         </summary> | ||||||
|  |         <dl class="stats-more-info-content"> | ||||||
|  |             <div class="stats-grouping"> | ||||||
|  |                 {{- if .LanguageTag.DisplayStr }} | ||||||
|  |                 <div class="stats-item" title="Language"> | ||||||
|  |                     <dt> | ||||||
|  |                         <span class="sr-only">Language</span> | ||||||
|  |                         <i class="fa fa-language" aria-hidden="true"></i> | ||||||
|  |                     </dt> | ||||||
|  |                     <dd> | ||||||
|  |                         <span class="sr-only">{{ .LanguageTag.DisplayStr -}}</span> | ||||||
|  |                         <span aria-hidden="true" title="{{- .LanguageTag.DisplayStr -}}">{{- .LanguageTag.TagStr -}}</span> | ||||||
|  |                     </dd> | ||||||
|  |                 </div> | ||||||
|  |                 {{- else }} | ||||||
|  |                 {{- end }} | ||||||
|  |                 {{- if not .RepliesCount }} | ||||||
|  |                 <div class="stats-item" title="Replies"> | ||||||
|  |                     <dt> | ||||||
|  |                         <span class="sr-only">Replies</span> | ||||||
|  |                         <i class="fa fa-reply-all" aria-hidden="true"></i> | ||||||
|  |                     </dt> | ||||||
|  |                     <dd>{{- .RepliesCount -}}</dd> | ||||||
|  |                 </div> | ||||||
|  |                 {{- else }} | ||||||
|  |                 {{- end }} | ||||||
|                 <div class="stats-item" title="Faves"> |                 <div class="stats-item" title="Faves"> | ||||||
|                     <dt> |                     <dt> | ||||||
|                         <span class="sr-only">Favourites</span> |                         <span class="sr-only">Favourites</span> | ||||||
|  | @ -83,27 +141,28 @@ | ||||||
|                     </dt> |                     </dt> | ||||||
|                     <dd>{{- .ReblogsCount -}}</dd> |                     <dd>{{- .ReblogsCount -}}</dd> | ||||||
|                 </div> |                 </div> | ||||||
|             {{- if .Pinned }} |  | ||||||
|             <div class="stats-item" title="Pinned"> |  | ||||||
|                 <dt> |  | ||||||
|                     <span class="sr-only">Pinned</span> |  | ||||||
|                     <i class="fa fa-thumb-tack" aria-hidden="true"></i> |  | ||||||
|                 </dt> |  | ||||||
|                 <dd class="sr-only">{{- .Pinned -}}</dd> |  | ||||||
|             </div> |             </div> | ||||||
|             {{- else }} |             {{- if and .EditedAt (gt (len .EditTimeline) 1) -}} | ||||||
|             {{- end }} |             <div class="stats-item edit-timeline text-cutoff"> | ||||||
|         </div> |                 <dt>Edit timeline:</dt> | ||||||
|     </div> |                 {{- range $index, $edited := .EditTimeline }} | ||||||
|     {{- if .LanguageTag.DisplayStr }} |                 {{- if not (eq $index (add (len $.EditTimeline) -1)) }} | ||||||
|     <div class="stats-item language" title="{{ .LanguageTag.DisplayStr }}"> |                 <dd class="text-cutoff" title="Edited {{ $edited -}}"> | ||||||
|         <dt class="sr-only">Language</dt> |                     <span class="sr-only">Edited</span> | ||||||
|         <dd> |                     <i class="fa fa-asterisk" aria-hidden="true"></i> | ||||||
|             <span class="sr-only">{{ .LanguageTag.DisplayStr }}</span> |                     <time datetime="{{- $edited -}}">{{- $edited | timestampPrecise -}}</time> | ||||||
|             <span aria-hidden="true">{{- .LanguageTag.TagStr -}}</span> |  | ||||||
|                 </dd> |                 </dd> | ||||||
|     </div> |  | ||||||
|                 {{- else }} |                 {{- else }} | ||||||
|  |                 <dd class="text-cutoff" title="Published {{ $.CreatedAt -}}"> | ||||||
|  |                     <span class="sr-only">Published</span> | ||||||
|  |                     <i class="fa fa-pencil" aria-hidden="true"></i> | ||||||
|  |                     <time datetime="{{- $.CreatedAt -}}">{{- $.CreatedAt | timestampPrecise -}}</time> | ||||||
|  |                 </dd> | ||||||
|                 {{- end }} |                 {{- end }} | ||||||
|  |                 {{- end }} | ||||||
|  |             </div> | ||||||
|  |             {{ end }} | ||||||
|         </dl> |         </dl> | ||||||
|  |     </details> | ||||||
|  | </div> | ||||||
| {{- end }} | {{- end }} | ||||||
|  | @ -78,7 +78,6 @@ | ||||||
|             <a href="#replies">jump to replies</a> |             <a href="#replies">jump to replies</a> | ||||||
|             {{- end }} |             {{- end }} | ||||||
|         </div> |         </div> | ||||||
| 
 |  | ||||||
|         {{- range $status := .context.Statuses }} |         {{- range $status := .context.Statuses }} | ||||||
|         <article |         <article | ||||||
|             class="status{{- if $status.ThreadContextStatus }} expanded{{- end -}}{{- if $status.Indent }} indent-{{ $status.Indent }}{{- end -}}" |             class="status{{- if $status.ThreadContextStatus }} expanded{{- end -}}{{- if $status.Indent }} indent-{{ $status.Indent }}{{- end -}}" | ||||||
|  | @ -90,9 +89,6 @@ | ||||||
|         {{- include "repliesStart" $ | indent 1 }} |         {{- include "repliesStart" $ | indent 1 }} | ||||||
|         {{- end }} |         {{- end }} | ||||||
|         {{- end }} |         {{- end }} | ||||||
| 
 |  | ||||||
|     {{- if .context.ThreadReplies }} |  | ||||||
|     </section> |     </section> | ||||||
|     {{- end }} |  | ||||||
| </main> | </main> | ||||||
| {{- end }} | {{- end }} | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue