11 Commits

Author SHA1 Message Date
Zoë Bijl 60731df277 [bugfix] show header logo + align header buttons
the logo wasn’t showing on the small screen layout. this fixes that. it also neatly aligns the buttons in the header area.
2025-10-24 10:44:30 +02:00
tobi ac7354ca62 [chore/docker] Remove reference to vanilla in Dockerfile (#114)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/114
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
2025-10-21 15:49:01 +02:00
Zoë Bijl 6e2caa1c2c [docs] fix typo 2025-10-21 15:16:52 +02:00
kipvandenbos 5447f63a3c [bugfix] Use correct branch name for next publication (#113)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/113
Co-authored-by: kipvandenbos <kipvandenbos@noreply.codeberg.org>
Co-committed-by: kipvandenbos <kipvandenbos@noreply.codeberg.org>
2025-10-21 15:11:49 +02:00
tobi f5a55a64df [feature/cicd] Add next image publication on squerge to next branch (#112)
Build a `next` tagged docker image when we squerge something into next (makes my life a bit easier).

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/112
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
2025-10-21 15:08:31 +02:00
Zoë Bijl b976e9438f [bugfix] rewrite basic media-gallery css (#109)
Solves an issue where only four images would show up if more than four were added.

Fixes #34 & #107

Example of a post with many images:

![A post with thirteen images attached. they form a nice two column grid with the last item being two columns wide](/attachments/c44a4985-5297-4395-8964-15651b947d87)

---

@jacksonchen666 suggested we have a limit to the number of images and perhaps some sort of indicator to show that there are more images. I’ve made [an issue to track that](https://codeberg.org/superseriousbusiness/masto-fe-standalone/issues/110).

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/109
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-21 14:34:40 +02:00
Zoë Bijl d03bfe2ab8 [bugfix] further CSS fixes for Phosphor update
commit 242cfc4b06
Author: Zoë Bijl <code@moiety.me>
Date:   Tue Oct 21 00:22:46 2025 +0200

    [bugfix] tweak display name alignment

commit 23e5d9840f
Author: Zoë Bijl <code@moiety.me>
Date:   Tue Oct 21 00:00:59 2025 +0200

    [bugfix] improve display name alignment

commit 1664835c94
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 17:03:52 2025 +0200

    [feature] add text-decoration to usernames and hashtags

commit d4fdb18549
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 16:38:08 2025 +0200

    [bugfix] correct spacing in status__content__spoiler

commit c19307a115
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 16:28:30 2025 +0200

    [feature] remove giant logo in multi-column view

commit 51e2c6e1c3
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 16:24:52 2025 +0200

    [feature] add gts logo in the multi-column menu

commit edc83b0f54
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 16:23:26 2025 +0200

    [bugfix] fix width of fullwidth media gallery

commit 9923c1b6da
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 15:17:25 2025 +0200

    [chore] remove `fixedWith` from icons

commit 935d6b73ef
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 15:09:43 2025 +0200

    [chore] lint

commit 776f02bd5f
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 15:07:52 2025 +0200

    [bugfix] correctly align multiline column-header button

commit d988d35671
Author: Zoë Bijl <code@moiety.me>
Date:   Mon Oct 20 15:04:35 2025 +0200

    [feat] add new size variables

commit 34bcbb669d
Author: Zoë Bijl <code@moiety.me>
Date:   Sun Oct 19 23:47:20 2025 +0200

    [bugfix] re-enable hicolor privacy icons

commit 97f2cb8f69
Author: Zoë Bijl <code@moiety.me>
Date:   Sun Oct 19 23:26:16 2025 +0200

    [bugfix] correctly align “toot” buttons

commit 52bcd4b6d0
Author: Zoë Bijl <code@moiety.me>
Date:   Thu Oct 16 16:22:44 2025 +0200

    [bugfix] replace `--size` with global `--size-icon`

    BREAKING CHANGE: any user styles that overwrote `--size` in a `,gts-icon` class will need to be updated.

commit 9812a2611f
Author: Zoë Bijl <code@moiety.me>
Date:   Thu Oct 16 15:53:37 2025 +0200

    [bugfix] further tweaks to `.poll__footer` alignment

commit 798d6fbf79
Author: Zoë Bijl <code@moiety.me>
Date:   Thu Oct 16 15:38:45 2025 +0200

    [bugfix] correctly align .poll__footer
2025-10-21 00:31:41 +02:00
Annika Backstrom 9e1c6c3646 [chore] disable collapsed posts by default
Fixes #98
2025-10-18 12:51:36 +01:00
Zoë Bijl 4b4b4b9d38 [bugfix] correct lock-open-simple direction
the lock opened the wrong way; it was pointing left when it should’ve pointed right to be consistent with GTS.
2025-10-16 15:21:46 +02:00
Zoë Bijl 7f073ccd59 [docs] update changelog 2025-10-16 14:40:54 +02:00
Zoë Bijl 02c368b22a [chore] remove last reference to font-awesome 2025-10-16 12:57:43 +02:00
67 changed files with 393 additions and 314 deletions
+24
View File
@@ -0,0 +1,24 @@
# https://woodpecker-ci.org/docs/usage/workflow-syntax#when---global-workflow-conditions
when:
- event: push
branch: next
# https://goreleaser.com/ci/woodpecker/
# https://woodpecker-ci.org/docs/usage/workflow-syntax#clone
clone:
git:
image: woodpeckerci/plugin-git
settings:
tags: true
# https://woodpecker-ci.org/plugins/docker-buildx
steps:
publish:
image: woodpeckerci/plugin-docker-buildx:5.2.2
settings:
pull_image: true
username: gotosocial
password:
from_secret: gts_docker_password
repo: superseriousbusiness/masto-fe-standalone
tag: next
+14 -2
View File
@@ -11,19 +11,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added documentation for `yarn dev` (#75)
- Added an .editorconfig (#78)
- Added a changelog basaed on “Keep a Changelog” (#80)
- Added a CHANGELOG.md based on “Keep a Changelog” (#80)
### Changed
- Preserve mastodon-settings in localStorage (#66)
- Redesigned the login page (#76)
- Changed all icons with the Phosphor icon set (#77)
- Changed all icons to the Phosphor icon set (#77)
- Changed AUTHORS.md to reflect fork contributors (#89)
### Fixed
- Updated caniuse-lite browserlist (#82)
- Fixed various linter issues (#85)
- Fixed various CSS issues (#100)
- Updated Prettier to 3.6.2 (#86)
- Updated Yarn to 4.10.3 (#90)
- Updated Webpack to 5.102.1 (#83)
- Updated ESlint to 9.37.0 (#88)
- Fixed an issue where media items wouldnt show correctly (#109)
### Removed
- Removed FontAwesome (#99)
- Removed unused CSS files (#99)
- Removed various unused assets
## [0.5.0] - 2025-07-14
-1
View File
@@ -27,7 +27,6 @@ RUN apk upgrade --update --no-cache
# Copy bigger nested stuff.
COPY --from=builder /build/public/packs/js/flavours/glitch /usr/share/nginx/html/packs/js/flavours/glitch
COPY --from=builder /build/public/packs/js/flavours/vanilla /usr/share/nginx/html/packs/js/flavours/vanilla
# Copy remaining files.
COPY --from=builder /build/public /usr/share/nginx/html/
@@ -32,7 +32,7 @@ export default class ColumnBackButton extends PureComponent {
const component = (
<button onClick={this.handleClick} className='column-back-button'>
<Icon id='arrow-left' className='column-back-button__icon' fixedWidth />
<Icon id='arrow-left' className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</button>
);
@@ -27,7 +27,7 @@ export default class ColumnBackButtonSlim extends PureComponent {
return (
<div className='column-back-button--slim'>
<div role='button' tabIndex={0} onClick={this.handleClick} className='column-back-button column-back-button--slim-button'>
<Icon id='arrow-left' className='column-back-button__icon' fixedWidth />
<Icon id='arrow-left' className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</div>
</div>
@@ -133,7 +133,7 @@ class ColumnHeader extends PureComponent {
if (!pinned && ((multiColumn && router.history.location?.state?.fromMastodon) || showBackButton)) {
backButton = (
<button onClick={this.handleBackClick} className='column-header__back-button'>
<Icon id='arrow-left' className='column-back-button__icon' fixedWidth />
<Icon id='arrow-left' className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</button>
);
@@ -176,7 +176,7 @@ class ColumnHeader extends PureComponent {
<h1 className={buttonClassName}>
{hasTitle && (
<button onClick={this.handleTitleClick}>
<Icon id={icon} fixedWidth className='column-header__icon' />
<Icon id={icon} className='column-header__icon' />
{title}
</button>
)}
@@ -5,17 +5,10 @@ import classNames from "classnames";
interface Props extends React.HTMLAttributes<HTMLImageElement> {
id: string,
className?: string,
fixedWidth?: boolean,
children?: never,
}
export const Icon: React.FC<Props> = ({
id,
className,
fixedWidth,
title,
...other
}) => (
export const Icon: React.FC<Props> = ({ id, className, title, ...other }) => (
<svg className={classNames("gts-icon", className)} {...other}>
{title && <title>{title}</title>}
<use href={`/icons.svg#${id}`} />
@@ -16,11 +16,11 @@ export const IconWithBadge: React.FC<Props> = ({
issueBadge,
className,
}) => (
<div className='gts-icon-with-badge'>
<Icon id={id} fixedWidth className={className} />
<div className="gts-icon-with-badge">
<Icon id={id} className={className} />
{count > 0 && (
<span className='gts-icon-with-badge__badge'>{formatNumber(count)}</span>
<span className="gts-icon-with-badge__badge">{formatNumber(count)}</span>
)}
{issueBadge && <div className='gts-icon-with-badge__issue-badge' />}
{issueBadge && <div className="gts-icon-with-badge__issue-badge" />}
</div>
);
@@ -329,7 +329,6 @@ class StatusContent extends PureComponent {
mediaIcons.forEach((mediaIcon, idx) => {
toggleText.push(
<Icon
fixedWidth
className='status__content__spoiler-icon'
id={mediaIcon}
aria-hidden='true'
@@ -86,7 +86,6 @@ class StatusIcons extends PureComponent {
renderIcon (mediaIcon) {
return (
<Icon
fixedWidth
className='status__media-icon'
key={`media-icon--${mediaIcon}`}
id={mediaIcon}
@@ -113,7 +112,6 @@ class StatusIcons extends PureComponent {
{settings.get("reply") && status.get("in_reply_to_id", null) !== null ? (
<Icon
className='status__reply-icon'
fixedWidth
id='arrow-bend-double-up-left'
aria-hidden='true'
title={intl.formatMessage(messages.inReplyTo)}
@@ -121,7 +119,6 @@ class StatusIcons extends PureComponent {
) : null}
{settings.get("local_only") && status.get("local_only") &&
<Icon
fixedWidth
id='house-line'
aria-hidden='true'
title={intl.formatMessage(messages.localOnly)}
@@ -36,7 +36,6 @@ class VisibilityIcon extends ImmutablePureComponent {
const icon = (<Icon
className='status__visibility-icon'
fixedWidth
id={visibilityIcon}
title={label}
aria-hidden='true'
@@ -72,7 +72,7 @@ class Section extends PureComponent {
return (
<div className={classNames("about__section", { active: !collapsed })}>
<div className='about__section__title' role='button' tabIndex={0} onClick={this.handleClick}>
<Icon id={collapsed ? "caret-right" : "caret-down"} fixedWidth /> {title}
<Icon id={collapsed ? "caret-right" : "caret-down"} /> {title}
</div>
{!collapsed && (
@@ -28,7 +28,7 @@ class ActionBar extends PureComponent {
return (
<div>
<div className='account__disclaimer'>
<Icon id='info' fixedWidth />
<Icon id='info' />
<FormattedMessage
id='account.suspended_disclaimer_full'
defaultMessage='This user has been suspended by a moderator.'
@@ -43,7 +43,7 @@ class ActionBar extends PureComponent {
if (account.get("acct") !== account.get("username")) {
extraInfo = (
<div className='account__disclaimer'>
<Icon id='info' fixedWidth />
<Icon id='info' />
<FormattedMessage
id='account.disclaimer_full'
defaultMessage="Information below may reflect the user's profile incompletely."
@@ -22,12 +22,12 @@ export default class FollowRequestNote extends ImmutablePureComponent {
<div className='follow-request-banner__action'>
<button type='button' className='button button-tertiary button--confirmation' onClick={onAuthorize}>
<Icon id='check' fixedWidth />
<Icon id='check' />
<FormattedMessage id='follow_request.authorize' defaultMessage='Authorize' />
</button>
<button type='button' className='button button-tertiary button--destructive' onClick={onReject}>
<Icon id='x' fixedWidth />
<Icon id='x' />
<FormattedMessage id='follow_request.reject' defaultMessage='Reject' />
</button>
</div>
@@ -37,7 +37,7 @@ export default class MovedNote extends ImmutablePureComponent {
return (
<div className='account__moved-note'>
<div className='account__moved-note__message'>
<div className='account__moved-note__icon-wrapper'><Icon id='signpost' className='account__moved-note__icon' fixedWidth /></div>
<div className='account__moved-note__icon-wrapper'><Icon id='signpost' className='account__moved-note__icon' /></div>
<FormattedMessage id='account.moved_to' defaultMessage='{name} has indicated that their new account is now:' values={{ name: <bdi><strong dangerouslySetInnerHTML={displayNameHtml} /></bdi> }} />
</div>
@@ -564,8 +564,8 @@ class Audio extends PureComponent {
<div className='video-player__controls active'>
<div className='video-player__buttons-bar'>
<div className='video-player__buttons left'>
<button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay}><Icon id={paused ? "play" : "pause"} fixedWidth /></button>
<button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? "speaker-slash" : "speaker-high"} fixedWidth /></button>
<button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay}><Icon id={paused ? "play" : "pause"} /></button>
<button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? "speaker-slash" : "speaker-high"} /></button>
<div className={classNames("video-player__volume", { active: this.state.hovered })} ref={this.setVolumeRef} onMouseDown={this.handleVolumeMouseDown}>
<div className='video-player__volume__current' style={{ width: `${muted ? 0 : volume * 100}%`, backgroundColor: this._getAccentColor() }} />
@@ -585,9 +585,9 @@ class Audio extends PureComponent {
</div>
<div className='video-player__buttons right'>
{!editable && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} className='player-button' onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
{!editable && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} className='player-button' onClick={this.toggleReveal}><Icon id='eye-slash' /></button>}
<a title={intl.formatMessage(messages.download)} aria-label={intl.formatMessage(messages.download)} className='video-player__download__icon player-button' href={this.props.src} download>
<Icon id={"file-arrow-down"} fixedWidth />
<Icon id={"file-arrow-down"} />
</a>
</div>
</div>
@@ -155,7 +155,7 @@ export default class ComposerOptionsDropdownContent extends PureComponent {
if (!contents) {
contents = (
<>
{icon && <Icon className='icon' fixedWidth id={icon} />}
{icon && <Icon className='icon' id={icon} />}
<div className='privacy-dropdown__option__content'>
<strong>{text}</strong>
@@ -393,7 +393,6 @@ class EmojiPickerDropdown extends PureComponent {
<div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown}>
<button ref={this.setTargetRef} className='emoji-button' title={title} aria-label={title} aria-expanded={active} onClick={this.onToggle} onKeyDown={this.onToggle}>
{button || <Icon
fixedWidth
id='smiley'
aria-hidden='true'
className={classNames("emojione", { "pulse-loading": active && loading })}
@@ -80,7 +80,7 @@ class Header extends ImmutablePureComponent {
title={intl.formatMessage(messages.start)}
to='/getting-started'
className='drawer__tab'
><Icon id='asterisk' /></Link>
><Icon id='gts-simple' /></Link>
{renderForColumn("HOME", (
<Link
aria-label={intl.formatMessage(messages.home_timeline)}
@@ -62,9 +62,10 @@ class Publisher extends ImmutablePureComponent {
} else if (privacy === "private" || privacy === "direct") {
const iconId = privacyIcons[privacy];
publishText = (
<span>
<Icon id={iconId} /> {intl.formatMessage(messages.publish)}
</span>
<>
<Icon id={iconId} />
<span>{intl.formatMessage(messages.publish)}</span>
</>
);
} else {
publishText = privacy !== "unlisted" ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
@@ -80,26 +81,22 @@ class Publisher extends ImmutablePureComponent {
return (
<div className={computedClass}>
{sideArm && !isEditing && sideArm !== "none" ? (
<div className='compose-form__publish-button-wrapper'>
<Button
className='side_arm'
disabled={disabled}
onClick={onSecondarySubmit}
style={{ padding: null }}
text={<Icon id={privacyIcons[sideArm]} />}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage(privacyNames[sideArm])}`}
/>
</div>
) : null}
<div className='compose-form__publish-button-wrapper'>
<Button
className='primary'
text={publishText}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage(privacyNames[privacy])}`}
onClick={this.handleSubmit}
className='side_arm'
disabled={disabled}
onClick={onSecondarySubmit}
style={{ padding: null }}
text={<Icon id={privacyIcons[sideArm]} />}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage(privacyNames[sideArm])}`}
/>
</div>
) : null}
<Button
className='primary'
text={publishText}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage(privacyNames[privacy])}`}
onClick={this.handleSubmit}
disabled={disabled}
/>
</div>
);
}
@@ -43,7 +43,7 @@ class SearchResults extends ImmutablePureComponent {
if (results.get("accounts") && results.get("accounts").size > 0) {
accounts = (
<SearchSection title={<><Icon id='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
<SearchSection title={<><Icon id='users' /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
{withoutLastResult(results.get("accounts")).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
{(results.get("accounts").size > INITIAL_PAGE_LIMIT && results.get("accounts").size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreAccounts} />}
</SearchSection>
@@ -52,7 +52,7 @@ class SearchResults extends ImmutablePureComponent {
if (results.get("hashtags") && results.get("hashtags").size > 0) {
hashtags = (
<SearchSection title={<><Icon id='tag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
<SearchSection title={<><Icon id='tag' /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
{withoutLastResult(results.get("hashtags")).map(hashtag => <Hashtag key={hashtag.get("name")} hashtag={hashtag} />)}
{(results.get("hashtags").size > INITIAL_PAGE_LIMIT && results.get("hashtags").size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreHashtags} />}
</SearchSection>
@@ -61,7 +61,7 @@ class SearchResults extends ImmutablePureComponent {
if (results.get("statuses") && results.get("statuses").size > 0) {
statuses = (
<SearchSection title={<><Icon id='chat-circle-dots' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
<SearchSection title={<><Icon id='chat-circle-dots' /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
{withoutLastResult(results.get("statuses")).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
{(results.get("statuses").size > INITIAL_PAGE_LIMIT && results.get("statuses").size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
</SearchSection>
@@ -71,7 +71,7 @@ class SearchResults extends ImmutablePureComponent {
return (
<div className='drawer--results'>
<header className='search-results__header'>
<Icon id='magnifying-glass' fixedWidth />
<Icon id='magnifying-glass' />
<FormattedMessage id='explore.search_results' defaultMessage='Search results' />
</header>
@@ -46,7 +46,6 @@ class TextareaIcons extends ImmutablePureComponent {
title={intl.formatMessage(message)}
>
<Icon
fixedWidth
id={icon}
/>
</span>
@@ -165,19 +165,19 @@ class Results extends PureComponent {
filteredResults = (accounts.size + hashtags.size + statuses.size) > 0 ? (
<>
{accounts.size > 0 && (
<SearchSection key='accounts' title={<><Icon id='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>} onClickMore={this.handleLoadMoreAccounts}>
<SearchSection key='accounts' title={<><Icon id='users' /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>} onClickMore={this.handleLoadMoreAccounts}>
{accounts.take(INITIAL_DISPLAY).map(id => <Account key={id} id={id} />)}
</SearchSection>
)}
{hashtags.size > 0 && (
<SearchSection key='hashtags' title={<><Icon id='tag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>} onClickMore={this.handleLoadMoreHashtags}>
<SearchSection key='hashtags' title={<><Icon id='tag' /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>} onClickMore={this.handleLoadMoreHashtags}>
{hashtags.take(INITIAL_DISPLAY).map(hashtag => <Hashtag key={hashtag.get("name")} hashtag={hashtag} />)}
</SearchSection>
)}
{statuses.size > 0 && (
<SearchSection key='statuses' title={<><Icon id='chat-circle-dots' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>} onClickMore={this.handleLoadMoreStatuses}>
<SearchSection key='statuses' title={<><Icon id='chat-circle-dots' /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>} onClickMore={this.handleLoadMoreStatuses}>
{statuses.take(INITIAL_DISPLAY).map(id => <Status key={id} id={id} />)}
</SearchSection>
)}
@@ -78,7 +78,7 @@ class SelectFilter extends PureComponent {
renderCreateNew (name) {
return (
<div key='add-new-filter' role='button' tabIndex={0} className='language-dropdown__dropdown__results__item' onClick={this.handleNewFilterClick} onKeyDown={this.handleKeyDown}>
<Icon id='plus' fixedWidth /> <FormattedMessage id='filter_modal.select_filter.prompt_new' defaultMessage='New category: {name}' values={{ name }} />
<Icon id='plus' /> <FormattedMessage id='filter_modal.select_filter.prompt_new' defaultMessage='New category: {name}' values={{ name }} />
</div>
);
}
@@ -55,7 +55,7 @@ class List extends ImmutablePureComponent {
<div className='list'>
<div className='list__wrapper'>
<div className='list__display-name'>
<Icon id='dot' className='column-link__icon' fixedWidth />
<Icon id='dot' className='column-link__icon' />
{list.get("title")}
</div>
@@ -45,7 +45,7 @@ export default class LocalSettingsPage extends PureComponent {
active,
}, className);
const iconElem = icon ? <Icon fixedWidth id={icon} /> : (textIcon ? <span className='text-icon-button'>{textIcon}</span> : null);
const iconElem = icon ? <Icon id={icon} /> : (textIcon ? <span className='text-icon-button'>{textIcon}</span> : null);
if (href) {
return (
@@ -95,7 +95,7 @@ export default class AdminReport extends ImmutablePureComponent {
<div className={classNames("notification notification-admin-report focusable", { unread })} tabIndex={0}>
<div className='notification__message'>
<div className='notification__favourite-icon-wrapper'>
<Icon id='flag' fixedWidth />
<Icon id='flag' />
</div>
<span title={notification.get("created_at")}>
@@ -86,7 +86,7 @@ export default class NotificationFollow extends ImmutablePureComponent {
<div className={classNames("notification notification-admin-sign-up focusable", { unread })} tabIndex={0}>
<div className='notification__message'>
<div className='notification__favourite-icon-wrapper'>
<Icon fixedWidth id='user-plus' />
<Icon id='user-plus' />
</div>
<FormattedMessage
@@ -66,42 +66,42 @@ class FilterBar extends PureComponent {
onClick={this.onClick("mention")}
title={intl.formatMessage(tooltips.mentions)}
>
<Icon id={selectedFilter === "mention" ? "arrow-bend-double-up-left-filled" : "arrow-bend-double-up-left"} fixedWidth />
<Icon id={selectedFilter === "mention" ? "arrow-bend-double-up-left-filled" : "arrow-bend-double-up-left"} />
</button>
<button
className={selectedFilter === "favourite" ? "active" : ""}
onClick={this.onClick("favourite")}
title={intl.formatMessage(tooltips.favourites)}
>
<Icon id={selectedFilter === "favourite" ? "star-filled" : "star"} fixedWidth />
<Icon id={selectedFilter === "favourite" ? "star-filled" : "star"} />
</button>
<button
className={selectedFilter === "reblog" ? "active" : ""}
onClick={this.onClick("reblog")}
title={intl.formatMessage(tooltips.boosts)}
>
<Icon id={selectedFilter === "reblog" ? "rocket-launch-filled" : "rocket-launch"} fixedWidth />
<Icon id={selectedFilter === "reblog" ? "rocket-launch-filled" : "rocket-launch"} />
</button>
<button
className={selectedFilter === "poll" ? "active" : ""}
onClick={this.onClick("poll")}
title={intl.formatMessage(tooltips.polls)}
>
<Icon id={selectedFilter === "poll" ? "chart-bar-horizontal-filled" : "chart-bar-horizontal"} fixedWidth />
<Icon id={selectedFilter === "poll" ? "chart-bar-horizontal-filled" : "chart-bar-horizontal"} />
</button>
<button
className={selectedFilter === "status" ? "active" : ""}
onClick={this.onClick("status")}
title={intl.formatMessage(tooltips.statuses)}
>
<Icon id={selectedFilter === "status" ? "chat-circle-dots-filled" : "chat-circle-dots"} fixedWidth />
<Icon id={selectedFilter === "status" ? "chat-circle-dots-filled" : "chat-circle-dots"} />
</button>
<button
className={selectedFilter === "follow" ? "active" : ""}
onClick={this.onClick("follow")}
title={intl.formatMessage(tooltips.follows)}
>
<Icon id={selectedFilter === "follow" ? "user-plus-filled" : "user-plus"} fixedWidth />
<Icon id={selectedFilter === "follow" ? "user-plus-filled" : "user-plus"} />
</button>
</div>
);
@@ -86,7 +86,7 @@ export default class NotificationFollow extends ImmutablePureComponent {
<div className={classNames("notification notification-follow focusable", { unread })} tabIndex={0}>
<div className='notification__message'>
<div className='notification__favourite-icon-wrapper'>
<Icon fixedWidth id='user-plus' />
<Icon id='user-plus' />
</div>
<FormattedMessage
@@ -103,7 +103,7 @@ class FollowRequest extends ImmutablePureComponent {
<div className={classNames("notification notification-follow-request focusable", { unread })} tabIndex={0}>
<div className='notification__message'>
<div className='notification__favourite-icon-wrapper'>
<Icon id='user' fixedWidth />
<Icon id='user' />
</div>
<FormattedMessage
@@ -24,7 +24,7 @@ export default class ColumnHeader extends PureComponent {
let iconElement = "";
if (icon) {
iconElement = <Icon id={icon} fixedWidth className='column-header__icon' />;
iconElement = <Icon id={icon} className='column-header__icon' />;
}
return (
@@ -8,7 +8,7 @@ import { Icon } from "flavours/glitch/components/icon";
const ColumnLink = ({ icon, text, to, onClick, href, method, badge, transparent, ...other }) => {
const className = classNames("column-link", { "column-link--transparent": transparent });
const badgeElement = typeof badge !== "undefined" ? <span className='column-link__badge'>{badge}</span> : null;
const iconElement = typeof icon === "string" ? <Icon id={icon} fixedWidth className='column-link__icon' /> : icon;
const iconElement = typeof icon === "string" ? <Icon id={icon} className='column-link__icon' /> : icon;
if (href) {
return (
@@ -19,7 +19,7 @@ const Account = connect(state => ({
account: state.getIn(["accounts", me]),
}))(({ account }) => (
<Permalink href={account.get("url")} to={`/@${account.get("acct")}`} title={account.get("acct")}>
<Avatar account={account} size={35} />
<Avatar account={account} size={34} />
</Permalink>
));
@@ -108,8 +108,7 @@ class Header extends PureComponent {
return (
<div className='ui__header'>
<Link to='/' className='ui__header__logo'>
<WordmarkLogo />
<SymbolLogo />
<Icon id='gts-simple' />
</Link>
<div className='ui__header__links'>
@@ -141,8 +141,8 @@ class MediaModal extends ImmutablePureComponent {
const index = this.getIndex();
const leftNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><Icon id='caret-left' fixedWidth /></button>;
const rightNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='caret-right' fixedWidth /></button>;
const leftNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><Icon id='caret-left' /></button>;
const rightNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='caret-right' /></button>;
const content = media.map((image) => {
const width = image.getIn(["meta", "original", "width"]) || null;
@@ -640,11 +640,11 @@ class Video extends PureComponent {
<div className='video-player__buttons-bar'>
<div className='video-player__buttons left'>
<button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={autoFocus}>
<Icon id={paused ? "play" : "pause"} fixedWidth />
<Icon id={paused ? "play" : "pause"} />
</button>
<button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}>
<Icon id={muted ? "speaker-slash" : "speaker-high"} fixedWidth />
<Icon id={muted ? "speaker-slash" : "speaker-high"} />
</button>
<div className={classNames("video-player__volume", { active: this.state.hovered })} onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
@@ -667,10 +667,10 @@ class Video extends PureComponent {
</div>
<div className='video-player__buttons right'>
{(!onCloseVideo && !editable && !fullscreen && !this.props.alwaysVisible) && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} className='player-button' onClick={this.toggleReveal}><Icon id='eye-slash-filled' fixedWidth /></button>}
{(!fullscreen && onOpenVideo) && <button type='button' title={intl.formatMessage(messages.expand)} aria-label={intl.formatMessage(messages.expand)} className='player-button' onClick={this.handleOpenVideo}><Icon id='arrows-out-simple' fixedWidth /></button>}
{onCloseVideo && <button type='button' title={intl.formatMessage(messages.close)} aria-label={intl.formatMessage(messages.close)} className='player-button' onClick={this.handleCloseVideo}><Icon id='arrows-in-simple' fixedWidth /></button>}
<button type='button' title={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} className='player-button' onClick={this.toggleFullscreen}><Icon id={fullscreen ? "arrows-in-simple" : "frame-corners"} fixedWidth /></button>
{(!onCloseVideo && !editable && !fullscreen && !this.props.alwaysVisible) && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} className='player-button' onClick={this.toggleReveal}><Icon id='eye-slash-filled' /></button>}
{(!fullscreen && onOpenVideo) && <button type='button' title={intl.formatMessage(messages.expand)} aria-label={intl.formatMessage(messages.expand)} className='player-button' onClick={this.handleOpenVideo}><Icon id='arrows-out-simple' /></button>}
{onCloseVideo && <button type='button' title={intl.formatMessage(messages.close)} aria-label={intl.formatMessage(messages.close)} className='player-button' onClick={this.handleCloseVideo}><Icon id='arrows-in-simple' /></button>}
<button type='button' title={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} className='player-button' onClick={this.toggleFullscreen}><Icon id={fullscreen ? "arrows-in-simple" : "frame-corners"} /></button>
</div>
</div>
</div>
@@ -29,7 +29,7 @@ const initialState = ImmutableMap({
shared_state : true,
}),
collapsed : ImmutableMap({
enabled : true,
enabled : false,
auto : ImmutableMap({
all : false,
notifications : false,
@@ -43,9 +43,9 @@
@mixin fullwidth-gallery {
&.full-width {
margin-left: -10px;
margin-right: -10px;
width: calc(100% + 20px);
margin-left: -15px;
margin-right: -15px;
width: calc(100% + 30px);
max-width: none;
border-radius: 0;
}
@@ -16,23 +16,21 @@ $emojis-requiring-inversion: "back" "copyright" "curly_loop" "currency_exchange"
}
.hicolor-privacy-icons {
.status__visibility-icon.fa-globe,
.privacy-dropdown__option .fa-globe {
:is(.status__visibility-icon, .privacy-dropdown__option) use[href*="planet"] {
color: #1976d2;
}
.status__visibility-icon.fa-unlock,
.privacy-dropdown__option .fa-unlock {
:is(.status__visibility-icon, .privacy-dropdown__option)
use[href*="lock-open-simple"] {
color: #388e3c;
}
.status__visibility-icon.fa-lock,
.privacy-dropdown__option .fa-lock {
:is(.status__visibility-icon, .privacy-dropdown__option)
use[href*="lock-simple"] {
color: #ffa000;
}
.status__visibility-icon.fa-envelope,
.privacy-dropdown__option .fa-envelope {
:is(.status__visibility-icon, .privacy-dropdown__option) use[href*="#at"] {
color: #d32f2f;
}
}
@@ -157,7 +157,7 @@
}
.gts-icon {
--size: 20px;
--size-icon: 20px;
display: block;
}
@@ -195,7 +195,7 @@
}
.gts-icon {
--size: 16px;
--size-icon: 16px;
margin-inline-end: 5px;
vertical-align: text-bottom;
@@ -370,7 +370,7 @@
}
svg.gts-icon {
--size: 20px;
--size-icon: 20px;
}
}
@@ -472,7 +472,7 @@
}
svg.gts-icon {
--size: 20px;
--size-icon: 20px;
display: block;
}
@@ -635,7 +635,7 @@
}
.gts-icon {
--size: 24px;
--size-icon: 24px;
display: block;
}
@@ -867,18 +867,13 @@
}
.follow-request-banner .button {
--size-icon: 20px;
display: flex;
align-items: center;
gap: 5px;
justify-content: center;
width: 100%;
svg.gts-icon {
--size: 20px;
width: var(--size);
height: var(--size);
}
}
.account-memorial-banner__message {
@@ -56,57 +56,6 @@
$ui-header-height: 55px;
.ui__header {
display: none;
box-sizing: border-box;
height: $ui-header-height;
position: sticky;
top: 0;
z-index: 3;
justify-content: space-between;
align-items: center;
&__logo {
display: inline-flex;
padding: 15px;
.logo {
height: $ui-header-height - 30px;
width: auto;
}
.logo--wordmark {
display: none;
}
@media screen and (width >= 320px) {
.logo--wordmark {
display: block;
}
.logo--icon {
display: none;
}
}
}
&__links {
display: flex;
align-items: center;
gap: 10px;
padding: 0 10px;
overflow: hidden;
.button {
flex: 0 0 auto;
}
.button-tertiary {
flex-shrink: 1;
}
}
}
.tabs-bar__wrapper {
background: darken($ui-base-color, 8%);
position: sticky;
@@ -335,6 +284,8 @@ $ui-header-height: 55px;
.column-header__back-button,
.column-header__footer-button,
.column-header__setting-btn {
--size-icon: 24px;
display: flex;
border: 0;
color: inherit;
@@ -343,8 +294,6 @@ $ui-header-height: 55px;
transition: all 0.3s;
.gts-icon {
--size: 24px;
display: block;
}
}
@@ -355,6 +304,7 @@ $ui-header-height: 55px;
align-items: center;
flex-grow: 1;
padding: 12px 0 13px 15px;
text-align: start;
}
.column-header__buttons {
@@ -404,16 +354,14 @@ $ui-header-height: 55px;
.column-header__footer-button,
.column-header__setting-btn {
--size-icon: 20px;
gap: 5px;
align-items: center;
padding: 6px;
border-radius: var(--button-border-radius);
color: inherit;
.gts-icon {
--size: 20px;
}
&:focus-visible,
&:hover,
&.active {
@@ -735,6 +683,8 @@ $ui-header-height: 55px;
}
.column-inline-form {
--size-icon: 20px;
padding: 7px 15px;
padding-inline-end: 5px;
display: flex;
@@ -760,10 +710,6 @@ $ui-header-height: 55px;
margin: 0 5px;
padding: 6px;
}
.gts-icon {
--size: 20px;
}
}
.column-settings__outer {
@@ -1054,6 +1000,8 @@ $ui-header-height: 55px;
}
&__action {
--size-icon: 20px;
float: right;
.icon-button {
@@ -1066,8 +1014,6 @@ $ui-header-height: 55px;
}
.gts-icon {
--size: 20px;
display: block;
}
}
@@ -514,7 +514,7 @@
}
svg.gts-icon {
--size: 20px;
--size-icon: 20px;
scale: 1.2;
}
@@ -565,16 +565,14 @@
}
.privacy-dropdown__option {
--size-icon: 24px;
display: flex;
align-items: center;
padding: 10px;
color: $inverted-text-color;
cursor: pointer;
svg.gts-icon {
--size: 24px;
}
.privacy-dropdown__option__content {
flex: 1 1 auto;
color: $lighter-text-color;
@@ -611,23 +609,22 @@
.compose-form__publish {
display: flex;
justify-content: flex-end;
min-width: 0;
flex: 0 0 auto;
column-gap: 5px;
flex: 0 0 auto;
justify-content: flex-end;
margin-top: 10px;
min-width: 0;
.compose-form__publish-button-wrapper {
overflow: hidden;
padding-top: 10px;
button {
--size-icon: 18px;
button {
padding: 7px 10px;
text-align: center;
}
& > .side_arm {
width: 36px;
}
display: flex;
align-items: center;
flex-shrink: 0;
gap: 5px;
padding: 8px 12px;
line-height: 20px;
text-align: center;
}
}
@@ -73,6 +73,8 @@
}
.layout-multiple-columns .drawer__tab {
--size-icon: 24px;
display: flex;
gap: 5px;
align-items: center;
@@ -88,8 +90,6 @@
transition: all 0.3s;
.gts-icon {
--size: 24px;
display: block;
}
@@ -149,12 +149,10 @@
}
.navigation-bar .compose__action-bar button {
--size-icon: 20px;
display: flex;
padding: 6px;
svg.gts-icon {
--size: 20px;
}
}
.drawer--results {
@@ -77,8 +77,8 @@
color: $inverted-text-color;
background: transparent;
svg {
--size: 24px;
svg.gts-icon {
--size-icon: 24px;
margin: 0;
}
@@ -64,29 +64,7 @@
line-height: 18px;
}
.media-gallery {
box-sizing: border-box;
overflow: hidden;
border-radius: 4px;
position: relative;
width: 100%;
min-height: 64px;
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: 50% 50%;
gap: 2px;
@include fullwidth-gallery;
}
.media-gallery__item {
border: 0;
box-sizing: border-box;
display: block;
position: relative;
border-radius: 4px;
overflow: hidden;
&--tall {
grid-row: span 2;
}
@@ -189,7 +167,7 @@
color: rgba($white, 0.7);
.gts-icon {
--size: 24px;
--size-icon: 24px;
display: block;
}
@@ -283,11 +261,9 @@
padding: 20px 0;
.icon-button {
color: $white;
--size-icon: 24px;
.gts-icon {
--size: 24px;
}
color: $white;
&:hover,
&:focus,
@@ -571,14 +547,14 @@
}
&__buttons-bar {
--size-icon: 20px;
display: flex;
justify-content: space-between;
padding-bottom: 8px;
margin: 0 -5px;
.gts-icon {
--size: 20px;
display: block;
}
@@ -1315,6 +1315,8 @@ button.icon-button.active i.fa-retweet {
}
.spoiler-button {
--size-icon: 18px;
top: 0;
inset-inline-start: 0;
width: 100%;
@@ -1323,8 +1325,6 @@ button.icon-button.active i.fa-retweet {
z-index: 100;
svg.gts-icon {
--size: 18px;
display: block;
}
@@ -1060,15 +1060,13 @@
padding: 15px;
.report-modal__close {
--size-icon: 20px;
position: absolute;
top: 10px;
inset-inline-end: 10px;
display: flex;
padding: 6px;
svg.gts-icon {
--size: 20px;
}
}
}
@@ -4,7 +4,7 @@
.search__icon,
.search__icon.gts-icon {
--size: 20px;
--size-icon: 20px;
position: absolute;
top: 13px;
@@ -35,6 +35,8 @@
}
.search__button {
--size-icon: 20px;
position: absolute;
top: 7px;
right: 7px;
@@ -48,8 +50,6 @@
transition: all 0.3s;
.gts-icon {
--size: 20px;
display: block;
}
@@ -154,13 +154,11 @@
.search-results__header,
.search-results__section__header h3 {
--size-icon: 20px;
display: flex;
gap: 5px;
align-items: center;
.gts-icon {
--size: 20px;
}
}
.search-results__header {
@@ -277,8 +277,8 @@
.layout-single-column .ui__header {
display: flex;
background: $ui-base-color;
border-bottom: 1px solid lighten($ui-base-color, 8%);
background: $ui-base-color;
}
.layout-single-column {
@@ -89,16 +89,6 @@
}
}
&.mention {
&:hover {
text-decoration: none;
span {
text-decoration: underline;
}
}
}
.fa {
color: $dark-text-color;
}
@@ -409,19 +399,11 @@
}
.status__action-bar {
--size-icon: 20px;
display: flex;
gap: 10px;
align-items: center;
svg.gts-icon {
--size: 20px;
}
&.detailed-status__action-bar {
svg.gts-icon {
--size: 24px;
}
}
}
.status__action-bar-button,
@@ -446,9 +428,9 @@
}
.detailed-status {
background: lighten($ui-base-color, 4%);
padding: 14px 10px;
padding: 15px;
border-top: 1px solid lighten($ui-base-color, 8%);
background: lighten($ui-base-color, 4%);
&--flex {
display: flex;
@@ -579,9 +561,8 @@ a.status__display-name,
.status__avatar {
flex: none;
margin-inline-end: 10px;
height: 48px;
width: 48px;
height: var(--size-avatar);
width: var(--size-avatar);
}
.muted {
+25 -20
View File
@@ -2,8 +2,8 @@
/* Variables */
:root {
--drawer-border-radius: 8px;
--button-border-radius: 6px;
--drawer-border-radius: var(--size-layout-radius);
--button-border-radius: var(--size-ui-radius);
}
/* Icons debug */
@@ -13,11 +13,10 @@
/* Diff */
.gts-icon {
--size: 1em;
display: inline-block;
width: var(--size);
height: var(--size);
flex-shrink: 0;
width: var(--size-icon);
height: var(--size-icon);
}
.gts-icon-with-badge {
@@ -59,7 +58,7 @@
.column-header .gts-icon,
.column-link .gts-icon,
.local-settings__navigation__item .gts-icon {
--size: 24px;
--size-icon: 24px;
}
.navigation-panel {
@@ -94,12 +93,9 @@
}
}
.notification__filter-bar svg,
.status__info__icons svg {
--size: 18px;
width: var(--size);
height: var(--size);
.notification__filter-bar svg.gts-icon,
.status__info__icons svg.gts-icon {
--size-icon: 18px;
}
.detailed-status__meta {
@@ -121,16 +117,25 @@
}
.detailed-status__meta svg {
--size: 16px;
width: var(--size);
height: var(--size);
--size-icon: 16px;
}
.notification__favourite-icon-wrapper svg {
--size: 16px;
--size-icon: 16px;
width: var(--size);
height: var(--size);
color: $highlight-text-color;
}
.drawer__pager {
flex-grow: unset;
}
.drawer__inner {
position: relative;
top: unset;
}
.drawer__inner__mastodon,
.drawer__inner.darker {
display: none;
}
@@ -10,4 +10,6 @@
@import "sizes";
/* 🧩 Components */
@import "media-gallery";
@import "status";
@import "ui-header";
@@ -6,6 +6,7 @@
--color-fg: #fff;
--color-bg: #191b22;
--color-lines: #3d4455;
--color-logo: #c76c33;
/* Accent */
--color-accent: #8c8dff;
@@ -1 +1,73 @@
/* 🖼️ Media Gallery */
.media-gallery {
position: relative;
display: grid;
grid-template-columns: auto auto;
gap: var(--size-ui-gap);
overflow: hidden;
}
.media-gallery:not(.full-width) {
border-radius: var(--size-ui-radius);
}
.media-gallery.full-width {
margin-inline: -15px;
/* the `div` is there for specificity */
div.media-gallery__item {
border-radius: 0;
}
}
.media-gallery:not(.full-width) .spoiler-button__overlay {
border-radius: var(--size-ui-radius);
}
.media-gallery__item {
overflow: hidden;
}
/* Only one image */
.media-gallery__item:nth-child(2):nth-last-child(1) {
border-radius: var(--size-ui-radius);
}
/* First image in a set of two */
.media-gallery__item:nth-child(2):nth-last-child(2) {
border-top-left-radius: var(--size-ui-radius);
border-bottom-left-radius: var(--size-ui-radius);
}
/* Second image in a set of two */
.media-gallery__item:nth-child(3):nth-last-child(1) {
border-top-right-radius: var(--size-ui-radius);
border-bottom-right-radius: var(--size-ui-radius);
}
/* First image in a set of at least two */
.media-gallery__item:nth-child(2):not(:nth-last-child(1)) {
border-top-left-radius: var(--size-ui-radius);
}
/* Second image in a set of at least two */
.media-gallery__item:nth-child(3):not(:nth-last-child(1)) {
border-top-right-radius: var(--size-ui-radius);
}
/* Second to last image in an even set */
.media-gallery__item:nth-last-child(2):nth-child(even) {
border-bottom-left-radius: var(--size-ui-radius);
}
/* Last image in an even set */
.media-gallery__item:last-child:nth-child(odd) {
border-bottom-right-radius: var(--size-ui-radius);
}
/* Last image in an uneven set */
.media-gallery__item:last-child:nth-child(even) {
grid-column: 1/-1;
border-bottom-right-radius: var(--size-ui-radius);
border-bottom-left-radius: var(--size-ui-radius);
}
@@ -1,4 +1,15 @@
/* 📏 Sizes */
:root {
/* Layout: larger elements, mostly containers */
--size-layout-gap: 10px;
--size-layout-radius: 8px;
/* UI: smaller elements such as form elements and icons */
--size-ui-gap: 5px;
--size-ui-radius: 6px;
/* Components */
--size-avatar: 46px;
--size-icon: 20px;
--size-header-block: #{$ui-header-height};
}
@@ -30,3 +30,21 @@
.status__action-bar :is(a, button) {
color: var(--color-secondary-fg);
}
.status .mention {
&,
&:hover {
text-decoration: none;
}
}
.status .mention:is(:focus, :hover) span {
text-decoration-color: currentcolor;
}
.status .mention span {
text-decoration-line: underline;
text-decoration-color: var(--color-accent-lines);
text-decoration-thickness: 2px;
text-underline-offset: 2px;
}
@@ -2,7 +2,7 @@
.status__info__account {
display: grid;
grid-template-columns: auto 1fr;
gap: 10px;
gap: var(--size-layout-gap);
overflow: hidden;
text-overflow: clip;
}
@@ -1,6 +1,6 @@
/* 🚥 Status: Display name */
.status__display-name {
align-self: start;
align-self: center;
justify-self: start;
color: var(--color-content-fg);
font-size: 15px;
@@ -12,6 +12,12 @@
text-overflow: clip;
}
.display-name__html,
.display-name__account {
display: block;
line-height: max(21px, 1.4em);
}
.display-name__html {
font-weight: 700;
}
@@ -1,14 +1,14 @@
/* 🚥 Status: Icons */
.status__info__icons {
--size-icon: 18px;
position: relative;
display: flex;
gap: 5px;
gap: var(--size-ui-gap);
align-items: start;
color: var(--color-secondary-fg);
svg.gts-icon {
--size: 18px;
display: block;
}
@@ -1,7 +1,7 @@
/* 🚥 Status: Info */
.status__info {
display: grid;
gap: 5px;
gap: var(--size-ui-gap);
grid-template-columns: 1fr auto;
.notification__message {
@@ -3,7 +3,7 @@
display: inline-flex;
align-items: center;
align-self: start;
gap: 5px;
gap: var(--size-ui-gap);
padding: 5px 10px;
border: 1px solid var(--color-accent-lines);
border-radius: 50px;
@@ -19,11 +19,9 @@
}
.status__prepend-icon {
--size: 18px;
--size-icon: 18px;
display: block;
width: var(--size);
height: var(--size);
}
.status__prepend-display-name {
@@ -1,7 +1,15 @@
/* 🚥 Status: Spoiler link */
.status__content__spoiler,
.status__content__spoiler-link {
margin-block-start: var(--size-ui-gap);
}
.status__content__spoiler-link {
--size-icon: 14px;
display: flex;
gap: 5px;
gap: var(--size-ui-gap);
padding: 5px 8px;
border: 1px solid var(--color-accent-lines);
border-radius: 8px;
@@ -11,10 +19,6 @@
background: var(--color-accent-bg);
transition: all 0.3s;
.gts-icon {
--size: 14px;
}
&:hover {
border-color: var(--color-lines);
color: var(--color-fg);
@@ -0,0 +1,43 @@
/* 🧑‍💻 UI: Header */
.ui__header {
position: sticky;
top: 0;
z-index: 3;
display: none;
align-items: center;
justify-content: space-between;
padding-inline-start: 7px;
height: var(--size-header-block);
box-sizing: border-box;
svg.gts-icon {
display: block;
}
}
.ui__header__logo {
--size-icon: 32px;
padding: 8px;
}
.ui__header__links {
display: flex;
align-items: center;
gap: 10px;
padding-inline: 10px;
overflow: hidden;
a {
display: flex;
align-items: center;
line-height: 20px;
}
.button {
flex: 0 0 auto;
}
.button-tertiary {
flex-shrink: 1;
}
}
@@ -6,6 +6,7 @@
--color-fg: #000;
--color-bg: #eff3f5;
--color-lines: #c0cdd9;
--color-logo: #df8958;
/* Accent */
--color-accent: #4d4eff;
@@ -189,7 +189,8 @@
&__footer {
display: flex;
gap: 5px;
align-items: center;
gap: min(0.22em, 4px);
padding-top: 6px;
padding-bottom: 5px;
color: $dark-text-color;
@@ -217,8 +218,8 @@
.button {
height: 36px;
margin-inline-end: min(0.22em, 4px);
padding: 0 16px;
margin-inline-end: 10px;
font-size: 14px;
}
}
@@ -240,10 +241,10 @@
}
.poll__footer {
border-top: 1px solid darken($simple-background-color, 8%);
padding: 10px;
display: flex;
align-items: center;
border-top: 1px solid darken($simple-background-color, 8%);
padding: 10px;
button,
select {
-1
View File
@@ -1,5 +1,4 @@
import Rails from "@rails/ujs";
import "font-awesome/css/font-awesome.css";
export function start() {
require.context("../images/", true);
+15 -1
View File
@@ -14,6 +14,20 @@
<path fill="#333a42" d="M418 531c0 24-23 29-32 8q-8-20-31-19c-12 0-24 11-27 19-6 19-32 16-33-4 0-28 27-55 61-57s62 29 62 53m122 63q3-3 4-8t-2-9l-5-4-7-1q-10-3-21-2l-28 3-5 4q-3 5-2 9 1 5 4 8 5 8 14 9 8 2 17 2 9 1 17-2 9-2 14-9m-3 70q19 3 34-7l6-6q2-3 1-8-1-3-5-5-3-2-8-1l-5 2q-10 4-21 4-12-1-21-7-5-3-9-9l-9 9q-10 6-21 7-11 0-22-4l-5-2q-3-1-7 1t-5 5q-1 5 1 8l6 6q15 10 34 7 16-1 28-10 13 9 28 10m63-133c0 24 23 29 32 8q8-20 31-19c12 0 24 11 26 19 6 20 33 16 33-3 1-29-26-56-60-58s-62 29-62 53"/>
</symbol>
<symbol id="gts-simple" viewBox="0 0 65 65">
<path fill="var(--color-logo)" d="M62.2 37.2c3.6 3 3 7.5.8 9.6 1 9.6-5.4 9.2-6.4 5.5-3.1 4.1-5.4 2.6-5.7 2.4a32 32 0 0 1-18 5.3q-10-.2-17.6-5.3c-2.4 1.6-4.9.6-6.3-1.6-5 5.3-7.4-.7-6-4.5-3.6-1.8-3.4-6 1-11.4q-.3-1.6-.3-3.4c0-10 7-21.2 15.7-23.2-5.7-3.7.3-8.2 6.3-3.7 2.1-5 7.3-5 7.4-.7 8 0 12.4 2.9 16.3 5 2.2 1 4.8 2.3 7.9 2.4 3.6.2 5.6 4.1 1.6 7.2 2.3 4 3.3 7.9 3.3 16.4"/>
<path fill="#e8e7e5" d="M22.1 19.6a15 15 0 0 0-5.2 1c-4.3 1.5-6.6 5.2-7.6 9.2a16 16 0 0 1 9.7-3.5c7.6-.4 10.2 5.1 10.2 7.5q0 3.6-2.9 5a21 21 0 0 1-8.1 1.4c-3.2 0-5.2-.6-9-1.4 2 10.6 12 17 24 17 11.8 0 21.8-6.4 24-17-3.9.8-5.9 1.4-9.1 1.4-1.3 0-6-.2-8.1-1.4q-3-1.4-3-5c.1-2.4 2.7-7.9 10.2-7.5 4.7.3 7 1.5 9.8 3.5-1-4-3.3-7.7-7.6-9.2-7.6-2.8-12.6 1.3-16.3 1.4-2.7 0-6.2-2.4-11-2.4m35.4 13.7v1.2zm0 2.1v.2zm0 .6v.1zm-.2 2.2v.2zm-48-8.4"/>
<path fill="#77889b" d="M29.2 33.8c0-2.4-2.6-7.9-10.2-7.5a16 16 0 0 0-9.7 3.5 21 21 0 0 0-.1 9c3.8.8 5.8 1.4 9 1.4a20 20 0 0 0 8.1-1.4q3-1.4 3-5m7.9 0c0-2.4 2.6-7.9 10.1-7.5 4.7.3 7 1.5 9.8 3.5a21 21 0 0 1 .1 9c-3.8.8-5.8 1.4-9 1.4-1.3 0-6-.2-8.1-1.4q-3-1.4-3-5"/>
<path fill="#333a42" d="M26.4 34.4c0 1.8-1.7 2.2-2.4.6q-.6-1.5-2.3-1.4c-1 0-1.8.8-2 1.4a1.2 1.2 0 0 1-2.4-.3c0-2 2-4 4.5-4.2 2.5-.1 4.6 2.2 4.6 4m4.4 4.7-.3-.6q0-.4.2-.7l.4-.2.4-.2h1.6l2.1.2.4.2.2.7-.3.6q-.5.6-1.1.7l-1.3.1-1.2-.1q-.6-.1-1-.7m4.3 5.1q1.5.2 2.5-.6.3 0 .5-.4v-.5q0-.3-.3-.4l-.6-.1-.3.1q-.7.3-1.6.3t-1.6-.5l-.7-.6-.7.6q-.7.5-1.5.5-.7 0-1.6-.3l-.4-.1h-.5l-.4.5.1.5.4.4q1.2.8 2.5.6 1.2 0 2.1-.7 1 .7 2.1.7m4.7-9.9c0 1.8 1.7 2.2 2.3.6q.8-1.5 2.4-1.4c.9 0 1.7.8 2 1.4.4 1.5 2.3 1.2 2.4-.2 0-2.1-2-4.2-4.5-4.3s-4.6 2.1-4.6 4"/>
</symbol>
<symbol id="gts-phosphor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<g fill="currentcolor">
<ellipse cx="16" cy="17" opacity=".2" rx="12" ry="11"/>
<path d="M13.6 5c.5-1 2.4-1.7 2.4 0v1q3.6 0 6.5 1.7 2.5 1 3.4 1 1.7 0 1.6 1.3 0 .7-1 1.6a10 10 0 0 1 1.4 6.8q1 1 1.1 2.2 0 1.3-.7 1.8 0 3-1 3.2-1.2.4-1.6-.9-1 1.3-1.7 1.3-.5 0-.8-.2-3 2.1-7.2 2.2-4.1 0-7.2-2.2-.4.4-1 .3-.5 0-1.3-1-1.1 1.1-2 .8-.8-.6-.5-2.7-.8-.5-1-1.7 0-1.2 1.2-2.8L4 17a11 11 0 0 1 6.8-10c-1.1-.6-1.4-1.7-.4-2q1.6-.6 3 1.4l-.2-.2q0-.5.4-1.2m2.4 6c-2.6 0-5-2.2-6.7-.7Q6 12.8 6 17c0 5 4.5 9 10 9s10-4 10-9q-.1-4.2-3.4-6.8c-1.8-1.4-4 .7-6.6.7m-1.2 7.4-.2-.4v-.5l.3-.3h.3l.9-.1h.9l.3.1.2.3v.9l-.7.6h-1.4q-.5-.1-.6-.6M13 16.5c0 1-1 1.2-1.3.3q-.3-.8-1.3-.7t-1 .7c-.3.8-1.4.7-1.4-.1 0-1.2 1-2.3 2.5-2.3 1.4-.1 2.5 1.1 2.5 2.1m6 0c0 1 1 1.2 1.3.3q.3-.8 1.3-.7t1 .7c.3.8 1.4.7 1.4-.1 0-1.1-1-2.3-2.5-2.3-1.4-.1-2.5 1.1-2.5 2.1m-1.7 5.9q1 0 1.7-.4l.3-.4v-.4l-.2-.2h-.6q-.5.3-1 .2l-1.1-.4q-.3 0-.5-.4l-.5.4-1 .4q-.6 0-1.1-.2h-.6q-.3 0-.3.2v.4l.4.4q.6.4 1.7.4.8 0 1.4-.6z"/>
</g>
</symbol>
<symbol id="arrow-bend-up-left" fill="currentcolor" viewBox="0 0 256 256">
<path d="M80,56v96L32,104Z" opacity="0.2"></path>
<path d="M128,96H88V56a8,8,0,0,0-13.66-5.66l-48,48a8,8,0,0,0,0,11.32l48,48A8,8,0,0,0,88,152V112h40a88.1,88.1,0,0,1,88,88,8,8,0,0,0,16,0A104.11,104.11,0,0,0,128,96ZM72,132.69,43.31,104,72,75.31Z"></path>
@@ -283,7 +297,7 @@
<symbol id="lock-open-simple" fill="currentcolor" viewBox="0 0 256 256">
<path d="M216,96V208a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8H208A8,8,0,0,1,216,96Z" opacity="0.2"></path>
<path d="M48,8 C74.509668,8 96,29.490332 96,56 L95.9994315,80 L208,80 C216.836556,80 224,87.163444 224,96 L224,208 C224,216.836556 216.836556,224 208,224 L48,224 C39.163444,224 32,216.836556 32,208 L32,96 C32,87.163444 39.163444,80 48,80 L79.9994315,80 L80,56 C80,38.5036191 65.9582171,24.2868724 48.5291785,24.0042871 L48,24 C32.5086083,24 18.8027209,35.0099629 15.83982,49.592866 C14.9601045,53.922679 10.7369471,56.7195356 6.40713405,55.83982 C2.077321,54.9601045 -0.719535601,50.7369471 0.160179973,46.407134 C4.64934606,24.3122088 24.9557992,8 48,8 Z M208,96 L48,96 L48,208 L208,208 L208,96 Z"/>
<path d="M207.998431,8 C231.042632,8 251.349085,24.3122088 255.838251,46.407134 C256.717967,50.7369471 253.92111,54.9601045 249.591297,55.83982 C245.261484,56.7195356 241.038327,53.922679 240.158611,49.592866 C237.195711,35.0099629 223.489823,24 207.998431,24 C190.325319,24 175.998431,38.326888 175.998431,56 L175.998431,80 L208,80 C216.836556,80 224,87.163444 224,96 L224,208 C224,216.836556 216.836556,224 208,224 L48,224 C39.163444,224 32,216.836556 32,208 L32,96 C32,87.163444 39.163444,80 48,80 L159.998431,80 L159.998431,56 C159.998431,29.490332 181.488763,8 207.998431,8 Z M208,96 L48,96 L48,208 L208,208 L208,96 Z"/>
</symbol>
<symbol id="magnifying-glass" fill="currentcolor" viewBox="0 0 256 256">

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 59 KiB