fix/activitpub, theme color
This commit is contained in:
parent
0929cc092e
commit
1bb3073dd4
134
README.md
134
README.md
@ -1,136 +1,84 @@
|
||||
<h1><picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./lib/assets/wordmark.dark.png?raw=true">
|
||||
<source media="(prefers-color-scheme: light)" srcset="./lib/assets/wordmark.light.png?raw=true">
|
||||
<img alt="Whippy Edition" src="./lib/assets/wordmark.light.png?raw=true" height="100">
|
||||
<img alt="Whippy Edition" src="./lib/assets/wordmark.light.png" height="100">
|
||||
</picture></h1>
|
||||
|
||||
[![GitHub release](https://img.shields.io/github/release/whippyshou/mastodon.svg)][releases]
|
||||
[![Ruby Testing](https://github.com/mastodon/mastodon/actions/workflows/test-ruby.yml/badge.svg)](https://github.com/mastodon/mastodon/actions/workflows/test-ruby.yml)
|
||||
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin]
|
||||
|
||||
[releases]: https://github.com/mastodon/mastodon/releases
|
||||
[crowdin]: https://crowdin.com/project/mastodon
|
||||
[releases]: https://github.com/whippyshou/mastodon/releases
|
||||
|
||||
Mastodon is a **free, open-source social network server** based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, and video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub!)
|
||||
|
||||
Click below to **learn more** in a video:
|
||||
**휘핑 에디션**은 **오리지널 캐릭터의 교류**를 목적으로 하는 **커뮤니티**를 위해 제공되는 오픈소스 네트워크 미디어 소프트웨어입니다. 휘핑 에디션은 Mastodon gGmbH에서 제공하는 오픈소스 소프트웨어인 Mastodon에서 파생되었으며 자유로운 수정 및 복제, 사용이 가능합니다.
|
||||
|
||||
[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo]
|
||||
|
||||
[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
|
||||
<img alt="Whippy Edition" src="./lib/assets/preview.png">
|
||||
|
||||
## Navigation
|
||||
|
||||
- [Project homepage 🐘](https://joinmastodon.org)
|
||||
- [Support the development via Patreon][patreon]
|
||||
- [View sponsors](https://joinmastodon.org/sponsors)
|
||||
- [Blog](https://blog.joinmastodon.org)
|
||||
- [Documentation](https://docs.joinmastodon.org)
|
||||
- [Roadmap](https://joinmastodon.org/roadmap)
|
||||
- [Official Docker image](https://github.com/mastodon/mastodon/pkgs/container/mastodon)
|
||||
- [Browse Mastodon servers](https://joinmastodon.org/communities)
|
||||
- [Browse Mastodon apps](https://joinmastodon.org/apps)
|
||||
- [마스토돈 프로젝트 홈페이지 🐘](https://joinmastodon.org)
|
||||
- [CAFE : WHIPPY CREAM <img alt="Whippy Edition" src="./lib/assets/Postype_Symbol-1.svg?raw=true" height="20"> ][postype]
|
||||
- [Mastodon with modern birdsite-like UI 🐦](https://github.com/ronilaukkarinen/mastodon-bird-ui/)
|
||||
|
||||
[patreon]: https://www.patreon.com/mastodon
|
||||
[postype]:https://www.postype.com/15635470
|
||||
|
||||
## Features
|
||||
위의 링크에서 **휘핑 에디션**에 대한 좀 더 자세한 내용을 확인하실 수 있습니다.
|
||||
|
||||
<img src="/app/javascript/images/elephant_ui_working.svg?raw=true" align="right" width="30%" />
|
||||
## Feature
|
||||
|
||||
### No vendor lock-in: Fully interoperable with any conforming platform
|
||||
마스토돈과 차별화되는 **휘핑에디션**의 특징은 크게 세가지로 나누어집니다.
|
||||
|
||||
It doesn't have to be Mastodon; whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/)
|
||||
|
||||
### Real-time, chronological timeline updates
|
||||
#### 다이렉트 메시지(개인적인 멘션)의 타임라인 및 알림 분리
|
||||
캐릭터 커뮤니티에서는 일반 툿과 DM의 용도가 분리되어 있습니다. 그렇기 때문에 DM과 일반 게시글이 혼재되어있는 타임라인과 알림창은 사용자에게 혼란을 야기할 수 있습니다.
|
||||
|
||||
Updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!
|
||||
휘핑 에디션에서는 홈 타임라인과 계정 프로필에 DM이 필터링되어 나타나지 않습니다. 또한 알림창의 탭에 일반 멘션과 DM을 분리해 사용자는 필요에 따라 일반 멘션/DM 알림을 나누어 확인할 수 있습니다.
|
||||
|
||||
### Media attachments like images and short videos
|
||||
#### 방문자(외부인)의 접근 차단
|
||||
캐릭터 커뮤니티는 폐쇄적인 성향을 띱니다. 대부분의 사용자는 자신의 게시물이 허가되지 않은 타인에게 노출되는 것을 꺼려합니다.
|
||||
|
||||
Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos loop continuously!
|
||||
휘핑 에디션 인스턴스에 올라오는 모든 게시물은 비등재(이하 ‘로컬’)/팔로워 공개로 게시되며, 타 서버의 퍼블릭 타임라인/타 도메인의 팔로워의 타임라인에 노출되지 않습니다.
|
||||
|
||||
### Safety and moderation tools
|
||||
또한 사이트 방문자에게 계정의 게시물을 노출하지 않습니다. 휘핑 에디션의 모든 게시글들은 인스턴스의 가입자만이 접근할 수 있습니다.
|
||||
|
||||
Mastodon includes private posts, locked accounts, phrase filtering, muting, blocking, and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/)
|
||||
|
||||
### OAuth2 and a straightforward REST API
|
||||
#### 커뮤니티에 적합한 UI 개선
|
||||
|
||||
사용자간의 원활한 교류를 지원하기 위해 여러가지 추가 기능 및 편의성 패치를 진행하였습니다.
|
||||
- 커뮤니티의 테마에 맞춰 사이트의 테마 커스텀 가능
|
||||
- 관리자의 타 계정간의 DM 확인 기능 추가
|
||||
- 사이트 내 도메인 노출 최소화
|
||||
- 계정의 표시 이름 강조
|
||||
- 게시글의 공개 범위와 관계없이 답글 갯수 표시
|
||||
- 타임라인에 노출되는 미디어 썸네일의 최대 높이 제한
|
||||
- 계정의 미디어 모아보기 타임라인 썸네일 클릭시 해당 게시글 타래로 이동
|
||||
- 게시글의 공개 범위와 관계없이 방문자에게 계정의 바이오를 포함한 계정 게시글 비공개
|
||||
|
||||
그 외에 자잘한 UI의 개선이 있습니다.
|
||||
|
||||
Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Streaming APIs. This results in a rich app ecosystem with a lot of choices!
|
||||
|
||||
## Deployment
|
||||
|
||||
### Tech stack
|
||||
|
||||
- **Ruby on Rails** powers the REST API and other web pages
|
||||
- **React.js** and Redux are used for the dynamic parts of the interface
|
||||
- **Node.js** powers the streaming API
|
||||
- **Ruby on Rails** 는 REST API and 기타 웹페이지를 구동합니다.
|
||||
- **React.js** 와 Redux는 인터페이스의 동적 파트에 사용됩니다.
|
||||
- **Node.js** 는 streaming API를 구동합니다.
|
||||
|
||||
### Requirements
|
||||
|
||||
- **PostgreSQL** 9.5+
|
||||
- **Redis** 4+
|
||||
- **Ruby** 2.7+
|
||||
- **Node.js** 14+
|
||||
- **PostgreSQL** 12.16
|
||||
- **Redis** 5.0.7
|
||||
- **Ruby** 3.2.2
|
||||
- **Node.js** 16.20.2
|
||||
|
||||
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
|
||||
기입되어있는 버전은 휘핑 에디션 설치 당시의 버전으로, 휘핑 에디션은 2023년 10월 11일 릴리즈된 마스토돈 v4.2.1을 기반으로 합니다. 자세한 내용은 [마스토돈 홈페이지 설치 가이드](https://docs.joinmastodon.org/admin/install/)를 참고해주세요.
|
||||
|
||||
## Development
|
||||
|
||||
### Vagrant
|
||||
|
||||
A **Vagrant** configuration is included for development purposes. To use it, complete the following steps:
|
||||
|
||||
- Install Vagrant and Virtualbox
|
||||
- Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater`
|
||||
- Run `vagrant up`
|
||||
- Run `vagrant ssh -c "cd /vagrant && foreman start"`
|
||||
- Open `http://mastodon.local` in your browser
|
||||
|
||||
### MacOS
|
||||
|
||||
To set up **MacOS** for native development, complete the following steps:
|
||||
|
||||
- Install the latest stable Ruby version (use a Ruby version manager for easy installation and management of Ruby versions)
|
||||
- Run `brew install postgresql@14`
|
||||
- Run `brew install redis`
|
||||
- Run `brew install imagemagick`
|
||||
- Install Foreman or a similar tool (such as [overmind](https://github.com/DarthSim/overmind)) to handle multiple process launching.
|
||||
- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from .nvmrc
|
||||
- Run `corepack enable && yarn set version classic`
|
||||
- Run `bundle exec rails db:setup` (optionally prepend `RAILS_ENV=development` to target the dev environment)
|
||||
- Finally, run `overmind start -f Procfile.dev`
|
||||
|
||||
### Docker
|
||||
|
||||
For development with **Docker**, complete the following steps:
|
||||
|
||||
- Install Docker Desktop
|
||||
- Run `docker compose -f .devcontainer/docker-compose.yml up -d`
|
||||
- Run `docker compose -f .devcontainer/docker-compose.yml exec app .devcontainer/post-create.sh`
|
||||
- Finally, run `docker compose -f .devcontainer/docker-compose.yml exec app foreman start -f Procfile.dev`
|
||||
|
||||
If you are using an IDE with [support for the Development Container specification](https://containers.dev/supporting), it will run the above `docker compose` commands automatically. For **Visual Studio Code** this requires the [Dev Container extension](https://containers.dev/supporting#dev-containers).
|
||||
|
||||
### GitHub Codespaces
|
||||
|
||||
To get you coding in just a few minutes, GitHub Codespaces provides a web-based version of Visual Studio Code and a cloud-hosted development environment fully configured with the software needed for this project..
|
||||
|
||||
- Click this button to create a new codespace:<br>
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json)
|
||||
- Wait for the environment to build. This will take a few minutes.
|
||||
- When the editor is ready, run `foreman start -f Procfile.dev` in the terminal.
|
||||
- After a few seconds, a popup will appear with a button labeled _Open in Browser_. This will open Mastodon.
|
||||
- On the _Ports_ tab, right click on the “stream” row and select _Port visibility_ → _Public_.
|
||||
|
||||
## Contributing
|
||||
|
||||
Mastodon is **free, open-source software** licensed under **AGPLv3**.
|
||||
**휘핑에디션**의 기반이 되는 마스토돈은 **AGPLv3** 라이선스가 부여된 **프리 오픈소스 소프트웨어**입니다. 자유롭게 버그의 수정, 혹은 기능의 추가 및 제거가 가능합니다. 단, 모든 소스코드는 네트워크상의 사용자에게 무료로 공개, 제공되어야 하며 휘핑 에디션 또한 하단의 **AGPLv3** 라이선스를 따릅니다.
|
||||
|
||||
You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository or submit translations using Crowdin. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
|
||||
|
||||
**IRC channel**: #mastodon on irc.libera.chat
|
||||
|
||||
## License
|
||||
## Lisence
|
||||
|
||||
Copyright (C) 2016-2023 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md))
|
||||
|
||||
|
@ -9,7 +9,7 @@ class Api::V1::Statuses::PinsController < Api::BaseController
|
||||
|
||||
def create
|
||||
StatusPin.create!(account: current_account, status: @status)
|
||||
distribute_add_activity!
|
||||
#distribute_add_activity!
|
||||
render json: @status, serializer: REST::StatusSerializer
|
||||
end
|
||||
|
||||
@ -18,7 +18,7 @@ class Api::V1::Statuses::PinsController < Api::BaseController
|
||||
|
||||
if pin
|
||||
pin.destroy!
|
||||
distribute_remove_activity!
|
||||
#distribute_remove_activity!
|
||||
end
|
||||
|
||||
render json: @status, serializer: REST::StatusSerializer
|
||||
|
@ -111,6 +111,7 @@ class DropdownMenu extends PureComponent {
|
||||
};
|
||||
|
||||
handleClick = e => {
|
||||
e.stopPropagation();
|
||||
const { onItemClick } = this.props;
|
||||
onItemClick(e);
|
||||
};
|
||||
|
@ -251,12 +251,13 @@ class MediaGallery extends PureComponent {
|
||||
trailing: true,
|
||||
});
|
||||
|
||||
handleOpen = () => {
|
||||
handleOpen = e => {
|
||||
if (this.props.onToggleVisibility) {
|
||||
this.props.onToggleVisibility();
|
||||
} else {
|
||||
this.setState({ visible: !this.state.visible });
|
||||
}
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
handleClick = (index) => {
|
||||
|
@ -15,9 +15,10 @@ class PictureInPicturePlaceholder extends PureComponent {
|
||||
aspectRatio: PropTypes.string,
|
||||
};
|
||||
|
||||
handleClick = () => {
|
||||
handleClick = e => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch(removePictureInPicture());
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
render () {
|
||||
|
@ -434,6 +434,8 @@ class Header extends ImmutablePureComponent {
|
||||
|
||||
{!(suspended || hidden) && (
|
||||
<div className='account__header__extra'>
|
||||
|
||||
{(signedIn) &&(
|
||||
<div className='account__header__bio' ref={this.setRef}>
|
||||
{(account.get('id') !== me && signedIn) && <AccountNoteContainer account={account} />}
|
||||
|
||||
@ -441,8 +443,8 @@ class Header extends ImmutablePureComponent {
|
||||
|
||||
<div className='account__header__fields'>
|
||||
<dl>
|
||||
<dt><FormattedMessage id='account.joined_short' defaultMessage='Joined' /></dt>
|
||||
<dd>{intl.formatDate(account.get('created_at'), { year: 'numeric', month: 'short', day: '2-digit' })}</dd>
|
||||
{/* <dt><FormattedMessage id='account.joined_short' defaultMessage='Joined' /></dt>
|
||||
<dd>{intl.formatDate(account.get('created_at'), { year: 'numeric', month: 'short', day: '2-digit' })}</dd> */}
|
||||
</dl>
|
||||
|
||||
{fields.map((pair, i) => (
|
||||
@ -456,6 +458,8 @@ class Header extends ImmutablePureComponent {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<div className='account__header__extra__links'>
|
||||
<NavLink isActive={this.isStatusesPageActive} activeClassName='active' to={`/@${account.get('acct')}`} title={intl.formatNumber(account.get('statuses_count'))}>
|
||||
|
@ -158,6 +158,22 @@ class Audio extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
toggleClickPlay = e => {
|
||||
|
||||
e.stopPropagation();
|
||||
|
||||
if (!this.audioContext) {
|
||||
this._initAudioContext();
|
||||
}
|
||||
|
||||
if (this.state.paused) {
|
||||
this.setState({ paused: false }, () => this.audio.play());
|
||||
} else {
|
||||
this.setState({ paused: true }, () => this.audio.pause());
|
||||
}
|
||||
};
|
||||
|
||||
togglePlay = () => {
|
||||
if (!this.audioContext) {
|
||||
this._initAudioContext();
|
||||
@ -204,7 +220,11 @@ class Audio extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
toggleMute = () => {
|
||||
toggleMute = e => {
|
||||
|
||||
e.stopPropagation();
|
||||
|
||||
|
||||
const muted = !(this.state.muted || this.state.volume === 0);
|
||||
|
||||
this.setState((state) => ({ muted, volume: Math.max(state.volume || 0.5, 0.05) }), () => {
|
||||
@ -214,7 +234,9 @@ class Audio extends PureComponent {
|
||||
});
|
||||
};
|
||||
|
||||
toggleReveal = () => {
|
||||
toggleReveal = e => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (this.props.onToggleVisibility) {
|
||||
this.props.onToggleVisibility();
|
||||
} else {
|
||||
@ -222,6 +244,10 @@ class Audio extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
handleStopEvent = e => {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
handleVolumeMouseDown = e => {
|
||||
document.addEventListener('mousemove', this.handleMouseVolSlide, true);
|
||||
document.addEventListener('mouseup', this.handleVolumeMouseUp, true);
|
||||
@ -234,11 +260,12 @@ class Audio extends PureComponent {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
handleVolumeMouseUp = () => {
|
||||
handleVolumeMouseUp = e=> {
|
||||
document.removeEventListener('mousemove', this.handleMouseVolSlide, true);
|
||||
document.removeEventListener('mouseup', this.handleVolumeMouseUp, true);
|
||||
document.removeEventListener('touchmove', this.handleMouseVolSlide, true);
|
||||
document.removeEventListener('touchend', this.handleVolumeMouseUp, true);
|
||||
|
||||
};
|
||||
|
||||
handleMouseDown = e => {
|
||||
@ -255,7 +282,7 @@ class Audio extends PureComponent {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
handleMouseUp = () => {
|
||||
handleMouseUp = e => {
|
||||
document.removeEventListener('mousemove', this.handleMouseMove, true);
|
||||
document.removeEventListener('mouseup', this.handleMouseUp, true);
|
||||
document.removeEventListener('touchmove', this.handleMouseMove, true);
|
||||
@ -314,12 +341,16 @@ class Audio extends PureComponent {
|
||||
}
|
||||
}, 150, { trailing: true });
|
||||
|
||||
handleMouseEnter = () => {
|
||||
handleMouseEnter = e => {
|
||||
this.setState({ hovered: true });
|
||||
e.stopPropagation();
|
||||
|
||||
};
|
||||
|
||||
handleMouseLeave = () => {
|
||||
handleMouseLeave = e => {
|
||||
this.setState({ hovered: false });
|
||||
e.stopPropagation();
|
||||
|
||||
};
|
||||
|
||||
handleLoadedData = () => {
|
||||
@ -432,6 +463,8 @@ class Audio extends PureComponent {
|
||||
// On the audio element or the seek bar, we can safely use the space bar
|
||||
// for playback control because there are no buttons to press
|
||||
|
||||
e.stopPropagation();
|
||||
|
||||
if (e.key === ' ') {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -506,9 +539,9 @@ class Audio extends PureComponent {
|
||||
className='audio-player__canvas'
|
||||
width={this.state.width}
|
||||
height={this.state.height}
|
||||
style={{ width: '100%', position: 'absolute', top: 0, left: 0 }}
|
||||
style={{ width: '100%', position: 'absolute', top: 0, left: 0, cursor:'pointer'}}
|
||||
ref={this.setCanvasRef}
|
||||
onClick={this.togglePlay}
|
||||
onClick={this.toggleClickPlay}
|
||||
onKeyDown={this.handleAudioKeyDown}
|
||||
title={alt}
|
||||
aria-label={alt}
|
||||
@ -539,7 +572,7 @@ class Audio extends PureComponent {
|
||||
}}
|
||||
/>}
|
||||
|
||||
<div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
|
||||
<div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef} onClick = {this.handleStopEvent}>
|
||||
<div className='video-player__seek__buffer' style={{ width: `${buffer}%` }} />
|
||||
<div className='video-player__seek__progress' style={{ width: `${progress}%`, backgroundColor: this._getAccentColor() }} />
|
||||
|
||||
@ -552,12 +585,12 @@ class Audio extends PureComponent {
|
||||
</div>
|
||||
|
||||
<div className='video-player__controls active'>
|
||||
<div className='video-player__buttons-bar'>
|
||||
<div className='video-player__buttons-bar' onClick = {this.handleStopEvent} >
|
||||
<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(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.toggleClickPlay}><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 ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className={classNames('video-player__volume', { active: this.state.hovered })} ref={this.setVolumeRef} onMouseDown={this.handleVolumeMouseDown}>
|
||||
<div className={classNames('video-player__volume', { active: this.state.hovered })} ref={this.setVolumeRef} onClick = {this.handleStopEvent} onMouseDown={this.handleVolumeMouseDown}>
|
||||
<div className='video-player__volume__current' style={{ width: `${muted ? 0 : volume * 100}%`, backgroundColor: this._getAccentColor() }} />
|
||||
|
||||
<span
|
||||
|
@ -177,7 +177,7 @@ class HomeTimeline extends PureComponent {
|
||||
scrollKey={`home_timeline-${columnId}`}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
timelineId='home'
|
||||
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Follow more people to fill it up.' />}
|
||||
emptyMessage={<FormattedMessage id='empty_column.local' defaultMessage='Your home timeline is empty! Follow more people to fill it up.' />}
|
||||
bindToDocument={!multiColumn}
|
||||
/>
|
||||
) : <NotSignedInIndicator />}
|
||||
|
@ -85,7 +85,8 @@ export default class Card extends PureComponent {
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
}
|
||||
|
||||
handleEmbedClick = () => {
|
||||
handleEmbedClick = e => {
|
||||
e.stopPropagation();
|
||||
this.setState({ embedded: true });
|
||||
};
|
||||
|
||||
|
@ -640,6 +640,8 @@ class Status extends ImmutablePureComponent {
|
||||
let ancestors, descendants;
|
||||
const { isLoading, status, ancestorsIds, descendantsIds, intl, domain, multiColumn, pictureInPicture } = this.props;
|
||||
const { fullscreen } = this.state;
|
||||
const { signedIn } = this.context.identity;
|
||||
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@ -649,7 +651,7 @@ class Status extends ImmutablePureComponent {
|
||||
);
|
||||
}
|
||||
|
||||
if (status === null) {
|
||||
if (status === null || !signedIn ) {
|
||||
return (
|
||||
<BundleColumnError multiColumn={multiColumn} errorType='routing' />
|
||||
);
|
||||
|
@ -200,8 +200,8 @@ class SwitchingColumnsArea extends PureComponent {
|
||||
{/* <Redirect from='/timelines/public' to='/public' exact />
|
||||
<Redirect from='/timelines/public/local' to='/public/local' exact />
|
||||
<WrappedRoute path='/public' exact component={Firehose} componentParams={{ feedType: 'public' }} content={children} />
|
||||
<WrappedRoute path='/public/local' exact component={Firehose} componentParams={{ feedType: 'community' }} content={children} />
|
||||
*/}
|
||||
<WrappedRoute path='/public/local' exact component={Firehose} componentParams={{ feedType: 'community' }} content={children} /> */}
|
||||
|
||||
<Redirect from='/timelines/local' to='/local' exact />
|
||||
<WrappedRoute path='/local' exact component={LocalTimeline} content={children} />
|
||||
|
||||
@ -217,7 +217,7 @@ class SwitchingColumnsArea extends PureComponent {
|
||||
|
||||
<WrappedRoute path='/start' exact component={Onboarding} content={children} />
|
||||
{/* <WrappedRoute path='/directory' component={Directory} content={children} /> */}
|
||||
{/* <WrappedRoute path={['/explore', '/search']} component={Explore} content={children} /> */}
|
||||
<WrappedRoute path={['/search']} component={Explore} content={children} />
|
||||
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
||||
|
||||
<WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} />
|
||||
|
@ -197,6 +197,8 @@ body.theme-bird-ui-contrast.layout-multiple-columns {
|
||||
/* Light theme */
|
||||
body.theme-bird-ui-light.layout-multiple-columns {
|
||||
|
||||
--active-header-radial-gradient: radial-gradient(ellipse,rgb(239, 154, 154 / 25%) 0,rgb(255, 0 ,81 / 0%) 60%);
|
||||
|
||||
--color-brand-mastodon: #be2a4d;
|
||||
--color-brand-mastodon-links: #df98a2;
|
||||
--color-accent-dark-50: #be2a4d80;
|
||||
@ -217,10 +219,12 @@ body.theme-bird-ui-light.layout-multiple-columns {
|
||||
--color-light-shade: #00000005;
|
||||
--color-focusable-toot: rgba(0, 0, 0, 0.035);
|
||||
--color-light-shade: #db9e9e12;
|
||||
--color-mud: #f8e8ec;
|
||||
|
||||
--color-mud: #f0dee2;
|
||||
|
||||
--color-black-coral: #9188a6;
|
||||
--color-profile-button-hover: #1e1b231a;
|
||||
--color-column-link-hover: #1e1b231a;
|
||||
--color-profile-button-hover: #db9e9e40;
|
||||
--color-column-link-hover: #db9e9e40;
|
||||
--color-modal-overlay: #6a5b8366;
|
||||
--color-dark: #f7f9f9;
|
||||
--color-thread-line: #e1e8ed;
|
||||
@ -4809,3 +4813,11 @@ div[tabindex="-1"] + div[tabindex="-1"] > .status__wrapper > .status-reply.statu
|
||||
* Star animation micro-interactions end
|
||||
* -------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
.layout-single-column .picture-in-picture .video-player,
|
||||
.layout-single-column .picture-in-picture .audio-player
|
||||
{
|
||||
border-radius: unset;
|
||||
}
|
||||
|
@ -216,6 +216,10 @@ body.theme-bird-ui-contrast.layout-single-column {
|
||||
/* Light theme */
|
||||
body.theme-bird-ui-light.layout-single-column {
|
||||
|
||||
|
||||
--active-header-radial-gradient: radial-gradient(ellipse,rgb(239, 154, 154 / 25%) 0,rgb(255, 0 ,81 / 0%) 60%);
|
||||
|
||||
|
||||
--color-brand-mastodon: #be2a4d;
|
||||
--color-brand-mastodon-links: #df98a2;
|
||||
--color-accent-dark-50: #be2a4d80;
|
||||
@ -223,11 +227,13 @@ body.theme-bird-ui-light.layout-single-column {
|
||||
--color-accent:#df98a2;
|
||||
--color-accent-dark: #be2a4d;
|
||||
|
||||
|
||||
--color-bg: #fff;
|
||||
--color-fg: #000;
|
||||
|
||||
--color-border: #e9dee0;
|
||||
--color-dim: #c16c80;
|
||||
|
||||
|
||||
--color-green: #17bf63;
|
||||
--color-red: #e0245e;
|
||||
@ -238,11 +244,13 @@ body.theme-bird-ui-light.layout-single-column {
|
||||
--color-focusable-toot: rgba(0, 0, 0, 0.035);
|
||||
--color-light-text: #1f1b23;
|
||||
|
||||
--color-mud: #f8e8ec;
|
||||
--color-mud: #f0dee2;
|
||||
|
||||
--color-black-coral: #9188a6;
|
||||
--color-profile-button-hover: #1e1b231a;
|
||||
--color-column-link-hover: #1e1b231a;
|
||||
|
||||
--color-profile-button-hover: #db9e9e40;
|
||||
--color-column-link-hover: #db9e9e40;
|
||||
|
||||
--color-modal-overlay: #6a5b8366;
|
||||
--color-dark: #f7f9f9;
|
||||
--color-thread-line: #e1e8ed;
|
||||
@ -4834,6 +4842,13 @@ div[tabindex="-1"] + div[tabindex="-1"] > .status__wrapper > .status-reply.statu
|
||||
}
|
||||
}
|
||||
|
||||
.layout-single-column .picture-in-picture .video-player,
|
||||
.layout-single-column .picture-in-picture .audio-player
|
||||
{
|
||||
border-radius: unset;
|
||||
}
|
||||
|
||||
|
||||
/* stylelint-enable no-duplicate-selectors */
|
||||
/*
|
||||
* Star animation micro-interactions end
|
||||
|
@ -5,7 +5,7 @@ $white: #ffffff;
|
||||
$red-600: #b7253d; // Deep Carmine
|
||||
$red-500: #df405a; // Cerise
|
||||
|
||||
$classic-base-color: #282c37;
|
||||
$classic-base-color: #372831;
|
||||
$classic-primary-color: #9baec8;
|
||||
$classic-secondary-color: #d9e1e8;
|
||||
$classic-highlight-color: #cf647d;
|
||||
|
@ -10,7 +10,9 @@
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.batch-table__row .media-gallery{
|
||||
max-height: 500px;
|
||||
}
|
||||
.inline-alert {
|
||||
color: $valid-value-color;
|
||||
font-weight: 400;
|
||||
|
@ -204,8 +204,10 @@ body.theme-theme-ui-contrast.layout-multiple-columns {
|
||||
}
|
||||
|
||||
/* Light theme */
|
||||
body.theme-theme-ui-light.layout-multiple-columns {
|
||||
|
||||
body.theme-default.layout-multiple-columns {
|
||||
|
||||
--active-header-radial-gradient: radial-gradient(ellipse,rgb(239, 154, 154 / 25%) 0,rgb(255, 0 ,81 / 0%) 60%);
|
||||
|
||||
--bg-image : url('../images/theme/bg_light.png');
|
||||
--logo: url('../images/theme/wordmark_light.png');
|
||||
--m-logo: url('../images/theme/m_logo_light.png');
|
||||
@ -231,11 +233,15 @@ body.theme-theme-ui-light.layout-multiple-columns {
|
||||
--color-red: #e0245e;
|
||||
--color-red-75: #e0245ebf;
|
||||
--color-focusable-toot: rgba(0, 0, 0, 0.035);
|
||||
|
||||
--color-light-shade: #db9e9e12;
|
||||
--color-mud: #f8e8ec;
|
||||
--color-mud: #f0dee2;
|
||||
|
||||
--color-black-coral: #9188a6;
|
||||
--color-profile-button-hover: #1e1b231a;
|
||||
--color-column-link-hover: #1e1b231a;
|
||||
|
||||
--color-profile-button-hover: #db9e9e40;
|
||||
--color-column-link-hover: #db9e9e40;
|
||||
|
||||
--color-modal-overlay: #6a5b8366;
|
||||
--color-dark: #f7f9f9;
|
||||
--color-thread-line: #e1e8ed;
|
||||
@ -4837,3 +4843,9 @@ div[tabindex="-1"] + div[tabindex="-1"] > .status__wrapper > .status-reply.statu
|
||||
* Star animation micro-interactions end
|
||||
* -------------------------------------
|
||||
*/
|
||||
.layout-single-column .picture-in-picture .video-player,
|
||||
.layout-single-column .picture-in-picture .audio-player
|
||||
{
|
||||
border-radius: unset;
|
||||
}
|
||||
|
@ -223,7 +223,9 @@ body.theme-theme-ui-contrast.layout-single-column {
|
||||
}
|
||||
|
||||
/* Light theme */
|
||||
body.theme-theme-ui-light.layout-single-column {
|
||||
body.theme-default.layout-single-column {
|
||||
|
||||
--active-header-radial-gradient: radial-gradient(ellipse,rgb(239, 154, 154 / 25%) 0,rgb(255, 0 ,81 / 0%) 60%);
|
||||
|
||||
--bg-image : url('../images/theme/bg_light.png');
|
||||
--logo: url('../images/theme/wordmark_light.png');
|
||||
@ -252,11 +254,13 @@ body.theme-theme-ui-light.layout-single-column {
|
||||
--color-focusable-toot: rgba(0, 0, 0, 0.035);
|
||||
--color-light-text: #1f1b23;
|
||||
|
||||
--color-mud: #f8e8ec;
|
||||
--color-mud: #f0dee2;
|
||||
|
||||
--color-black-coral: #9188a6;
|
||||
--color-profile-button-hover: #1e1b231a;
|
||||
--color-column-link-hover: #1e1b231a;
|
||||
|
||||
--color-profile-button-hover: #db9e9e40;
|
||||
--color-column-link-hover: #db9e9e40;
|
||||
|
||||
--color-modal-overlay: #6a5b8366;
|
||||
--color-dark: #f7f9f9;
|
||||
--color-thread-line: #e1e8ed;
|
||||
@ -4892,3 +4896,10 @@ div[tabindex="-1"] + div[tabindex="-1"] > .status__wrapper > .status-reply.statu
|
||||
* Star animation micro-interactions end
|
||||
* -------------------------------------
|
||||
*/
|
||||
|
||||
.layout-single-column .picture-in-picture .video-player,
|
||||
.layout-single-column .picture-in-picture .audio-player
|
||||
{
|
||||
border-radius: unset;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ class PostStatusService < BaseService
|
||||
Trends.tags.register(@status)
|
||||
LinkCrawlWorker.perform_async(@status.id)
|
||||
DistributionWorker.perform_async(@status.id)
|
||||
ActivityPub::DistributionWorker.perform_async(@status.id)
|
||||
#ActivityPub::DistributionWorker.perform_async(@status.id)
|
||||
PollExpirationNotifyWorker.perform_at(@status.poll.expires_at, @status.poll.id) if @status.poll
|
||||
end
|
||||
|
||||
|
@ -30,7 +30,7 @@ class ReblogService < BaseService
|
||||
|
||||
Trends.register!(reblog)
|
||||
DistributionWorker.perform_async(reblog.id)
|
||||
ActivityPub::DistributionWorker.perform_async(reblog.id)
|
||||
#ActivityPub::DistributionWorker.perform_async(reblog.id)
|
||||
|
||||
create_notification(reblog)
|
||||
bump_potential_friendship(account, reblog)
|
||||
|
@ -134,7 +134,7 @@ class UpdateStatusService < BaseService
|
||||
|
||||
def broadcast_updates!
|
||||
DistributionWorker.perform_async(@status.id, { 'update' => true })
|
||||
ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id)
|
||||
#ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id)
|
||||
end
|
||||
|
||||
def queue_poll_notifications!
|
||||
|
@ -1737,7 +1737,7 @@ en:
|
||||
bird-ui-dark: Mastodon Bird UI (dark)
|
||||
mastodon-light: Mastodon (Light)
|
||||
mastodon-dark: Mastodon (Dark)
|
||||
theme-ui-light: Mastodon Bird UI - vanila (dark)
|
||||
theme-ui-dark: Mastodon Bird UI - vanila (dark)
|
||||
time:
|
||||
formats:
|
||||
default: "%b %d, %Y, %H:%M"
|
||||
|
@ -1701,8 +1701,8 @@ ko:
|
||||
does_not_match_previous_name: 이전 이름과 맞지 않습니다
|
||||
themes:
|
||||
contrast: 마스토돈 (고대비)
|
||||
default: 휘핑 에디션 커스텀 테마 (어두움)
|
||||
theme-ui-light: 휘핑 에디션 커스텀 테마 (밝음)
|
||||
default: 휘핑 에디션 커스텀 테마 (밝음)
|
||||
theme-ui-dark: 휘핑 에디션 커스텀 테마 (어두움)
|
||||
mastodon-light: 마스토돈 (밝음)
|
||||
mastodon-dark: 마스토돈 (어두움)
|
||||
bird-ui-light: 파란새풍 테마 (밝음)
|
||||
|
@ -1,9 +1,8 @@
|
||||
# default: styles/mastodon-bird-ui-dark.scss
|
||||
default: styles/theme-ui-dark.scss
|
||||
theme-ui-light : styles/theme-ui-light.scss
|
||||
default: styles/theme-ui-light.scss
|
||||
theme-ui-dark : styles/theme-ui-dark.scss
|
||||
bird-ui-light: styles/bird-ui-light.scss
|
||||
bird-ui-dark: styles/bird-ui-dark.scss
|
||||
mastodon-dark: styles/application.scss
|
||||
mastodon-light: styles/mastodon-light.scss
|
||||
contrast: styles/contrast.scss
|
||||
|
||||
mastodon-dark: styles/application.scss
|
||||
contrast: styles/contrast.scss
|
20
lib/assets/Postype_Symbol-1.svg
Normal file
20
lib/assets/Postype_Symbol-1.svg
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="레이어_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px" viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<g id="brand_icon_00000015349382672088204330000013330278862377765539_">
|
||||
<g id="postype_blog_avatar_black_00000132056605817055768850000007591255024010429864_">
|
||||
<path id="Rectangle_00000113332819955128433970000003121550538948759936_" d="M85,0h330c46.94,0,85,38.06,85,85v330
|
||||
c0,46.94-38.06,85-85,85H85c-46.94,0-85-38.06-85-85V85C0,38.06,38.06,0,85,0z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="postype_symbol_00000167373025056826617510000014779858738401813159_" class="st0" d="M295.23,118.54
|
||||
c55.65,0,100.77,45.12,100.77,100.78s-45.12,100.78-100.77,100.78l-36.82,0.06v73.38H221.7V159.62h-31.98v233.92h-36.72V159.62H121
|
||||
v-41.08H295.23z M298.38,159.79H258.5v118.25h39.88c32.65,0,59.12-26.47,59.12-59.12S331.03,159.79,298.38,159.79L298.38,159.79z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
10
lib/assets/logo.svg
Normal file
10
lib/assets/logo.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="65" height="65" viewBox="0 0 61 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M60.7539 14.3904C59.8143 7.40642 53.7273 1.90257 46.5117 0.836066C45.2943 0.655854 40.6819 0 29.9973 0H29.9175C19.2299 0 16.937 0.655854 15.7196 0.836066C8.70488 1.87302 2.29885 6.81852 0.744617 13.8852C-0.00294988 17.3654 -0.0827298 21.2237 0.0561464 24.7629C0.254119 29.8384 0.292531 34.905 0.753482 39.9598C1.07215 43.3175 1.62806 46.6484 2.41704 49.9276C3.89445 55.9839 9.87499 61.0239 15.7344 63.0801C22.0077 65.2244 28.7542 65.5804 35.2184 64.1082C35.9295 63.9428 36.6318 63.7508 37.3252 63.5321C38.8971 63.0329 40.738 62.4745 42.0913 61.4937C42.1099 61.4799 42.1251 61.4621 42.1358 61.4417C42.1466 61.4212 42.1526 61.3986 42.1534 61.3755V56.4773C42.153 56.4557 42.1479 56.4345 42.1383 56.4151C42.1287 56.3958 42.1149 56.3788 42.0979 56.3655C42.0809 56.3522 42.0611 56.3429 42.04 56.3382C42.019 56.3335 41.9971 56.3336 41.9761 56.3384C37.8345 57.3276 33.5905 57.8234 29.3324 57.8156C22.0045 57.8156 20.0336 54.3384 19.4693 52.8908C19.0156 51.6397 18.7275 50.3346 18.6124 49.0088C18.6112 48.9866 18.6153 48.9643 18.6243 48.9439C18.6333 48.9236 18.647 48.9056 18.6643 48.8915C18.6816 48.8774 18.7019 48.8675 18.7237 48.8628C18.7455 48.858 18.7681 48.8585 18.7897 48.8641C22.8622 49.8465 27.037 50.3423 31.2265 50.3412C32.234 50.3412 33.2387 50.3412 34.2463 50.3146C38.4598 50.1964 42.9009 49.9808 47.0465 49.1713C47.1499 49.1506 47.2534 49.1329 47.342 49.1063C53.881 47.8507 60.1038 43.9097 60.7362 33.9301C60.7598 33.5372 60.8189 29.8148 60.8189 29.4071C60.8218 28.0215 61.2651 19.5781 60.7539 14.3904Z" fill="url(#paint0_linear_89_8)"/>
|
||||
<path d="M50.3943 22.237V39.5876H43.5185V22.7481C43.5185 19.2029 42.0411 17.3949 39.036 17.3949C35.7325 17.3949 34.0778 19.5338 34.0778 23.7585V32.9759H27.2434V23.7585C27.2434 19.5338 25.5857 17.3949 22.2822 17.3949C19.2949 17.3949 17.8027 19.2029 17.8027 22.7481V39.5876H10.9298V22.237C10.9298 18.6918 11.835 15.8754 13.6453 13.7877C15.5128 11.7049 17.9623 10.6355 21.0028 10.6355C24.522 10.6355 27.1813 11.9885 28.9542 14.6917L30.665 17.5633L32.3788 14.6917C34.1517 11.9885 36.811 10.6355 40.3243 10.6355C43.3619 10.6355 45.8114 11.7049 47.6847 13.7877C49.4931 15.8734 50.3963 18.6899 50.3943 22.237Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_89_8" x1="30.5" y1="0" x2="30.5" y2="65" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6364FF"/>
|
||||
<stop offset="1" stop-color="#563ACC"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
BIN
lib/assets/preview.png
Normal file
BIN
lib/assets/preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 326 KiB |
Loading…
Reference in New Issue
Block a user