parent
							
								
									268e955aef
								
							
						
					
					
						commit
						385eb83893
					
				
					 18 changed files with 55 additions and 39 deletions
				
			
		| 
						 | 
				
			
			@ -33,7 +33,7 @@ export const AnimatedNumber: React.FC<Props> = ({ value, obfuscate }) => {
 | 
			
		|||
  const willEnter = useCallback(() => ({ y: -1 * direction }), [direction]);
 | 
			
		||||
  const willLeave = useCallback(
 | 
			
		||||
    () => ({ y: spring(1 * direction, { damping: 35, stiffness: 400 }) }),
 | 
			
		||||
    [direction]
 | 
			
		||||
    [direction],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  if (reduceMotion) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ export const Avatar: React.FC<Props> = ({
 | 
			
		|||
 | 
			
		||||
  if (account) {
 | 
			
		||||
    style.backgroundImage = `url(${account.get(
 | 
			
		||||
      hovering ? 'avatar' : 'avatar_static'
 | 
			
		||||
      hovering ? 'avatar' : 'avatar_static',
 | 
			
		||||
    )})`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ export const Avatar: React.FC<Props> = ({
 | 
			
		|||
      className={classNames(
 | 
			
		||||
        'account__avatar',
 | 
			
		||||
        { 'account__avatar-inline': inline },
 | 
			
		||||
        className
 | 
			
		||||
        className,
 | 
			
		||||
      )}
 | 
			
		||||
      onMouseEnter={handleMouseEnter}
 | 
			
		||||
      onMouseLeave={handleMouseLeave}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl';
 | 
			
		|||
 | 
			
		||||
export const StatusesCounter = (
 | 
			
		||||
  displayNumber: React.ReactNode,
 | 
			
		||||
  pluralReady: number
 | 
			
		||||
  pluralReady: number,
 | 
			
		||||
) => (
 | 
			
		||||
  <FormattedMessage
 | 
			
		||||
    id='account.statuses_counter'
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ export const StatusesCounter = (
 | 
			
		|||
 | 
			
		||||
export const FollowingCounter = (
 | 
			
		||||
  displayNumber: React.ReactNode,
 | 
			
		||||
  pluralReady: number
 | 
			
		||||
  pluralReady: number,
 | 
			
		||||
) => (
 | 
			
		||||
  <FormattedMessage
 | 
			
		||||
    id='account.following_counter'
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ export const FollowingCounter = (
 | 
			
		|||
 | 
			
		||||
export const FollowersCounter = (
 | 
			
		||||
  displayNumber: React.ReactNode,
 | 
			
		||||
  pluralReady: number
 | 
			
		||||
  pluralReady: number,
 | 
			
		||||
) => (
 | 
			
		||||
  <FormattedMessage
 | 
			
		||||
    id='account.followers_counter'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ export const GIFV: React.FC<Props> = ({
 | 
			
		|||
        onClick();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    [onClick]
 | 
			
		||||
    [onClick],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ export const timeAgoString = (
 | 
			
		|||
  now: number,
 | 
			
		||||
  year: number,
 | 
			
		||||
  timeGiven: boolean,
 | 
			
		||||
  short?: boolean
 | 
			
		||||
  short?: boolean,
 | 
			
		||||
) => {
 | 
			
		||||
  const delta = now - date.getTime();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,28 +118,28 @@ export const timeAgoString = (
 | 
			
		|||
    relativeTime = intl.formatMessage(messages.today);
 | 
			
		||||
  } else if (delta < 10 * SECOND) {
 | 
			
		||||
    relativeTime = intl.formatMessage(
 | 
			
		||||
      short ? messages.just_now : messages.just_now_full
 | 
			
		||||
      short ? messages.just_now : messages.just_now_full,
 | 
			
		||||
    );
 | 
			
		||||
  } else if (delta < 7 * DAY) {
 | 
			
		||||
    if (delta < MINUTE) {
 | 
			
		||||
      relativeTime = intl.formatMessage(
 | 
			
		||||
        short ? messages.seconds : messages.seconds_full,
 | 
			
		||||
        { number: Math.floor(delta / SECOND) }
 | 
			
		||||
        { number: Math.floor(delta / SECOND) },
 | 
			
		||||
      );
 | 
			
		||||
    } else if (delta < HOUR) {
 | 
			
		||||
      relativeTime = intl.formatMessage(
 | 
			
		||||
        short ? messages.minutes : messages.minutes_full,
 | 
			
		||||
        { number: Math.floor(delta / MINUTE) }
 | 
			
		||||
        { number: Math.floor(delta / MINUTE) },
 | 
			
		||||
      );
 | 
			
		||||
    } else if (delta < DAY) {
 | 
			
		||||
      relativeTime = intl.formatMessage(
 | 
			
		||||
        short ? messages.hours : messages.hours_full,
 | 
			
		||||
        { number: Math.floor(delta / HOUR) }
 | 
			
		||||
        { number: Math.floor(delta / HOUR) },
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      relativeTime = intl.formatMessage(
 | 
			
		||||
        short ? messages.days : messages.days_full,
 | 
			
		||||
        { number: Math.floor(delta / DAY) }
 | 
			
		||||
        { number: Math.floor(delta / DAY) },
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  } else if (date.getFullYear() === year) {
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ const timeRemainingString = (
 | 
			
		|||
  intl: IntlShape,
 | 
			
		||||
  date: Date,
 | 
			
		||||
  now: number,
 | 
			
		||||
  timeGiven = true
 | 
			
		||||
  timeGiven = true,
 | 
			
		||||
) => {
 | 
			
		||||
  const delta = date.getTime() - now;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import { toShortNumber, pluralReady, DECIMAL_UNITS } from '../utils/numbers';
 | 
			
		|||
 | 
			
		||||
type ShortNumberRenderer = (
 | 
			
		||||
  displayNumber: JSX.Element,
 | 
			
		||||
  pluralReady: number
 | 
			
		||||
  pluralReady: number,
 | 
			
		||||
) => JSX.Element;
 | 
			
		||||
 | 
			
		||||
interface ShortNumberProps {
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ export const ShortNumberRenderer: React.FC<ShortNumberProps> = ({
 | 
			
		|||
 | 
			
		||||
  if (children && renderer) {
 | 
			
		||||
    console.warn(
 | 
			
		||||
      'Both renderer prop and renderer as a child provided. This is a mistake and you really should fix that. Only renderer passed as a child will be used.'
 | 
			
		||||
      'Both renderer prop and renderer as a child provided. This is a mistake and you really should fix that. Only renderer passed as a child will be used.',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ export type SearchData = [
 | 
			
		|||
  BaseEmoji['native'],
 | 
			
		||||
  Emoji['short_names'],
 | 
			
		||||
  Search,
 | 
			
		||||
  Emoji['unified']
 | 
			
		||||
  Emoji['unified'],
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export interface ShortCodesToEmojiData {
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ export type EmojiCompressed = [
 | 
			
		|||
  Skins,
 | 
			
		||||
  Category[],
 | 
			
		||||
  Data['aliases'],
 | 
			
		||||
  EmojisWithoutShortCodes
 | 
			
		||||
  EmojisWithoutShortCodes,
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ if (!HTMLCanvasElement.prototype.toBlob) {
 | 
			
		|||
      this: HTMLCanvasElement,
 | 
			
		||||
      callback: BlobCallback,
 | 
			
		||||
      type = 'image/png',
 | 
			
		||||
      quality: unknown
 | 
			
		||||
      quality: unknown,
 | 
			
		||||
    ) {
 | 
			
		||||
      const dataURL: string = this.toDataURL(type, quality);
 | 
			
		||||
      let data;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ const initialRootState = Object.fromEntries(
 | 
			
		|||
    reducer(undefined, {
 | 
			
		||||
      // empty action
 | 
			
		||||
    }),
 | 
			
		||||
  ])
 | 
			
		||||
  ]),
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const RootStateRecord = ImmutableRecord(initialRootState, 'RootState');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ interface PopModalOption {
 | 
			
		|||
}
 | 
			
		||||
const popModal = (
 | 
			
		||||
  state: State,
 | 
			
		||||
  { modalType, ignoreFocus }: PopModalOption
 | 
			
		||||
  { modalType, ignoreFocus }: PopModalOption,
 | 
			
		||||
): State => {
 | 
			
		||||
  if (
 | 
			
		||||
    modalType === undefined ||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,12 +52,12 @@ const popModal = (
 | 
			
		|||
const pushModal = (
 | 
			
		||||
  state: State,
 | 
			
		||||
  modalType: ModalType,
 | 
			
		||||
  modalProps: ModalProps
 | 
			
		||||
  modalProps: ModalProps,
 | 
			
		||||
): State => {
 | 
			
		||||
  return state.withMutations((record) => {
 | 
			
		||||
    record.set('ignoreFocus', false);
 | 
			
		||||
    record.update('stack', (stack) =>
 | 
			
		||||
      stack.unshift(Modal({ modalType, modalProps }))
 | 
			
		||||
      stack.unshift(Modal({ modalType, modalProps })),
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -68,14 +68,14 @@ export function modalReducer(
 | 
			
		|||
    modalType: ModalType;
 | 
			
		||||
    ignoreFocus: boolean;
 | 
			
		||||
    modalProps: Record<string, unknown>;
 | 
			
		||||
  }>
 | 
			
		||||
  }>,
 | 
			
		||||
) {
 | 
			
		||||
  switch (action.type) {
 | 
			
		||||
    case openModal.type:
 | 
			
		||||
      return pushModal(
 | 
			
		||||
        state,
 | 
			
		||||
        action.payload.modalType,
 | 
			
		||||
        action.payload.modalProps
 | 
			
		||||
        action.payload.modalProps,
 | 
			
		||||
      );
 | 
			
		||||
    case closeModal.type:
 | 
			
		||||
      return popModal(state, action.payload);
 | 
			
		||||
| 
						 | 
				
			
			@ -85,8 +85,8 @@ export function modalReducer(
 | 
			
		|||
      return state.update('stack', (stack) =>
 | 
			
		||||
        stack.filterNot(
 | 
			
		||||
          // @ts-expect-error TIMELINE_DELETE action is not typed yet.
 | 
			
		||||
          (modal) => modal.get('modalProps').statusId === action.id
 | 
			
		||||
        )
 | 
			
		||||
          (modal) => modal.get('modalProps').statusId === action.id,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    default:
 | 
			
		||||
      return state;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,12 @@ const easingOutQuint = (
 | 
			
		|||
  t: number,
 | 
			
		||||
  b: number,
 | 
			
		||||
  c: number,
 | 
			
		||||
  d: number
 | 
			
		||||
  d: number,
 | 
			
		||||
) => c * ((t = t / d - 1) * t * t * t * t + 1) + b;
 | 
			
		||||
const scroll = (
 | 
			
		||||
  node: Element,
 | 
			
		||||
  key: 'scrollTop' | 'scrollLeft',
 | 
			
		||||
  target: number
 | 
			
		||||
  target: number,
 | 
			
		||||
) => {
 | 
			
		||||
  const startTime = Date.now();
 | 
			
		||||
  const offset = node[key];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ export const store = configureStore({
 | 
			
		|||
      .concat(
 | 
			
		||||
        loadingBarMiddleware({
 | 
			
		||||
          promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'],
 | 
			
		||||
        })
 | 
			
		||||
        }),
 | 
			
		||||
      )
 | 
			
		||||
      .concat(errorsMiddleware)
 | 
			
		||||
      .concat(soundsMiddleware()),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = [
 | 
			
		|||
];
 | 
			
		||||
 | 
			
		||||
export const loadingBarMiddleware = (
 | 
			
		||||
  config: Config = {}
 | 
			
		||||
  config: Config = {},
 | 
			
		||||
): Middleware<Record<string, never>, RootState> => {
 | 
			
		||||
  const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypeSuffixes;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,9 +31,19 @@ body {
 | 
			
		|||
    // Droid Sans => Older Androids (<4.0)
 | 
			
		||||
    // Helvetica Neue => Older macOS <10.11
 | 
			
		||||
    // $font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0)
 | 
			
		||||
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
 | 
			
		||||
      Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
 | 
			
		||||
      $font-sans-serif, sans-serif;
 | 
			
		||||
    font-family:
 | 
			
		||||
      system-ui,
 | 
			
		||||
      -apple-system,
 | 
			
		||||
      BlinkMacSystemFont,
 | 
			
		||||
      'Segoe UI',
 | 
			
		||||
      Oxygen,
 | 
			
		||||
      Ubuntu,
 | 
			
		||||
      Cantarell,
 | 
			
		||||
      'Fira Sans',
 | 
			
		||||
      'Droid Sans',
 | 
			
		||||
      'Helvetica Neue',
 | 
			
		||||
      $font-sans-serif,
 | 
			
		||||
      sans-serif;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &.app-body {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -480,7 +480,9 @@ $ui-header-height: 55px;
 | 
			
		|||
  overflow: hidden;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  color: $darker-text-color;
 | 
			
		||||
  transition: max-height 150ms ease-in-out, opacity 300ms linear;
 | 
			
		||||
  transition:
 | 
			
		||||
    max-height 150ms ease-in-out,
 | 
			
		||||
    opacity 300ms linear;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  z-index: 1;
 | 
			
		||||
  position: relative;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,9 @@
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.no-reduce-motion .spoiler-input {
 | 
			
		||||
  transition: height 0.4s ease, opacity 0.4s ease;
 | 
			
		||||
  transition:
 | 
			
		||||
    height 0.4s ease,
 | 
			
		||||
    opacity 0.4s ease;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.spoiler-input {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,14 +253,16 @@
 | 
			
		|||
@for $i from 0 through 3 {
 | 
			
		||||
  .mbstobon-#{$i} .drawer__inner__mastodon {
 | 
			
		||||
    @if $i == 3 {
 | 
			
		||||
      background: url('~flavours/glitch/images/wave-drawer.png')
 | 
			
		||||
      background:
 | 
			
		||||
        url('~flavours/glitch/images/wave-drawer.png')
 | 
			
		||||
          no-repeat
 | 
			
		||||
          bottom /
 | 
			
		||||
          100%
 | 
			
		||||
          auto,
 | 
			
		||||
        lighten($ui-base-color, 13%);
 | 
			
		||||
    } @else {
 | 
			
		||||
      background: url('~flavours/glitch/images/wave-drawer-glitched.png')
 | 
			
		||||
      background:
 | 
			
		||||
        url('~flavours/glitch/images/wave-drawer-glitched.png')
 | 
			
		||||
          no-repeat
 | 
			
		||||
          bottom /
 | 
			
		||||
          100%
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ export function toShortNumber(sourceNumber: number): ShortNumber {
 | 
			
		|||
 */
 | 
			
		||||
export function pluralReady(
 | 
			
		||||
  sourceNumber: number,
 | 
			
		||||
  division: DecimalUnits
 | 
			
		||||
  division: DecimalUnits,
 | 
			
		||||
): number {
 | 
			
		||||
  if (division == null || division < DECIMAL_UNITS.HUNDRED) {
 | 
			
		||||
    return sourceNumber;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue