init
BIN
app/javascript/images/skin/bg_dark.jpg
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
app/javascript/images/skin/bg_light.jpg
Normal file
After Width: | Height: | Size: 838 KiB |
BIN
app/javascript/images/skin/ex_bg_dark.jpg
Normal file
After Width: | Height: | Size: 513 KiB |
BIN
app/javascript/images/skin/logo_dark.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
app/javascript/images/skin/logo_light.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
app/javascript/images/skin/m_logo_dark.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
app/javascript/images/skin/m_logo_light.png
Normal file
After Width: | Height: | Size: 32 KiB |
@ -78,10 +78,6 @@ export class DisplayName extends React.PureComponent<Props> {
|
||||
} else if (account) {
|
||||
let acct = account.get('acct');
|
||||
|
||||
if (!acct.includes('@') && localDomain) {
|
||||
acct = `${acct}@${localDomain}`;
|
||||
}
|
||||
|
||||
displayName = (
|
||||
<bdi>
|
||||
<strong
|
||||
|
@ -8,6 +8,7 @@ import { debounce } from 'lodash';
|
||||
import RegenerationIndicator from 'mastodon/components/regeneration_indicator';
|
||||
|
||||
import StatusContainer from '../containers/status_container';
|
||||
import StatusContainerWithoutDm from '../containers/status_container_without_dm';
|
||||
|
||||
import { LoadGap } from './load_gap';
|
||||
import ScrollableList from './scrollable_list';
|
||||
@ -98,18 +99,29 @@ export default class StatusList extends ImmutablePureComponent {
|
||||
maxId={index > 0 ? statusIds.get(index - 1) : null}
|
||||
onClick={onLoadMore}
|
||||
/>
|
||||
) : (
|
||||
<StatusContainer
|
||||
key={statusId}
|
||||
id={statusId}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
scrollKey={this.props.scrollKey}
|
||||
showThread
|
||||
withCounters={this.props.withCounters}
|
||||
/>
|
||||
))
|
||||
) :
|
||||
(timelineId == 'account' ?
|
||||
<StatusContainerWithoutDm
|
||||
key={statusId}
|
||||
id={statusId}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
scrollKey={this.props.scrollKey}
|
||||
showThread
|
||||
withCounters={this.props.withCounters}
|
||||
/>
|
||||
:
|
||||
<StatusContainer
|
||||
key={statusId}
|
||||
id={statusId}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
scrollKey={this.props.scrollKey}
|
||||
showThread
|
||||
withCounters={this.props.withCounters}
|
||||
/>))
|
||||
) : null;
|
||||
|
||||
if (scrollableContent && featuredStatusIds) {
|
||||
|
@ -0,0 +1,288 @@
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import {
|
||||
unmuteAccount,
|
||||
unblockAccount,
|
||||
} from '../actions/accounts';
|
||||
import { showAlertForError } from '../actions/alerts';
|
||||
import { initBlockModal } from '../actions/blocks';
|
||||
import { initBoostModal } from '../actions/boosts';
|
||||
import {
|
||||
replyCompose,
|
||||
mentionCompose,
|
||||
directCompose,
|
||||
} from '../actions/compose';
|
||||
import {
|
||||
blockDomain,
|
||||
unblockDomain,
|
||||
} from '../actions/domain_blocks';
|
||||
import {
|
||||
initAddFilter,
|
||||
} from '../actions/filters';
|
||||
import {
|
||||
reblog,
|
||||
favourite,
|
||||
bookmark,
|
||||
unreblog,
|
||||
unfavourite,
|
||||
unbookmark,
|
||||
pin,
|
||||
unpin,
|
||||
} from '../actions/interactions';
|
||||
import { openModal } from '../actions/modal';
|
||||
import { initMuteModal } from '../actions/mutes';
|
||||
import { deployPictureInPicture } from '../actions/picture_in_picture';
|
||||
import { initReport } from '../actions/reports';
|
||||
import {
|
||||
muteStatus,
|
||||
unmuteStatus,
|
||||
deleteStatus,
|
||||
hideStatus,
|
||||
revealStatus,
|
||||
toggleStatusCollapse,
|
||||
editStatus,
|
||||
translateStatus,
|
||||
undoStatusTranslation,
|
||||
} from '../actions/statuses';
|
||||
import Status from '../components/status';
|
||||
import { boostModal, deleteModal } from '../initial_state';
|
||||
import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
|
||||
|
||||
const messages = defineMessages({
|
||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
||||
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
|
||||
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' },
|
||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
||||
editConfirm: { id: 'confirmations.edit.confirm', defaultMessage: 'Edit' },
|
||||
editMessage: { id: 'confirmations.edit.message', defaultMessage: 'Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
||||
});
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getStatus = makeGetStatus();
|
||||
const getPictureInPicture = makeGetPictureInPicture();
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
//여기 status 바꿈
|
||||
status: getStatus(state, props).get('visibility')!=='direct'? getStatus(state, props) : null,
|
||||
nextInReplyToId: props.nextId ? state.getIn(['statuses', props.nextId, 'in_reply_to_id']) : null,
|
||||
pictureInPicture: getPictureInPicture(state, props),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
|
||||
|
||||
onReply (status, router) {
|
||||
dispatch((_, getState) => {
|
||||
let state = getState();
|
||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalProps: {
|
||||
message: intl.formatMessage(messages.replyMessage),
|
||||
confirm: intl.formatMessage(messages.replyConfirm),
|
||||
onConfirm: () => dispatch(replyCompose(status, router)) },
|
||||
}));
|
||||
} else {
|
||||
dispatch(replyCompose(status, router));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onModalReblog (status, privacy) {
|
||||
if (status.get('reblogged')) {
|
||||
dispatch(unreblog(status));
|
||||
} else {
|
||||
dispatch(reblog(status, privacy));
|
||||
}
|
||||
},
|
||||
|
||||
onReblog (status, e) {
|
||||
if ((e && e.shiftKey) || !boostModal) {
|
||||
this.onModalReblog(status);
|
||||
} else {
|
||||
dispatch(initBoostModal({ status, onReblog: this.onModalReblog }));
|
||||
}
|
||||
},
|
||||
|
||||
onFavourite (status) {
|
||||
if (status.get('favourited')) {
|
||||
dispatch(unfavourite(status));
|
||||
} else {
|
||||
dispatch(favourite(status));
|
||||
}
|
||||
},
|
||||
|
||||
onBookmark (status) {
|
||||
if (status.get('bookmarked')) {
|
||||
dispatch(unbookmark(status));
|
||||
} else {
|
||||
dispatch(bookmark(status));
|
||||
}
|
||||
},
|
||||
|
||||
onPin (status) {
|
||||
if (status.get('pinned')) {
|
||||
dispatch(unpin(status));
|
||||
} else {
|
||||
dispatch(pin(status));
|
||||
}
|
||||
},
|
||||
|
||||
onEmbed (status) {
|
||||
dispatch(openModal({
|
||||
modalType: 'EMBED',
|
||||
modalProps: {
|
||||
id: status.get('id'),
|
||||
onError: error => dispatch(showAlertForError(error)),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onDelete (status, history, withRedraft = false) {
|
||||
if (!deleteModal) {
|
||||
dispatch(deleteStatus(status.get('id'), history, withRedraft));
|
||||
} else {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalProps: {
|
||||
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
|
||||
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
|
||||
onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
|
||||
},
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
onEdit (status, history) {
|
||||
dispatch((_, getState) => {
|
||||
let state = getState();
|
||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalProps: {
|
||||
message: intl.formatMessage(messages.editMessage),
|
||||
confirm: intl.formatMessage(messages.editConfirm),
|
||||
onConfirm: () => dispatch(editStatus(status.get('id'), history)),
|
||||
},
|
||||
}));
|
||||
} else {
|
||||
dispatch(editStatus(status.get('id'), history));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onTranslate (status) {
|
||||
if (status.get('translation')) {
|
||||
dispatch(undoStatusTranslation(status.get('id'), status.get('poll')));
|
||||
} else {
|
||||
dispatch(translateStatus(status.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onDirect (account, router) {
|
||||
dispatch(directCompose(account, router));
|
||||
},
|
||||
|
||||
onMention (account, router) {
|
||||
dispatch(mentionCompose(account, router));
|
||||
},
|
||||
|
||||
onOpenMedia (statusId, media, index, lang) {
|
||||
dispatch(openModal({
|
||||
modalType: 'MEDIA',
|
||||
modalProps: { statusId, media, index, lang },
|
||||
}));
|
||||
},
|
||||
|
||||
onOpenVideo (statusId, media, lang, options) {
|
||||
dispatch(openModal({
|
||||
modalType: 'VIDEO',
|
||||
modalProps: { statusId, media, lang, options },
|
||||
}));
|
||||
},
|
||||
|
||||
onBlock (status) {
|
||||
const account = status.get('account');
|
||||
dispatch(initBlockModal(account));
|
||||
},
|
||||
|
||||
onUnblock (account) {
|
||||
dispatch(unblockAccount(account.get('id')));
|
||||
},
|
||||
|
||||
onReport (status) {
|
||||
dispatch(initReport(status.get('account'), status));
|
||||
},
|
||||
|
||||
onAddFilter (status) {
|
||||
dispatch(initAddFilter(status, { contextType }));
|
||||
},
|
||||
|
||||
onMute (account) {
|
||||
dispatch(initMuteModal(account));
|
||||
},
|
||||
|
||||
onUnmute (account) {
|
||||
dispatch(unmuteAccount(account.get('id')));
|
||||
},
|
||||
|
||||
onMuteConversation (status) {
|
||||
if (status.get('muted')) {
|
||||
dispatch(unmuteStatus(status.get('id')));
|
||||
} else {
|
||||
dispatch(muteStatus(status.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onToggleHidden (status) {
|
||||
if (status.get('hidden')) {
|
||||
dispatch(revealStatus(status.get('id')));
|
||||
} else {
|
||||
dispatch(hideStatus(status.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onToggleCollapsed (status, isCollapsed) {
|
||||
dispatch(toggleStatusCollapse(status.get('id'), isCollapsed));
|
||||
},
|
||||
|
||||
onBlockDomain (domain) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalProps: {
|
||||
message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' values={{ domain: <strong>{domain}</strong> }} />,
|
||||
confirm: intl.formatMessage(messages.blockDomainConfirm),
|
||||
onConfirm: () => dispatch(blockDomain(domain)),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onUnblockDomain (domain) {
|
||||
dispatch(unblockDomain(domain));
|
||||
},
|
||||
|
||||
deployPictureInPicture (status, type, mediaProps) {
|
||||
dispatch(deployPictureInPicture(status.get('id'), status.getIn(['account', 'id']), type, mediaProps));
|
||||
},
|
||||
|
||||
onInteractionModal (type, status) {
|
||||
dispatch(openModal({
|
||||
modalType: 'INTERACTION',
|
||||
modalProps: {
|
||||
type,
|
||||
accountId: status.getIn(['account', 'id']),
|
||||
url: status.get('uri'),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Status));
|
@ -120,7 +120,7 @@ class About extends PureComponent {
|
||||
<div className='scrollable about'>
|
||||
<div className='about__header'>
|
||||
<ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' />
|
||||
<h1>{isLoading ? <Skeleton width='10ch' /> : server.get('domain')}</h1>
|
||||
<h1>{isLoading ? <Skeleton width='10ch' /> : server.get('title')}</h1>
|
||||
<p><FormattedMessage id='about.powered_by' defaultMessage='Decentralized social media powered by {mastodon}' values={{ mastodon: <a href='https://joinmastodon.org' className='about__mail' target='_blank'>Mastodon</a> }} /></p>
|
||||
</div>
|
||||
|
||||
@ -175,35 +175,6 @@ class About extends PureComponent {
|
||||
))}
|
||||
</Section>
|
||||
|
||||
<Section title={intl.formatMessage(messages.blocks)} onOpen={this.handleDomainBlocksOpen}>
|
||||
{domainBlocks.get('isLoading') ? (
|
||||
<>
|
||||
<Skeleton width='100%' />
|
||||
<br />
|
||||
<Skeleton width='70%' />
|
||||
</>
|
||||
) : (domainBlocks.get('isAvailable') ? (
|
||||
<>
|
||||
<p><FormattedMessage id='about.domain_blocks.preamble' defaultMessage='Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.' /></p>
|
||||
|
||||
<div className='about__domain-blocks'>
|
||||
{domainBlocks.get('items').map(block => (
|
||||
<div className='about__domain-blocks__domain' key={block.get('domain')}>
|
||||
<div className='about__domain-blocks__domain__header'>
|
||||
<h6><span title={`SHA-256: ${block.get('digest')}`}>{block.get('domain')}</span></h6>
|
||||
<span className='about__domain-blocks__domain__type' title={intl.formatMessage(severityMessages[block.get('severity')].explanation)}>{intl.formatMessage(severityMessages[block.get('severity')].title)}</span>
|
||||
</div>
|
||||
|
||||
<p>{(block.get('comment') || '').length > 0 ? block.get('comment') : <FormattedMessage id='about.domain_blocks.no_reason_available' defaultMessage='Reason not available' />}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p><FormattedMessage id='about.not_available' defaultMessage='This information has not been made available on this server.' /></p>
|
||||
))}
|
||||
</Section>
|
||||
|
||||
<LinkFooter />
|
||||
|
||||
<div className='about__footer'>
|
||||
|
@ -368,7 +368,7 @@ class Header extends ImmutablePureComponent {
|
||||
const displayNameHtml = { __html: account.get('display_name_html') };
|
||||
const fields = account.get('fields');
|
||||
const isLocal = account.get('acct').indexOf('@') === -1;
|
||||
const acct = isLocal && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
|
||||
const acct = account.get('acct');
|
||||
const isIndexable = !account.get('noindex');
|
||||
|
||||
const badges = [];
|
||||
|
@ -21,6 +21,8 @@ export default class NavigationBar extends ImmutablePureComponent {
|
||||
|
||||
render () {
|
||||
const username = this.props.account.get('acct')
|
||||
const displayName = this.props.account.get('display_name');
|
||||
|
||||
return (
|
||||
<div className='navigation-bar'>
|
||||
<Link to={`/@${username}`}>
|
||||
@ -29,15 +31,17 @@ export default class NavigationBar extends ImmutablePureComponent {
|
||||
</Link>
|
||||
|
||||
<div className='navigation-bar__profile'>
|
||||
<span>
|
||||
<Link to={`/@${username}`}>
|
||||
<strong className='navigation-bar__profile-account'>{displayName}</strong>
|
||||
</Link>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<Link to={`/@${username}`}>
|
||||
<strong className='navigation-bar__profile-account'>@{username}</strong>
|
||||
</Link>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className='navigation-bar__actions'>
|
||||
|
@ -8,7 +8,7 @@ import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'mastodon/initial_state';
|
||||
import { title, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'mastodon/initial_state';
|
||||
import { PERMISSION_INVITE_USERS } from 'mastodon/permissions';
|
||||
import { logOut } from 'mastodon/utils/log_out';
|
||||
|
||||
@ -64,7 +64,7 @@ class LinkFooter extends PureComponent {
|
||||
return (
|
||||
<div className='link-footer'>
|
||||
<p>
|
||||
<strong>{domain}</strong>:
|
||||
<strong>{title}</strong>:
|
||||
{' '}
|
||||
<Link to='/about' target={multiColumn ? '_blank' : undefined}><FormattedMessage id='footer.about' defaultMessage='About' /></Link>
|
||||
{statusPageUrl && (
|
||||
|
@ -20,8 +20,6 @@ import SignInBanner from './sign_in_banner';
|
||||
const messages = defineMessages({
|
||||
home: { id: 'tabs_bar.home', defaultMessage: 'Home' },
|
||||
notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
|
||||
explore: { id: 'explore.title', defaultMessage: 'Explore' },
|
||||
firehose: { id: 'column.firehose', defaultMessage: 'Live feeds' },
|
||||
direct: { id: 'navigation_bar.direct', defaultMessage: 'Private mentions' },
|
||||
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' },
|
||||
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
|
||||
@ -29,7 +27,6 @@ const messages = defineMessages({
|
||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
followsAndFollowers: { id: 'navigation_bar.follows_and_followers', defaultMessage: 'Follows and followers' },
|
||||
about: { id: 'navigation_bar.about', defaultMessage: 'About' },
|
||||
search: { id: 'navigation_bar.search', defaultMessage: 'Search' },
|
||||
advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' },
|
||||
openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' },
|
||||
});
|
||||
@ -79,16 +76,6 @@ class NavigationPanel extends Component {
|
||||
</>
|
||||
)}
|
||||
|
||||
{trendsEnabled ? (
|
||||
<ColumnLink transparent to='/explore' icon='hashtag' text={intl.formatMessage(messages.explore)} />
|
||||
) : (
|
||||
<ColumnLink transparent to='/search' icon='search' text={intl.formatMessage(messages.search)} />
|
||||
)}
|
||||
|
||||
{(signedIn || timelinePreview) && (
|
||||
<ColumnLink transparent to='/public/local' isActive={this.isFirehoseActive} icon='globe' text={intl.formatMessage(messages.firehose)} />
|
||||
)}
|
||||
|
||||
{!signedIn && (
|
||||
<div className='navigation-panel__sign-in-banner'>
|
||||
<hr />
|
||||
@ -103,8 +90,6 @@ class NavigationPanel extends Component {
|
||||
<ColumnLink transparent to='/favourites' icon='star' text={intl.formatMessage(messages.favourites)} />
|
||||
<ColumnLink transparent to='/lists' icon='list-ul' text={intl.formatMessage(messages.lists)} />
|
||||
|
||||
<ListPanel />
|
||||
|
||||
<hr />
|
||||
|
||||
<ColumnLink transparent href='/settings/preferences' icon='cog' text={intl.formatMessage(messages.preferences)} />
|
||||
|
@ -18,6 +18,8 @@ const makeGetStatusIds = (pending = false) => createSelector([
|
||||
|
||||
const statusForId = statuses.get(id);
|
||||
let showStatus = true;
|
||||
|
||||
if (statusForId.get('visibility') === 'direct') return false;
|
||||
|
||||
if (statusForId.get('account') === me) return true;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
"about.domain_blocks.suspended.explanation": "이 서버의 어떤 데이터도 처리되거나, 저장 되거나 공유되지 않고, 이 서버의 어떤 유저와도 상호작용 하거나 대화할 수 없습니다.",
|
||||
"about.domain_blocks.suspended.title": "정지됨",
|
||||
"about.not_available": "이 정보는 이 서버에서 사용할 수 없습니다.",
|
||||
"about.powered_by": "{mastodon}으로 구동되는 분산 소셜 미디어",
|
||||
"about.powered_by": "{mastodon}으로 구동되는 전용 오리지널 캐릭터 커뮤니티",
|
||||
"about.rules": "서버 규칙",
|
||||
"account.account_note_header": "노트",
|
||||
"account.add_or_remove_from_list": "리스트에 추가 혹은 삭제",
|
||||
@ -21,7 +21,7 @@
|
||||
"account.blocked": "차단함",
|
||||
"account.browse_more_on_origin_server": "원본 프로필에서 더 탐색하기",
|
||||
"account.cancel_follow_request": "팔로우 취소",
|
||||
"account.direct": "@{name} 님에게 개인적으로 멘션",
|
||||
"account.direct": "@{name} 님에게 다이렉트 메시지",
|
||||
"account.disable_notifications": "@{name} 의 게시물 알림 끄기",
|
||||
"account.domain_blocked": "도메인 차단함",
|
||||
"account.edit_profile": "프로필 수정",
|
||||
@ -110,7 +110,7 @@
|
||||
"column.blocks": "차단한 사용자",
|
||||
"column.bookmarks": "북마크",
|
||||
"column.community": "로컬 타임라인",
|
||||
"column.direct": "개인적인 멘션",
|
||||
"column.direct": "다이렉트 메시지",
|
||||
"column.directory": "프로필 둘러보기",
|
||||
"column.domain_blocks": "차단한 도메인",
|
||||
"column.favourites": "좋아요",
|
||||
@ -228,7 +228,7 @@
|
||||
"empty_column.blocks": "아직 아무도 차단하지 않았습니다.",
|
||||
"empty_column.bookmarked_statuses": "아직 북마크에 저장한 게시물이 없습니다. 게시물을 북마크 지정하면 여기에 나타납니다.",
|
||||
"empty_column.community": "로컬 타임라인에 아무것도 없습니다. 아무거나 적어 보세요!",
|
||||
"empty_column.direct": "개인적인 멘션이 없습니다. 보내거나 받으면 여기에 표시됩니다.",
|
||||
"empty_column.direct": "다이렉트 메시지가 없습니다. 보내거나 받으면 여기에 표시됩니다.",
|
||||
"empty_column.domain_blocks": "아직 차단한 도메인이 없습니다.",
|
||||
"empty_column.explore_statuses": "아직 유행하는 것이 없습니다. 나중에 다시 확인하세요!",
|
||||
"empty_column.favourited_statuses": "아직 좋아요한 게시물이 없습니다. 게시물을 좋아요 하면 여기에 나타납니다.",
|
||||
@ -236,7 +236,7 @@
|
||||
"empty_column.follow_requests": "아직 팔로우 요청이 없습니다. 요청을 받았을 때 여기에 나타납니다.",
|
||||
"empty_column.followed_tags": "아직 아무 해시태그도 팔로우하고 있지 않습니다. 해시태그를 팔로우하면, 여기에 표시됩니다.",
|
||||
"empty_column.hashtag": "이 해시태그는 아직 사용되지 않았습니다.",
|
||||
"empty_column.home": "당신의 홈 타임라인은 비어있습니다! 더 많은 사람들을 팔로우 하여 채워보세요. {suggestions}",
|
||||
"empty_column.home": "당신의 홈 타임라인은 비어있습니다! 더 많은 사람들을 팔로우 하여 채워보세요.",
|
||||
"empty_column.list": "리스트에 아직 아무것도 없습니다. 리스트의 누군가가 게시물을 올리면 여기에 나타납니다.",
|
||||
"empty_column.lists": "아직 리스트가 없습니다. 리스트를 만들면 여기에 나타납니다.",
|
||||
"empty_column.mutes": "아직 아무도 뮤트하지 않았습니다.",
|
||||
@ -338,7 +338,7 @@
|
||||
"keyboard_shortcuts.column": "해당 컬럼에 포커스",
|
||||
"keyboard_shortcuts.compose": "작성창에 포커스",
|
||||
"keyboard_shortcuts.description": "설명",
|
||||
"keyboard_shortcuts.direct": "개인적인 멘션 컬럼 열기",
|
||||
"keyboard_shortcuts.direct": "다이렉트 메시지 컬럼 열기",
|
||||
"keyboard_shortcuts.down": "리스트에서 아래로 이동",
|
||||
"keyboard_shortcuts.enter": "게시물 열기",
|
||||
"keyboard_shortcuts.favourite": "게시물 좋아요",
|
||||
@ -401,7 +401,7 @@
|
||||
"navigation_bar.bookmarks": "북마크",
|
||||
"navigation_bar.community_timeline": "로컬 타임라인",
|
||||
"navigation_bar.compose": "새 게시물 작성",
|
||||
"navigation_bar.direct": "개인적인 멘션",
|
||||
"navigation_bar.direct": "다이렉트 메시지",
|
||||
"navigation_bar.discover": "발견하기",
|
||||
"navigation_bar.domain_blocks": "차단한 도메인",
|
||||
"navigation_bar.edit_profile": "프로필 수정",
|
||||
@ -607,7 +607,7 @@
|
||||
"server_banner.about_active_users": "30일 동안 이 서버를 사용한 사람들 (월간 활성 이용자)",
|
||||
"server_banner.active_users": "활성 사용자",
|
||||
"server_banner.administered_by": "관리자:",
|
||||
"server_banner.introduction": "{domain}은 마스토돈으로 운영되는 탈중앙화 된 소셜 네트워크의 일부입니다.",
|
||||
"server_banner.introduction": "마스토돈을 기반으로 운영되는 오리지널 캐릭터 커뮤니티 전용 인스턴스입니다.",
|
||||
"server_banner.learn_more": "더 알아보기",
|
||||
"server_banner.server_stats": "서버 통계:",
|
||||
"sign_in_banner.create_account": "계정 생성",
|
||||
@ -625,7 +625,7 @@
|
||||
"status.delete": "삭제",
|
||||
"status.detailed_status": "대화 자세히 보기",
|
||||
"status.direct": "@{name} 님에게 개인적으로 멘션",
|
||||
"status.direct_indicator": "개인적인 멘션",
|
||||
"status.direct_indicator": "다이렉트 메시지",
|
||||
"status.edit": "수정",
|
||||
"status.edited": "{date}에 수정함",
|
||||
"status.edited_x_times": "{count}번 수정됨",
|
||||
|
2
app/javascript/styles/mastodon-bird-ui-dark-vanilla.scss
Normal file
@ -0,0 +1,2 @@
|
||||
@import 'application';
|
||||
@import 'mastodon-bird-ui-vanilla/layout-single-column.scss';
|
2
app/javascript/styles/mastodon-bird-ui-dark.scss
Normal file
@ -0,0 +1,2 @@
|
||||
@import 'application';
|
||||
@import 'mastodon-bird-ui/layout-single-column.scss';
|
@ -0,0 +1,4 @@
|
||||
@import 'mastodon-light/variables';
|
||||
@import 'application';
|
||||
@import 'mastodon-light/diff';
|
||||
@import 'mastodon-bird-ui-vanilla/layout-single-column.scss';
|
4
app/javascript/styles/mastodon-bird-ui-light.scss
Normal file
@ -0,0 +1,4 @@
|
||||
@import 'mastodon-light/variables';
|
||||
@import 'application';
|
||||
@import 'mastodon-light/diff';
|
||||
@import 'mastodon-bird-ui/layout-single-column.scss';
|
4816
app/javascript/styles/mastodon-bird-ui/layout-multiple-columns.scss
Normal file
4880
app/javascript/styles/mastodon-bird-ui/layout-single-column.scss
Normal file
@ -3,13 +3,13 @@ $black: #000000;
|
||||
$white: #ffffff;
|
||||
|
||||
$classic-base-color: #282c37;
|
||||
$classic-primary-color: #9baec8;
|
||||
$classic-secondary-color: #d9e1e8;
|
||||
$classic-highlight-color: #858afa;
|
||||
$classic-primary-color: #c3b9e0;
|
||||
$classic-secondary-color: #dcdae0;
|
||||
$classic-highlight-color: #675797; // Brand purple
|
||||
|
||||
$blurple-600: #563acc; // Iris
|
||||
$blurple-500: #6364ff; // Brand purple
|
||||
$blurple-300: #858afa; // Faded Blue
|
||||
$blurple-600: #2d2740; // Iris
|
||||
$blurple-500: #423a5d; // Brand purple
|
||||
$blurple-300: #aea7c1; // Faded Blue
|
||||
$grey-600: #4e4c5a; // Trout
|
||||
$grey-100: #dadaf3; // Topaz
|
||||
|
||||
|
@ -3,10 +3,10 @@ $black: #000000; // Black
|
||||
$white: #ffffff; // White
|
||||
$red-600: #b7253d !default; // Deep Carmine
|
||||
$red-500: #df405a !default; // Cerise
|
||||
$blurple-600: #563acc; // Iris
|
||||
$blurple-500: #6364ff; // Brand purple
|
||||
$blurple-400: #7477fd; // Medium slate blue
|
||||
$blurple-300: #858afa; // Faded Blue
|
||||
$blurple-600: #d3a24e; // Iris
|
||||
$blurple-500: #f6cb82; // Brand purple
|
||||
$blurple-400: #fad9a0; // Medium slate blue
|
||||
$blurple-300: #f1e5cf; // Faded Blue
|
||||
$grey-600: #4e4c5a; // Trout
|
||||
$grey-100: #dadaf3; // Topaz
|
||||
|
||||
@ -19,9 +19,9 @@ $red-bookmark: $warning-red;
|
||||
|
||||
// Values from the classic Mastodon UI
|
||||
$classic-base-color: #282c37; // Midnight Express
|
||||
$classic-primary-color: #9baec8; // Echo Blue
|
||||
$classic-secondary-color: #d9e1e8; // Pattens Blue
|
||||
$classic-highlight-color: #6364ff; // Brand purple
|
||||
$classic-primary-color: #f9ddac;
|
||||
$classic-secondary-color: #fff7ea;
|
||||
$classic-highlight-color: #f6cb82; // Brand purple
|
||||
|
||||
// Variables for defaults in UI
|
||||
$base-shadow-color: $black !default;
|
||||
@ -60,7 +60,7 @@ $ui-button-destructive-background-color: $red-500 !default;
|
||||
$ui-button-destructive-focus-background-color: $red-600 !default;
|
||||
|
||||
$ui-button-icon-focus-outline: $ui-button-focus-outline !default;
|
||||
$ui-button-icon-hover-background-color: rgba(140, 141, 255, 40%) !default;
|
||||
$ui-button-icon-hover-background-color: #78718c !default;
|
||||
|
||||
// Variables for texts
|
||||
$primary-text-color: $white !default;
|
||||
|
@ -20,12 +20,7 @@
|
||||
#{t 'appearance.localization.body'} #{content_tag(:a, t('appearance.localization.guide_link_text'), href: t('appearance.localization.guide_link'), target: '_blank', rel: 'noopener')}
|
||||
|
||||
= f.simple_fields_for :settings, current_user.settings do |ff|
|
||||
%h4= t 'appearance.advanced_web_interface'
|
||||
|
||||
%p.hint= t 'appearance.advanced_web_interface_hint'
|
||||
|
||||
.fields-group
|
||||
= ff.input :'web.advanced_layout', wrapper: :with_label, hint: false, label: I18n.t('simple_form.labels.defaults.setting_advanced_layout')
|
||||
%h4= t 'appearance.animations_and_accessibility'
|
||||
|
||||
.fields-group
|
||||
|
@ -70,7 +70,7 @@ class Rack::Attack
|
||||
req.authenticated_user_id if req.api_request?
|
||||
end
|
||||
|
||||
throttle('throttle_per_token_api', limit: 300, period: 5.minutes) do |req|
|
||||
throttle('throttle_per_token_api', limit: 3000, period: 5.minutes) do |req|
|
||||
req.authenticated_token_id if req.api_request?
|
||||
end
|
||||
|
||||
|
@ -1730,10 +1730,13 @@ en:
|
||||
too_late: It is too late to appeal this strike
|
||||
tags:
|
||||
does_not_match_previous_name: does not match the previous name
|
||||
themes:
|
||||
contrast: Mastodon (High contrast)
|
||||
default: Mastodon (Dark)
|
||||
mastodon-light: Mastodon (Light)
|
||||
contrast: Mastodon (High contrast)
|
||||
default: Mastodon Bird UI (Dark)
|
||||
mastodon-bird-ui-light: Mastodon Bird UI (Light)
|
||||
mastodon-light: Mastodon (Light)
|
||||
mastodon-dark: Mastodon (Dark)
|
||||
mastodon-bird-ui-light-vanilla: Mastodon Bird UI - vanila (Light)
|
||||
mastodon-bird-ui-dark-vanilla: Mastodon Bird UI - vanila (dark)
|
||||
time:
|
||||
formats:
|
||||
default: "%b %d, %Y, %H:%M"
|
||||
|
@ -1701,8 +1701,12 @@ ko:
|
||||
does_not_match_previous_name: 이전 이름과 맞지 않습니다
|
||||
themes:
|
||||
contrast: 마스토돈 (고대비)
|
||||
default: 마스토돈 (어두움)
|
||||
default: 23.4 ~Ad Astra~ 테마 (비일상)
|
||||
mastodon-bird-ui-light: 23.4 ~Ad Astra~ 테마 (일상)
|
||||
mastodon-light: 마스토돈 (밝음)
|
||||
mastodon-dark: 마스토돈 (어두움)
|
||||
mastodon-bird-ui-light-vanilla: 파란새풍 테마 (밝음)
|
||||
mastodon-bird-ui-dark-vanilla: 파란새풍 테마 (어두움)
|
||||
time:
|
||||
formats:
|
||||
default: "%Y-%m-%d %H:%M"
|
||||
|
@ -1,3 +1,7 @@
|
||||
default: styles/application.scss
|
||||
contrast: styles/contrast.scss
|
||||
default: styles/mastodon-bird-ui-dark.scss
|
||||
mastodon-bird-ui-light: styles/mastodon-bird-ui-light.scss
|
||||
mastodon-dark: styles/application.scss
|
||||
mastodon-light: styles/mastodon-light.scss
|
||||
contrast: styles/contrast.scss
|
||||
mastodon-bird-ui-light-vanilla: styles/mastodon-bird-ui-light-vanilla.scss
|
||||
mastodon-bird-ui-dark-vanilla: styles/mastodon-bird-ui-dark-vanilla.scss
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
public/oops.gif
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 138 KiB |
BIN
public/oops.png
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 83 KiB |