mirror of
https://framagit.org/tykayn/mastodon.git
synced 2023-08-25 08:33:12 +02:00
back to tk bliss version 3.2
This commit is contained in:
commit
d348d67baf
8
.gitignore
vendored
8
.gitignore
vendored
@ -67,3 +67,11 @@ yarn-debug.log
|
|||||||
|
|
||||||
# Ignore Docker option files
|
# Ignore Docker option files
|
||||||
docker-compose.override.yml
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
|
||||||
|
/public/packs
|
||||||
|
/public/packs-test
|
||||||
|
/node_modules
|
||||||
|
/yarn-error.log
|
||||||
|
yarn-debug.log*
|
||||||
|
.yarn-integrity
|
||||||
|
1
.nope_browserlistrc
Normal file
1
.nope_browserlistrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
defaults
|
23
CHANGELOG.md
23
CHANGELOG.md
@ -3,7 +3,7 @@ Changelog
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [3.3.0] - 2020-12-27
|
## Unreleased
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- **Add hotkeys for audio/video control in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/15158), [Gargron](https://github.com/tootsuite/mastodon/pull/15198))
|
- **Add hotkeys for audio/video control in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/15158), [Gargron](https://github.com/tootsuite/mastodon/pull/15198))
|
||||||
@ -81,11 +81,11 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Change media modals look in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/15217), [Gargron](https://github.com/tootsuite/mastodon/pull/15221), [Gargron](https://github.com/tootsuite/mastodon/pull/15284), [Gargron](https://github.com/tootsuite/mastodon/pull/15283), [Kjwon15](https://github.com/tootsuite/mastodon/pull/15308), [noellabo](https://github.com/tootsuite/mastodon/pull/15305), [ThibG](https://github.com/tootsuite/mastodon/pull/15417))
|
- **Change media modals look in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/15217), [Gargron](https://github.com/tootsuite/mastodon/pull/15221), [Gargron](https://github.com/tootsuite/mastodon/pull/15284), [Gargron](https://github.com/tootsuite/mastodon/pull/15283), [Kjwon15](https://github.com/tootsuite/mastodon/pull/15308), [noellabo](https://github.com/tootsuite/mastodon/pull/15305))
|
||||||
- Background of the overlay matches the color of the image
|
- Background of the overlay matches the color of the image
|
||||||
- Action bar to interact with or open the toot from the modal
|
- Action bar to interact with or open the toot from the modal
|
||||||
- Change order of announcements in admin UI to be newest-first ([ThibG](https://github.com/tootsuite/mastodon/pull/15091))
|
- Change order of announcements in admin UI to be newest-first ([ThibG](https://github.com/tootsuite/mastodon/pull/15091))
|
||||||
- **Change account suspensions to be reversible by default** ([Gargron](https://github.com/tootsuite/mastodon/pull/14726), [ThibG](https://github.com/tootsuite/mastodon/pull/15152), [ThibG](https://github.com/tootsuite/mastodon/pull/15106), [ThibG](https://github.com/tootsuite/mastodon/pull/15100), [ThibG](https://github.com/tootsuite/mastodon/pull/15099), [noellabo](https://github.com/tootsuite/mastodon/pull/14855), [ThibG](https://github.com/tootsuite/mastodon/pull/15380), [Gargron](https://github.com/tootsuite/mastodon/pull/15420), [Gargron](https://github.com/tootsuite/mastodon/pull/15414))
|
- **Change account suspensions to be reversible by default** ([Gargron](https://github.com/tootsuite/mastodon/pull/14726), [ThibG](https://github.com/tootsuite/mastodon/pull/15152), [ThibG](https://github.com/tootsuite/mastodon/pull/15106), [ThibG](https://github.com/tootsuite/mastodon/pull/15100), [ThibG](https://github.com/tootsuite/mastodon/pull/15099), [noellabo](https://github.com/tootsuite/mastodon/pull/14855), [ThibG](https://github.com/tootsuite/mastodon/pull/15380))
|
||||||
- Suspensions no longer equal deletions
|
- Suspensions no longer equal deletions
|
||||||
- A suspended account can be unsuspended with minimal consequences for 30 days
|
- A suspended account can be unsuspended with minimal consequences for 30 days
|
||||||
- Immediate deletion of data is still available as an explicit option
|
- Immediate deletion of data is still available as an explicit option
|
||||||
@ -123,7 +123,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix layout on about page when contact account has a long username ([ThibG](https://github.com/tootsuite/mastodon/pull/15357))
|
- Fix layout on about page when contact account has a long username ([ThibG](https://github.com/tootsuite/mastodon/pull/15357))
|
||||||
- Fix follow limit preventing re-following of a moved account ([Gargron](https://github.com/tootsuite/mastodon/pull/14207), [ThibG](https://github.com/tootsuite/mastodon/pull/15384))
|
- Fix follow limit preventing re-following of a moved account ([Gargron](https://github.com/tootsuite/mastodon/pull/14207))
|
||||||
- **Fix deletes not reaching every server that interacted with toot** ([Gargron](https://github.com/tootsuite/mastodon/pull/15200))
|
- **Fix deletes not reaching every server that interacted with toot** ([Gargron](https://github.com/tootsuite/mastodon/pull/15200))
|
||||||
- Previously, delete of a toot would be primarily sent to the followers of its author, people mentioned in the toot, and people who reblogged the toot
|
- Previously, delete of a toot would be primarily sent to the followers of its author, people mentioned in the toot, and people who reblogged the toot
|
||||||
- Now, additionally, it is ensured that it is sent to people who replied to it, favourited it, and to the person it replies to even if that person is not mentioned
|
- Now, additionally, it is ensured that it is sent to people who replied to it, favourited it, and to the person it replies to even if that person is not mentioned
|
||||||
@ -163,7 +163,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Fix inefficiency when fetching bookmarks ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14674))
|
- Fix inefficiency when fetching bookmarks ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14674))
|
||||||
- Fix inefficiency when fetching favourites ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14673))
|
- Fix inefficiency when fetching favourites ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14673))
|
||||||
- Fix inefficiency when fetching media-only account timeline ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14675))
|
- Fix inefficiency when fetching media-only account timeline ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14675))
|
||||||
- Fix inefficieny when deleting accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/15387), [ThibG](https://github.com/tootsuite/mastodon/pull/15409), [ThibG](https://github.com/tootsuite/mastodon/pull/15407), [ThibG](https://github.com/tootsuite/mastodon/pull/15408), [ThibG](https://github.com/tootsuite/mastodon/pull/15402), [ThibG](https://github.com/tootsuite/mastodon/pull/15416), [Gargron](https://github.com/tootsuite/mastodon/pull/15421))
|
- Fix inefficieny when deleting accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/15387), [ThibG](https://github.com/tootsuite/mastodon/pull/15409), [ThibG](https://github.com/tootsuite/mastodon/pull/15407), [ThibG](https://github.com/tootsuite/mastodon/pull/15408), [ThibG](https://github.com/tootsuite/mastodon/pull/15402))
|
||||||
- Fix redundant query when processing batch actions on custom emojis ([niwatori24](https://github.com/tootsuite/mastodon/pull/14534))
|
- Fix redundant query when processing batch actions on custom emojis ([niwatori24](https://github.com/tootsuite/mastodon/pull/14534))
|
||||||
- Fix slow distinct queries where grouped queries are faster ([Gargron](https://github.com/tootsuite/mastodon/pull/15287))
|
- Fix slow distinct queries where grouped queries are faster ([Gargron](https://github.com/tootsuite/mastodon/pull/15287))
|
||||||
- Fix performance on instances list in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15282))
|
- Fix performance on instances list in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15282))
|
||||||
@ -387,14 +387,21 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Only then proceed to start removing their data (slow)
|
- Only then proceed to start removing their data (slow)
|
||||||
- Clear out media attachments in a separate worker (slow)
|
- Clear out media attachments in a separate worker (slow)
|
||||||
|
|
||||||
## [3.1.5] - 2020-07-07
|
## [v3.1.5] - 2020-07-07
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
- Fix media attachment enumeration ([ThibG](https://github.com/tootsuite/mastodon/pull/14254))
|
- Fix media attachment enumeration ([ThibG](https://github.com/tootsuite/mastodon/pull/14254))
|
||||||
- Change rate limits for various paths ([Gargron](https://github.com/tootsuite/mastodon/pull/14253))
|
- Change rate limits for various paths ([Gargron](https://github.com/tootsuite/mastodon/pull/14253))
|
||||||
- Fix other sessions not being logged out on password change ([Gargron](https://github.com/tootsuite/mastodon/pull/14252))
|
- Fix other sessions not being logged out on password change ([Gargron](https://github.com/tootsuite/mastodon/pull/14252))
|
||||||
|
|
||||||
## [3.1.4] - 2020-05-14
|
## [v3.1.5] - 2020-07-07
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix media attachment enumeration ([ThibG](https://github.com/tootsuite/mastodon/pull/14254))
|
||||||
|
- Change rate limits for various paths ([Gargron](https://github.com/tootsuite/mastodon/pull/14253))
|
||||||
|
- Fix other sessions not being logged out on password change ([Gargron](https://github.com/tootsuite/mastodon/pull/14252))
|
||||||
|
|
||||||
|
## [v3.1.4] - 2020-05-14
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `vi` to available locales ([taicv](https://github.com/tootsuite/mastodon/pull/13542))
|
- Add `vi` to available locales ([taicv](https://github.com/tootsuite/mastodon/pull/13542))
|
||||||
@ -461,7 +468,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- For apps that self-register on behalf of every individual user (such as most mobile apps), this is a non-issue
|
- For apps that self-register on behalf of every individual user (such as most mobile apps), this is a non-issue
|
||||||
- The issue only affects developers of apps who are shared between multiple users, such as server-side apps like cross-posters
|
- The issue only affects developers of apps who are shared between multiple users, such as server-side apps like cross-posters
|
||||||
|
|
||||||
## [3.1.3] - 2020-04-05
|
## [v3.1.3] - 2020-04-05
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add ability to filter audit log in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/13381))
|
- Add ability to filter audit log in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/13381))
|
||||||
|
@ -811,3 +811,9 @@ DEPENDENCIES
|
|||||||
webpacker (~> 5.2)
|
webpacker (~> 5.2)
|
||||||
webpush
|
webpush
|
||||||
xorcist (~> 1.1)
|
xorcist (~> 1.1)
|
||||||
|
|
||||||
|
RUBY VERSION
|
||||||
|
ruby 2.6.6p146
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.1.4
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
![Mastodon](https://i.imgur.com/NhZc40l.png)
|
![Mastodon](https://i.imgur.com/NhZc40l.png) - [mastodon.CipherBliss.com](https://mastodon.CipherBliss.com) version
|
||||||
========
|
========
|
||||||
|
|
||||||
[![GitHub release](https://img.shields.io/github/release/tootsuite/mastodon.svg)][releases]
|
[![GitHub release](https://img.shields.io/github/release/tootsuite/mastodon.svg)][releases]
|
||||||
|
2
app/assets/javascripts/user_groups.js
Normal file
2
app/assets/javascripts/user_groups.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
// All this logic will automatically be available in application.js.
|
80
app/assets/stylesheets/scaffold.css
Normal file
80
app/assets/stylesheets/scaffold.css
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
body {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
margin: 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, p, ol, ul, td {
|
||||||
|
font-family: verdana, arial, helvetica, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0 5px 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.field,
|
||||||
|
div.actions {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notice {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field_with_errors {
|
||||||
|
padding: 2px;
|
||||||
|
background-color: red;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
#error_explanation {
|
||||||
|
width: 450px;
|
||||||
|
border: 2px solid red;
|
||||||
|
padding: 7px 7px 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#error_explanation h2 {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 5px 5px 5px 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
margin: -7px -7px 0;
|
||||||
|
background-color: #c00;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#error_explanation ul li {
|
||||||
|
font-size: 12px;
|
||||||
|
list-style: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
}
|
4
app/assets/stylesheets/user_groups.css
Normal file
4
app/assets/stylesheets/user_groups.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/*
|
||||||
|
Place all the styles related to the matching controller here.
|
||||||
|
They will automatically be included in application.css.
|
||||||
|
*/
|
58
app/controllers/user_groups_controller.rb
Normal file
58
app/controllers/user_groups_controller.rb
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
class UserGroupsController < ApplicationController
|
||||||
|
before_action :set_user_group, only: [:show, :edit, :update, :destroy]
|
||||||
|
|
||||||
|
# GET /user_groups
|
||||||
|
def index
|
||||||
|
@user_groups = UserGroup.all
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /user_groups/1
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /user_groups/new
|
||||||
|
def new
|
||||||
|
@user_group = UserGroup.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /user_groups/1/edit
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /user_groups
|
||||||
|
def create
|
||||||
|
@user_group = UserGroup.new(user_group_params)
|
||||||
|
|
||||||
|
if @user_group.save
|
||||||
|
redirect_to @user_group, notice: 'User group was successfully created.'
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /user_groups/1
|
||||||
|
def update
|
||||||
|
if @user_group.update(user_group_params)
|
||||||
|
redirect_to @user_group, notice: 'User group was successfully updated.'
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# DELETE /user_groups/1
|
||||||
|
def destroy
|
||||||
|
@user_group.destroy
|
||||||
|
redirect_to user_groups_url, notice: 'User group was successfully destroyed.'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
|
def set_user_group
|
||||||
|
@user_group = UserGroup.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow a trusted parameter "white list" through.
|
||||||
|
def user_group_params
|
||||||
|
params.require(:user_group).permit(:name, :createAt, :visibility, :members)
|
||||||
|
end
|
||||||
|
end
|
2
app/helpers/user_groups_helper.rb
Normal file
2
app/helpers/user_groups_helper.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module UserGroupsHelper
|
||||||
|
end
|
BIN
app/javascript/images/logo_cipherbliss.png
Executable file
BIN
app/javascript/images/logo_cipherbliss.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -85,20 +85,20 @@ export function fetchAccount(id) {
|
|||||||
dispatch(fetchAccountFail(id, error));
|
dispatch(fetchAccountFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchAccountRequest(id) {
|
export function fetchAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FETCH_REQUEST,
|
type: ACCOUNT_FETCH_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchAccountSuccess() {
|
export function fetchAccountSuccess() {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FETCH_SUCCESS,
|
type: ACCOUNT_FETCH_SUCCESS,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchAccountFail(id, error) {
|
export function fetchAccountFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -107,7 +107,7 @@ export function fetchAccountFail(id, error) {
|
|||||||
error,
|
error,
|
||||||
skipAlert: true,
|
skipAlert: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function followAccount(id, options = { reblogs: true }) {
|
export function followAccount(id, options = { reblogs: true }) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -122,7 +122,7 @@ export function followAccount(id, options = { reblogs: true }) {
|
|||||||
dispatch(followAccountFail(error, locked));
|
dispatch(followAccountFail(error, locked));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unfollowAccount(id) {
|
export function unfollowAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -134,7 +134,7 @@ export function unfollowAccount(id) {
|
|||||||
dispatch(unfollowAccountFail(error));
|
dispatch(unfollowAccountFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function followAccountRequest(id, locked) {
|
export function followAccountRequest(id, locked) {
|
||||||
return {
|
return {
|
||||||
@ -143,7 +143,7 @@ export function followAccountRequest(id, locked) {
|
|||||||
locked,
|
locked,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function followAccountSuccess(relationship, alreadyFollowing) {
|
export function followAccountSuccess(relationship, alreadyFollowing) {
|
||||||
return {
|
return {
|
||||||
@ -152,7 +152,7 @@ export function followAccountSuccess(relationship, alreadyFollowing) {
|
|||||||
alreadyFollowing,
|
alreadyFollowing,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function followAccountFail(error, locked) {
|
export function followAccountFail(error, locked) {
|
||||||
return {
|
return {
|
||||||
@ -161,7 +161,7 @@ export function followAccountFail(error, locked) {
|
|||||||
locked,
|
locked,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unfollowAccountRequest(id) {
|
export function unfollowAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
@ -169,7 +169,7 @@ export function unfollowAccountRequest(id) {
|
|||||||
id,
|
id,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unfollowAccountSuccess(relationship, statuses) {
|
export function unfollowAccountSuccess(relationship, statuses) {
|
||||||
return {
|
return {
|
||||||
@ -178,7 +178,7 @@ export function unfollowAccountSuccess(relationship, statuses) {
|
|||||||
statuses,
|
statuses,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unfollowAccountFail(error) {
|
export function unfollowAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
@ -186,7 +186,7 @@ export function unfollowAccountFail(error) {
|
|||||||
error,
|
error,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function blockAccount(id) {
|
export function blockAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -199,7 +199,7 @@ export function blockAccount(id) {
|
|||||||
dispatch(blockAccountFail(id, error));
|
dispatch(blockAccountFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unblockAccount(id) {
|
export function unblockAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -211,14 +211,14 @@ export function unblockAccount(id) {
|
|||||||
dispatch(unblockAccountFail(id, error));
|
dispatch(unblockAccountFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function blockAccountRequest(id) {
|
export function blockAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_BLOCK_REQUEST,
|
type: ACCOUNT_BLOCK_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function blockAccountSuccess(relationship, statuses) {
|
export function blockAccountSuccess(relationship, statuses) {
|
||||||
return {
|
return {
|
||||||
@ -226,35 +226,35 @@ export function blockAccountSuccess(relationship, statuses) {
|
|||||||
relationship,
|
relationship,
|
||||||
statuses,
|
statuses,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function blockAccountFail(error) {
|
export function blockAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_BLOCK_FAIL,
|
type: ACCOUNT_BLOCK_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unblockAccountRequest(id) {
|
export function unblockAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNBLOCK_REQUEST,
|
type: ACCOUNT_UNBLOCK_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unblockAccountSuccess(relationship) {
|
export function unblockAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNBLOCK_SUCCESS,
|
type: ACCOUNT_UNBLOCK_SUCCESS,
|
||||||
relationship,
|
relationship,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unblockAccountFail(error) {
|
export function unblockAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNBLOCK_FAIL,
|
type: ACCOUNT_UNBLOCK_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
export function muteAccount(id, notifications, duration=0) {
|
export function muteAccount(id, notifications, duration=0) {
|
||||||
@ -268,7 +268,7 @@ export function muteAccount(id, notifications, duration=0) {
|
|||||||
dispatch(muteAccountFail(id, error));
|
dispatch(muteAccountFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteAccount(id) {
|
export function unmuteAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -280,14 +280,14 @@ export function unmuteAccount(id) {
|
|||||||
dispatch(unmuteAccountFail(id, error));
|
dispatch(unmuteAccountFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteAccountRequest(id) {
|
export function muteAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_MUTE_REQUEST,
|
type: ACCOUNT_MUTE_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteAccountSuccess(relationship, statuses) {
|
export function muteAccountSuccess(relationship, statuses) {
|
||||||
return {
|
return {
|
||||||
@ -295,35 +295,35 @@ export function muteAccountSuccess(relationship, statuses) {
|
|||||||
relationship,
|
relationship,
|
||||||
statuses,
|
statuses,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteAccountFail(error) {
|
export function muteAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_MUTE_FAIL,
|
type: ACCOUNT_MUTE_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteAccountRequest(id) {
|
export function unmuteAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNMUTE_REQUEST,
|
type: ACCOUNT_UNMUTE_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteAccountSuccess(relationship) {
|
export function unmuteAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNMUTE_SUCCESS,
|
type: ACCOUNT_UNMUTE_SUCCESS,
|
||||||
relationship,
|
relationship,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteAccountFail(error) {
|
export function unmuteAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNMUTE_FAIL,
|
type: ACCOUNT_UNMUTE_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
export function fetchFollowers(id) {
|
export function fetchFollowers(id) {
|
||||||
@ -340,14 +340,14 @@ export function fetchFollowers(id) {
|
|||||||
dispatch(fetchFollowersFail(id, error));
|
dispatch(fetchFollowersFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowersRequest(id) {
|
export function fetchFollowersRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWERS_FETCH_REQUEST,
|
type: FOLLOWERS_FETCH_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowersSuccess(id, accounts, next) {
|
export function fetchFollowersSuccess(id, accounts, next) {
|
||||||
return {
|
return {
|
||||||
@ -356,16 +356,16 @@ export function fetchFollowersSuccess(id, accounts, next) {
|
|||||||
accounts,
|
accounts,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowersFail(id, error) {
|
export function fetchFollowersFail(id, error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWERS_FETCH_FAIL,
|
type : FOLLOWERS_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipNotFound: true,
|
skipNotFound: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowers(id) {
|
export function expandFollowers(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -387,14 +387,14 @@ export function expandFollowers(id) {
|
|||||||
dispatch(expandFollowersFail(id, error));
|
dispatch(expandFollowersFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowersRequest(id) {
|
export function expandFollowersRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWERS_EXPAND_REQUEST,
|
type: FOLLOWERS_EXPAND_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowersSuccess(id, accounts, next) {
|
export function expandFollowersSuccess(id, accounts, next) {
|
||||||
return {
|
return {
|
||||||
@ -403,7 +403,7 @@ export function expandFollowersSuccess(id, accounts, next) {
|
|||||||
accounts,
|
accounts,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowersFail(id, error) {
|
export function expandFollowersFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -411,7 +411,7 @@ export function expandFollowersFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowing(id) {
|
export function fetchFollowing(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -427,14 +427,14 @@ export function fetchFollowing(id) {
|
|||||||
dispatch(fetchFollowingFail(id, error));
|
dispatch(fetchFollowingFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowingRequest(id) {
|
export function fetchFollowingRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWING_FETCH_REQUEST,
|
type: FOLLOWING_FETCH_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowingSuccess(id, accounts, next) {
|
export function fetchFollowingSuccess(id, accounts, next) {
|
||||||
return {
|
return {
|
||||||
@ -443,16 +443,16 @@ export function fetchFollowingSuccess(id, accounts, next) {
|
|||||||
accounts,
|
accounts,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowingFail(id, error) {
|
export function fetchFollowingFail(id, error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWING_FETCH_FAIL,
|
type : FOLLOWING_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipNotFound: true,
|
skipNotFound: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowing(id) {
|
export function expandFollowing(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -474,14 +474,14 @@ export function expandFollowing(id) {
|
|||||||
dispatch(expandFollowingFail(id, error));
|
dispatch(expandFollowingFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowingRequest(id) {
|
export function expandFollowingRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWING_EXPAND_REQUEST,
|
type: FOLLOWING_EXPAND_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowingSuccess(id, accounts, next) {
|
export function expandFollowingSuccess(id, accounts, next) {
|
||||||
return {
|
return {
|
||||||
@ -490,7 +490,7 @@ export function expandFollowingSuccess(id, accounts, next) {
|
|||||||
accounts,
|
accounts,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowingFail(id, error) {
|
export function expandFollowingFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -498,7 +498,7 @@ export function expandFollowingFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchRelationships(accountIds) {
|
export function fetchRelationships(accountIds) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -517,7 +517,7 @@ export function fetchRelationships(accountIds) {
|
|||||||
dispatch(fetchRelationshipsFail(error));
|
dispatch(fetchRelationshipsFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchRelationshipsRequest(ids) {
|
export function fetchRelationshipsRequest(ids) {
|
||||||
return {
|
return {
|
||||||
@ -525,7 +525,7 @@ export function fetchRelationshipsRequest(ids) {
|
|||||||
ids,
|
ids,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchRelationshipsSuccess(relationships) {
|
export function fetchRelationshipsSuccess(relationships) {
|
||||||
return {
|
return {
|
||||||
@ -533,16 +533,16 @@ export function fetchRelationshipsSuccess(relationships) {
|
|||||||
relationships,
|
relationships,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchRelationshipsFail(error) {
|
export function fetchRelationshipsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: RELATIONSHIPS_FETCH_FAIL,
|
type : RELATIONSHIPS_FETCH_FAIL,
|
||||||
error,
|
error,
|
||||||
skipLoading: true,
|
skipLoading : true,
|
||||||
skipNotFound: true,
|
skipNotFound: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowRequests() {
|
export function fetchFollowRequests() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -554,13 +554,13 @@ export function fetchFollowRequests() {
|
|||||||
dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
|
dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
|
||||||
}).catch(error => dispatch(fetchFollowRequestsFail(error)));
|
}).catch(error => dispatch(fetchFollowRequestsFail(error)));
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowRequestsRequest() {
|
export function fetchFollowRequestsRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_FETCH_REQUEST,
|
type: FOLLOW_REQUESTS_FETCH_REQUEST,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowRequestsSuccess(accounts, next) {
|
export function fetchFollowRequestsSuccess(accounts, next) {
|
||||||
return {
|
return {
|
||||||
@ -568,14 +568,14 @@ export function fetchFollowRequestsSuccess(accounts, next) {
|
|||||||
accounts,
|
accounts,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowRequestsFail(error) {
|
export function fetchFollowRequestsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_FETCH_FAIL,
|
type: FOLLOW_REQUESTS_FETCH_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowRequests() {
|
export function expandFollowRequests() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -593,13 +593,13 @@ export function expandFollowRequests() {
|
|||||||
dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
|
dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
|
||||||
}).catch(error => dispatch(expandFollowRequestsFail(error)));
|
}).catch(error => dispatch(expandFollowRequestsFail(error)));
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowRequestsRequest() {
|
export function expandFollowRequestsRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_EXPAND_REQUEST,
|
type: FOLLOW_REQUESTS_EXPAND_REQUEST,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowRequestsSuccess(accounts, next) {
|
export function expandFollowRequestsSuccess(accounts, next) {
|
||||||
return {
|
return {
|
||||||
@ -607,14 +607,14 @@ export function expandFollowRequestsSuccess(accounts, next) {
|
|||||||
accounts,
|
accounts,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowRequestsFail(error) {
|
export function expandFollowRequestsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_EXPAND_FAIL,
|
type: FOLLOW_REQUESTS_EXPAND_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function authorizeFollowRequest(id) {
|
export function authorizeFollowRequest(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -625,21 +625,21 @@ export function authorizeFollowRequest(id) {
|
|||||||
.then(() => dispatch(authorizeFollowRequestSuccess(id)))
|
.then(() => dispatch(authorizeFollowRequestSuccess(id)))
|
||||||
.catch(error => dispatch(authorizeFollowRequestFail(id, error)));
|
.catch(error => dispatch(authorizeFollowRequestFail(id, error)));
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function authorizeFollowRequestRequest(id) {
|
export function authorizeFollowRequestRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
|
type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function authorizeFollowRequestSuccess(id) {
|
export function authorizeFollowRequestSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function authorizeFollowRequestFail(id, error) {
|
export function authorizeFollowRequestFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -647,7 +647,7 @@ export function authorizeFollowRequestFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
export function rejectFollowRequest(id) {
|
export function rejectFollowRequest(id) {
|
||||||
@ -659,21 +659,21 @@ export function rejectFollowRequest(id) {
|
|||||||
.then(() => dispatch(rejectFollowRequestSuccess(id)))
|
.then(() => dispatch(rejectFollowRequestSuccess(id)))
|
||||||
.catch(error => dispatch(rejectFollowRequestFail(id, error)));
|
.catch(error => dispatch(rejectFollowRequestFail(id, error)));
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function rejectFollowRequestRequest(id) {
|
export function rejectFollowRequestRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_REJECT_REQUEST,
|
type: FOLLOW_REQUEST_REJECT_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function rejectFollowRequestSuccess(id) {
|
export function rejectFollowRequestSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_REJECT_SUCCESS,
|
type: FOLLOW_REQUEST_REJECT_SUCCESS,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function rejectFollowRequestFail(id, error) {
|
export function rejectFollowRequestFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -681,7 +681,7 @@ export function rejectFollowRequestFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function pinAccount(id) {
|
export function pinAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -693,7 +693,7 @@ export function pinAccount(id) {
|
|||||||
dispatch(pinAccountFail(error));
|
dispatch(pinAccountFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unpinAccount(id) {
|
export function unpinAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -705,46 +705,46 @@ export function unpinAccount(id) {
|
|||||||
dispatch(unpinAccountFail(error));
|
dispatch(unpinAccountFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function pinAccountRequest(id) {
|
export function pinAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_PIN_REQUEST,
|
type: ACCOUNT_PIN_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function pinAccountSuccess(relationship) {
|
export function pinAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_PIN_SUCCESS,
|
type: ACCOUNT_PIN_SUCCESS,
|
||||||
relationship,
|
relationship,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function pinAccountFail(error) {
|
export function pinAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_PIN_FAIL,
|
type: ACCOUNT_PIN_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unpinAccountRequest(id) {
|
export function unpinAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNPIN_REQUEST,
|
type: ACCOUNT_UNPIN_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unpinAccountSuccess(relationship) {
|
export function unpinAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNPIN_SUCCESS,
|
type: ACCOUNT_UNPIN_SUCCESS,
|
||||||
relationship,
|
relationship,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unpinAccountFail(error) {
|
export function unpinAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNPIN_FAIL,
|
type: ACCOUNT_UNPIN_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
@ -17,13 +17,13 @@ export function dismissAlert(alert) {
|
|||||||
type: ALERT_DISMISS,
|
type: ALERT_DISMISS,
|
||||||
alert,
|
alert,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function clearAlert() {
|
export function clearAlert() {
|
||||||
return {
|
return {
|
||||||
type: ALERT_CLEAR,
|
type: ALERT_CLEAR,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage, message_values = undefined) {
|
export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage, message_values = undefined) {
|
||||||
return {
|
return {
|
||||||
@ -32,7 +32,7 @@ export function showAlert(title = messages.unexpectedTitle, message = messages.u
|
|||||||
message,
|
message,
|
||||||
message_values,
|
message_values,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function showAlertForError(error, skipNotFound = false) {
|
export function showAlertForError(error, skipNotFound = false) {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
|
@ -3,21 +3,21 @@ import { normalizeAnnouncement } from './importer/normalizer';
|
|||||||
|
|
||||||
export const ANNOUNCEMENTS_FETCH_REQUEST = 'ANNOUNCEMENTS_FETCH_REQUEST';
|
export const ANNOUNCEMENTS_FETCH_REQUEST = 'ANNOUNCEMENTS_FETCH_REQUEST';
|
||||||
export const ANNOUNCEMENTS_FETCH_SUCCESS = 'ANNOUNCEMENTS_FETCH_SUCCESS';
|
export const ANNOUNCEMENTS_FETCH_SUCCESS = 'ANNOUNCEMENTS_FETCH_SUCCESS';
|
||||||
export const ANNOUNCEMENTS_FETCH_FAIL = 'ANNOUNCEMENTS_FETCH_FAIL';
|
export const ANNOUNCEMENTS_FETCH_FAIL = 'ANNOUNCEMENTS_FETCH_FAIL';
|
||||||
export const ANNOUNCEMENTS_UPDATE = 'ANNOUNCEMENTS_UPDATE';
|
export const ANNOUNCEMENTS_UPDATE = 'ANNOUNCEMENTS_UPDATE';
|
||||||
export const ANNOUNCEMENTS_DELETE = 'ANNOUNCEMENTS_DELETE';
|
export const ANNOUNCEMENTS_DELETE = 'ANNOUNCEMENTS_DELETE';
|
||||||
|
|
||||||
export const ANNOUNCEMENTS_DISMISS_REQUEST = 'ANNOUNCEMENTS_DISMISS_REQUEST';
|
export const ANNOUNCEMENTS_DISMISS_REQUEST = 'ANNOUNCEMENTS_DISMISS_REQUEST';
|
||||||
export const ANNOUNCEMENTS_DISMISS_SUCCESS = 'ANNOUNCEMENTS_DISMISS_SUCCESS';
|
export const ANNOUNCEMENTS_DISMISS_SUCCESS = 'ANNOUNCEMENTS_DISMISS_SUCCESS';
|
||||||
export const ANNOUNCEMENTS_DISMISS_FAIL = 'ANNOUNCEMENTS_DISMISS_FAIL';
|
export const ANNOUNCEMENTS_DISMISS_FAIL = 'ANNOUNCEMENTS_DISMISS_FAIL';
|
||||||
|
|
||||||
export const ANNOUNCEMENTS_REACTION_ADD_REQUEST = 'ANNOUNCEMENTS_REACTION_ADD_REQUEST';
|
export const ANNOUNCEMENTS_REACTION_ADD_REQUEST = 'ANNOUNCEMENTS_REACTION_ADD_REQUEST';
|
||||||
export const ANNOUNCEMENTS_REACTION_ADD_SUCCESS = 'ANNOUNCEMENTS_REACTION_ADD_SUCCESS';
|
export const ANNOUNCEMENTS_REACTION_ADD_SUCCESS = 'ANNOUNCEMENTS_REACTION_ADD_SUCCESS';
|
||||||
export const ANNOUNCEMENTS_REACTION_ADD_FAIL = 'ANNOUNCEMENTS_REACTION_ADD_FAIL';
|
export const ANNOUNCEMENTS_REACTION_ADD_FAIL = 'ANNOUNCEMENTS_REACTION_ADD_FAIL';
|
||||||
|
|
||||||
export const ANNOUNCEMENTS_REACTION_REMOVE_REQUEST = 'ANNOUNCEMENTS_REACTION_REMOVE_REQUEST';
|
export const ANNOUNCEMENTS_REACTION_REMOVE_REQUEST = 'ANNOUNCEMENTS_REACTION_REMOVE_REQUEST';
|
||||||
export const ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS = 'ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS';
|
export const ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS = 'ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS';
|
||||||
export const ANNOUNCEMENTS_REACTION_REMOVE_FAIL = 'ANNOUNCEMENTS_REACTION_REMOVE_FAIL';
|
export const ANNOUNCEMENTS_REACTION_REMOVE_FAIL = 'ANNOUNCEMENTS_REACTION_REMOVE_FAIL';
|
||||||
|
|
||||||
export const ANNOUNCEMENTS_REACTION_UPDATE = 'ANNOUNCEMENTS_REACTION_UPDATE';
|
export const ANNOUNCEMENTS_REACTION_UPDATE = 'ANNOUNCEMENTS_REACTION_UPDATE';
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ export const fetchAnnouncementsFail= error => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const updateAnnouncements = announcement => ({
|
export const updateAnnouncements = announcement => ({
|
||||||
type: ANNOUNCEMENTS_UPDATE,
|
type : ANNOUNCEMENTS_UPDATE,
|
||||||
announcement: normalizeAnnouncement(announcement),
|
announcement: normalizeAnnouncement(announcement),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -72,17 +72,17 @@ export const dismissAnnouncement = announcementId => (dispatch, getState) => {
|
|||||||
|
|
||||||
export const dismissAnnouncementRequest = announcementId => ({
|
export const dismissAnnouncementRequest = announcementId => ({
|
||||||
type: ANNOUNCEMENTS_DISMISS_REQUEST,
|
type: ANNOUNCEMENTS_DISMISS_REQUEST,
|
||||||
id: announcementId,
|
id : announcementId,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const dismissAnnouncementSuccess = announcementId => ({
|
export const dismissAnnouncementSuccess = announcementId => ({
|
||||||
type: ANNOUNCEMENTS_DISMISS_SUCCESS,
|
type: ANNOUNCEMENTS_DISMISS_SUCCESS,
|
||||||
id: announcementId,
|
id : announcementId,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const dismissAnnouncementFail = (announcementId, error) => ({
|
export const dismissAnnouncementFail = (announcementId, error) => ({
|
||||||
type: ANNOUNCEMENTS_DISMISS_FAIL,
|
type: ANNOUNCEMENTS_DISMISS_FAIL,
|
||||||
id: announcementId,
|
id : announcementId,
|
||||||
error,
|
error,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@ import { useEmoji } from './emojis';
|
|||||||
import resizeImage from '../utils/resize_image';
|
import resizeImage from '../utils/resize_image';
|
||||||
import { importFetchedAccounts } from './importer';
|
import { importFetchedAccounts } from './importer';
|
||||||
import { updateTimeline } from './timelines';
|
import { updateTimeline } from './timelines';
|
||||||
import { showAlertForError } from './alerts';
|
import { showAlert, showAlertForError } from './alerts';
|
||||||
import { showAlert } from './alerts';
|
|
||||||
import { defineMessages } from 'react-intl';
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
let cancelFetchComposeSuggestionsAccounts, cancelFetchComposeSuggestionsTags;
|
let cancelFetchComposeSuggestionsAccounts, cancelFetchComposeSuggestionsTags;
|
||||||
@ -81,7 +80,7 @@ export function changeCompose(text) {
|
|||||||
type: COMPOSE_CHANGE,
|
type: COMPOSE_CHANGE,
|
||||||
text: text,
|
text: text,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function replyCompose(status, routerHistory) {
|
export function replyCompose(status, routerHistory) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -92,19 +91,19 @@ export function replyCompose(status, routerHistory) {
|
|||||||
|
|
||||||
ensureComposeIsVisible(getState, routerHistory);
|
ensureComposeIsVisible(getState, routerHistory);
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function cancelReplyCompose() {
|
export function cancelReplyCompose() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_REPLY_CANCEL,
|
type: COMPOSE_REPLY_CANCEL,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function resetCompose() {
|
export function resetCompose() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_RESET,
|
type: COMPOSE_RESET,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function mentionCompose(account, routerHistory) {
|
export function mentionCompose(account, routerHistory) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -115,7 +114,7 @@ export function mentionCompose(account, routerHistory) {
|
|||||||
|
|
||||||
ensureComposeIsVisible(getState, routerHistory);
|
ensureComposeIsVisible(getState, routerHistory);
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function directCompose(account, routerHistory) {
|
export function directCompose(account, routerHistory) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -126,7 +125,7 @@ export function directCompose(account, routerHistory) {
|
|||||||
|
|
||||||
ensureComposeIsVisible(getState, routerHistory);
|
ensureComposeIsVisible(getState, routerHistory);
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function submitCompose(routerHistory) {
|
export function submitCompose(routerHistory) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
@ -182,27 +181,27 @@ export function submitCompose(routerHistory) {
|
|||||||
dispatch(submitComposeFail(error));
|
dispatch(submitComposeFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function submitComposeRequest() {
|
export function submitComposeRequest() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_REQUEST,
|
type: COMPOSE_SUBMIT_REQUEST,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function submitComposeSuccess(status) {
|
export function submitComposeSuccess(status) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_SUCCESS,
|
type: COMPOSE_SUBMIT_SUCCESS,
|
||||||
status: status,
|
status: status,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function submitComposeFail(error) {
|
export function submitComposeFail(error) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_FAIL,
|
type: COMPOSE_SUBMIT_FAIL,
|
||||||
error: error,
|
error: error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function uploadCompose(files) {
|
export function uploadCompose(files) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
@ -234,7 +233,7 @@ export function uploadCompose(files) {
|
|||||||
total += file.size - f.size;
|
total += file.size - f.size;
|
||||||
|
|
||||||
return api(getState).post('/api/v2/media', data, {
|
return api(getState).post('/api/v2/media', data, {
|
||||||
onUploadProgress: function({ loaded }){
|
onUploadProgress: function ({ loaded }) {
|
||||||
progress[i] = loaded;
|
progress[i] = loaded;
|
||||||
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
||||||
},
|
},
|
||||||
@ -259,9 +258,9 @@ export function uploadCompose(files) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export const uploadThumbnail = (id, file) => (dispatch, getState) => {
|
export const uploadThumbnail = (id, file) => (dispatch, getState) => {
|
||||||
dispatch(uploadThumbnailRequest());
|
dispatch(uploadThumbnailRequest());
|
||||||
@ -316,7 +315,7 @@ export function changeUploadCompose(id, params) {
|
|||||||
dispatch(changeUploadComposeFail(id, error));
|
dispatch(changeUploadComposeFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeUploadComposeRequest() {
|
export function changeUploadComposeRequest() {
|
||||||
return {
|
return {
|
||||||
@ -331,7 +330,7 @@ export function changeUploadComposeSuccess(media) {
|
|||||||
media: media,
|
media: media,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeUploadComposeFail(error) {
|
export function changeUploadComposeFail(error) {
|
||||||
return {
|
return {
|
||||||
@ -339,14 +338,14 @@ export function changeUploadComposeFail(error) {
|
|||||||
error: error,
|
error: error,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function uploadComposeRequest() {
|
export function uploadComposeRequest() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_REQUEST,
|
type: COMPOSE_UPLOAD_REQUEST,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function uploadComposeProgress(loaded, total) {
|
export function uploadComposeProgress(loaded, total) {
|
||||||
return {
|
return {
|
||||||
@ -354,7 +353,7 @@ export function uploadComposeProgress(loaded, total) {
|
|||||||
loaded: loaded,
|
loaded: loaded,
|
||||||
total: total,
|
total: total,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function uploadComposeSuccess(media, file) {
|
export function uploadComposeSuccess(media, file) {
|
||||||
return {
|
return {
|
||||||
@ -363,7 +362,7 @@ export function uploadComposeSuccess(media, file) {
|
|||||||
file: file,
|
file: file,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function uploadComposeFail(error) {
|
export function uploadComposeFail(error) {
|
||||||
return {
|
return {
|
||||||
@ -371,14 +370,14 @@ export function uploadComposeFail(error) {
|
|||||||
error: error,
|
error: error,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function undoUploadCompose(media_id) {
|
export function undoUploadCompose(media_id) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_UNDO,
|
type: COMPOSE_UPLOAD_UNDO,
|
||||||
media_id: media_id,
|
media_id: media_id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function clearComposeSuggestions() {
|
export function clearComposeSuggestions() {
|
||||||
if (cancelFetchComposeSuggestionsAccounts) {
|
if (cancelFetchComposeSuggestionsAccounts) {
|
||||||
@ -387,7 +386,7 @@ export function clearComposeSuggestions() {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_SUGGESTIONS_CLEAR,
|
type: COMPOSE_SUGGESTIONS_CLEAR,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
|
const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
|
||||||
if (cancelFetchComposeSuggestionsAccounts) {
|
if (cancelFetchComposeSuggestionsAccounts) {
|
||||||
@ -461,7 +460,7 @@ export function fetchComposeSuggestions(token) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function readyComposeSuggestionsEmojis(token, emojis) {
|
export function readyComposeSuggestionsEmojis(token, emojis) {
|
||||||
return {
|
return {
|
||||||
@ -469,7 +468,7 @@ export function readyComposeSuggestionsEmojis(token, emojis) {
|
|||||||
token,
|
token,
|
||||||
emojis,
|
emojis,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function readyComposeSuggestionsAccounts(token, accounts) {
|
export function readyComposeSuggestionsAccounts(token, accounts) {
|
||||||
return {
|
return {
|
||||||
@ -477,7 +476,7 @@ export function readyComposeSuggestionsAccounts(token, accounts) {
|
|||||||
token,
|
token,
|
||||||
accounts,
|
accounts,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export const readyComposeSuggestionsTags = (token, tags) => ({
|
export const readyComposeSuggestionsTags = (token, tags) => ({
|
||||||
type: COMPOSE_SUGGESTIONS_READY,
|
type: COMPOSE_SUGGESTIONS_READY,
|
||||||
@ -510,7 +509,7 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
|
|||||||
path,
|
path,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function updateSuggestionTags(token) {
|
export function updateSuggestionTags(token) {
|
||||||
return {
|
return {
|
||||||
@ -558,39 +557,39 @@ export function mountCompose() {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_MOUNT,
|
type: COMPOSE_MOUNT,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmountCompose() {
|
export function unmountCompose() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UNMOUNT,
|
type: COMPOSE_UNMOUNT,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeComposeSensitivity() {
|
export function changeComposeSensitivity() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SENSITIVITY_CHANGE,
|
type: COMPOSE_SENSITIVITY_CHANGE,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeComposeSpoilerness() {
|
export function changeComposeSpoilerness() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SPOILERNESS_CHANGE,
|
type: COMPOSE_SPOILERNESS_CHANGE,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeComposeSpoilerText(text) {
|
export function changeComposeSpoilerText(text) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SPOILER_TEXT_CHANGE,
|
type: COMPOSE_SPOILER_TEXT_CHANGE,
|
||||||
text,
|
text,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeComposeVisibility(value) {
|
export function changeComposeVisibility(value) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_VISIBILITY_CHANGE,
|
type: COMPOSE_VISIBILITY_CHANGE,
|
||||||
value,
|
value,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function insertEmojiCompose(position, emoji, needsSpace) {
|
export function insertEmojiCompose(position, emoji, needsSpace) {
|
||||||
return {
|
return {
|
||||||
@ -599,33 +598,33 @@ export function insertEmojiCompose(position, emoji, needsSpace) {
|
|||||||
emoji,
|
emoji,
|
||||||
needsSpace,
|
needsSpace,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changeComposing(value) {
|
export function changeComposing(value) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_COMPOSING_CHANGE,
|
type: COMPOSE_COMPOSING_CHANGE,
|
||||||
value,
|
value,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function addPoll() {
|
export function addPoll() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_POLL_ADD,
|
type: COMPOSE_POLL_ADD,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function removePoll() {
|
export function removePoll() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_POLL_REMOVE,
|
type: COMPOSE_POLL_REMOVE,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function addPollOption(title) {
|
export function addPollOption(title) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_POLL_OPTION_ADD,
|
type: COMPOSE_POLL_OPTION_ADD,
|
||||||
title,
|
title,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changePollOption(index, title) {
|
export function changePollOption(index, title) {
|
||||||
return {
|
return {
|
||||||
@ -633,14 +632,14 @@ export function changePollOption(index, title) {
|
|||||||
index,
|
index,
|
||||||
title,
|
title,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function removePollOption(index) {
|
export function removePollOption(index) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_POLL_OPTION_REMOVE,
|
type: COMPOSE_POLL_OPTION_REMOVE,
|
||||||
index,
|
index,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function changePollSettings(expiresIn, isMultiple) {
|
export function changePollSettings(expiresIn, isMultiple) {
|
||||||
return {
|
return {
|
||||||
@ -648,4 +647,4 @@ export function changePollSettings(expiresIn, isMultiple) {
|
|||||||
expiresIn,
|
expiresIn,
|
||||||
isMultiple,
|
isMultiple,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api';
|
||||||
import {
|
import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer';
|
||||||
importFetchedAccounts,
|
|
||||||
importFetchedStatuses,
|
|
||||||
importFetchedStatus,
|
|
||||||
} from './importer';
|
|
||||||
|
|
||||||
export const CONVERSATIONS_MOUNT = 'CONVERSATIONS_MOUNT';
|
export const CONVERSATIONS_MOUNT = 'CONVERSATIONS_MOUNT';
|
||||||
export const CONVERSATIONS_UNMOUNT = 'CONVERSATIONS_UNMOUNT';
|
export const CONVERSATIONS_UNMOUNT = 'CONVERSATIONS_UNMOUNT';
|
||||||
|
|
||||||
export const CONVERSATIONS_FETCH_REQUEST = 'CONVERSATIONS_FETCH_REQUEST';
|
export const CONVERSATIONS_FETCH_REQUEST = 'CONVERSATIONS_FETCH_REQUEST';
|
||||||
export const CONVERSATIONS_FETCH_SUCCESS = 'CONVERSATIONS_FETCH_SUCCESS';
|
export const CONVERSATIONS_FETCH_SUCCESS = 'CONVERSATIONS_FETCH_SUCCESS';
|
||||||
export const CONVERSATIONS_FETCH_FAIL = 'CONVERSATIONS_FETCH_FAIL';
|
export const CONVERSATIONS_FETCH_FAIL = 'CONVERSATIONS_FETCH_FAIL';
|
||||||
export const CONVERSATIONS_UPDATE = 'CONVERSATIONS_UPDATE';
|
export const CONVERSATIONS_UPDATE = 'CONVERSATIONS_UPDATE';
|
||||||
|
|
||||||
export const CONVERSATIONS_READ = 'CONVERSATIONS_READ';
|
export const CONVERSATIONS_READ = 'CONVERSATIONS_READ';
|
||||||
|
|
||||||
export const CONVERSATIONS_DELETE_REQUEST = 'CONVERSATIONS_DELETE_REQUEST';
|
export const CONVERSATIONS_DELETE_REQUEST = 'CONVERSATIONS_DELETE_REQUEST';
|
||||||
export const CONVERSATIONS_DELETE_SUCCESS = 'CONVERSATIONS_DELETE_SUCCESS';
|
export const CONVERSATIONS_DELETE_SUCCESS = 'CONVERSATIONS_DELETE_SUCCESS';
|
||||||
export const CONVERSATIONS_DELETE_FAIL = 'CONVERSATIONS_DELETE_FAIL';
|
export const CONVERSATIONS_DELETE_FAIL = 'CONVERSATIONS_DELETE_FAIL';
|
||||||
|
|
||||||
export const mountConversations = () => ({
|
export const mountConversations = () => ({
|
||||||
type: CONVERSATIONS_MOUNT,
|
type: CONVERSATIONS_MOUNT,
|
||||||
@ -30,7 +26,7 @@ export const unmountConversations = () => ({
|
|||||||
export const markConversationRead = conversationId => (dispatch, getState) => {
|
export const markConversationRead = conversationId => (dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: CONVERSATIONS_READ,
|
type: CONVERSATIONS_READ,
|
||||||
id: conversationId,
|
id : conversationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
api(getState).post(`/api/v1/conversations/${conversationId}/read`);
|
api(getState).post(`/api/v1/conversations/${conversationId}/read`);
|
||||||
|
@ -24,7 +24,7 @@ export const fetchAccountIdentityProofsSuccess = (accountId, identity_proofs) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const fetchAccountIdentityProofsFail = (accountId, err) => ({
|
export const fetchAccountIdentityProofsFail = (accountId, err) => ({
|
||||||
type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
|
type : IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
|
||||||
accountId,
|
accountId,
|
||||||
err,
|
err,
|
||||||
skipNotFound: true,
|
skipNotFound: true,
|
||||||
|
@ -6,28 +6,29 @@ import { ensureComposeIsVisible } from './compose';
|
|||||||
|
|
||||||
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
|
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
|
||||||
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
|
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
|
||||||
export const STATUS_FETCH_FAIL = 'STATUS_FETCH_FAIL';
|
export const STATUS_FETCH_FAIL = 'STATUS_FETCH_FAIL';
|
||||||
|
|
||||||
export const STATUS_DELETE_REQUEST = 'STATUS_DELETE_REQUEST';
|
export const STATUS_DELETE_REQUEST = 'STATUS_DELETE_REQUEST';
|
||||||
export const STATUS_DELETE_SUCCESS = 'STATUS_DELETE_SUCCESS';
|
export const STATUS_DELETE_SUCCESS = 'STATUS_DELETE_SUCCESS';
|
||||||
export const STATUS_DELETE_FAIL = 'STATUS_DELETE_FAIL';
|
export const STATUS_DELETE_FAIL = 'STATUS_DELETE_FAIL';
|
||||||
|
|
||||||
export const CONTEXT_FETCH_REQUEST = 'CONTEXT_FETCH_REQUEST';
|
export const CONTEXT_FETCH_REQUEST = 'CONTEXT_FETCH_REQUEST';
|
||||||
export const CONTEXT_FETCH_SUCCESS = 'CONTEXT_FETCH_SUCCESS';
|
export const CONTEXT_FETCH_SUCCESS = 'CONTEXT_FETCH_SUCCESS';
|
||||||
export const CONTEXT_FETCH_FAIL = 'CONTEXT_FETCH_FAIL';
|
export const CONTEXT_FETCH_FAIL = 'CONTEXT_FETCH_FAIL';
|
||||||
|
|
||||||
export const STATUS_MUTE_REQUEST = 'STATUS_MUTE_REQUEST';
|
export const STATUS_MUTE_REQUEST = 'STATUS_MUTE_REQUEST';
|
||||||
export const STATUS_MUTE_SUCCESS = 'STATUS_MUTE_SUCCESS';
|
export const STATUS_MUTE_SUCCESS = 'STATUS_MUTE_SUCCESS';
|
||||||
export const STATUS_MUTE_FAIL = 'STATUS_MUTE_FAIL';
|
export const STATUS_MUTE_FAIL = 'STATUS_MUTE_FAIL';
|
||||||
|
|
||||||
export const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST';
|
export const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST';
|
||||||
export const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS';
|
export const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS';
|
||||||
export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL';
|
export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL';
|
||||||
|
|
||||||
export const STATUS_REVEAL = 'STATUS_REVEAL';
|
export const STATUS_REVEAL = 'STATUS_REVEAL';
|
||||||
export const STATUS_HIDE = 'STATUS_HIDE';
|
|
||||||
export const STATUS_COLLAPSE = 'STATUS_COLLAPSE';
|
export const STATUS_COLLAPSE = 'STATUS_COLLAPSE';
|
||||||
|
|
||||||
|
export const STATUS_HIDE = 'STATUS_HIDE';
|
||||||
|
|
||||||
export const REDRAFT = 'REDRAFT';
|
export const REDRAFT = 'REDRAFT';
|
||||||
|
|
||||||
export function fetchStatusRequest(id, skipLoading) {
|
export function fetchStatusRequest(id, skipLoading) {
|
||||||
@ -36,7 +37,7 @@ export function fetchStatusRequest(id, skipLoading) {
|
|||||||
id,
|
id,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchStatus(id) {
|
export function fetchStatus(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -57,24 +58,24 @@ export function fetchStatus(id) {
|
|||||||
dispatch(fetchStatusFail(id, error, skipLoading));
|
dispatch(fetchStatusFail(id, error, skipLoading));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchStatusSuccess(skipLoading) {
|
export function fetchStatusSuccess(skipLoading) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_FETCH_SUCCESS,
|
type: STATUS_FETCH_SUCCESS,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchStatusFail(id, error, skipLoading) {
|
export function fetchStatusFail(id, error, skipLoading) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_FETCH_FAIL,
|
type : STATUS_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
skipAlert: true,
|
skipAlert: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function redraft(status, raw_text) {
|
export function redraft(status, raw_text) {
|
||||||
return {
|
return {
|
||||||
@ -82,7 +83,7 @@ export function redraft(status, raw_text) {
|
|||||||
status,
|
status,
|
||||||
raw_text,
|
raw_text,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function deleteStatus(id, routerHistory, withRedraft = false) {
|
export function deleteStatus(id, routerHistory, withRedraft = false) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -107,36 +108,43 @@ export function deleteStatus(id, routerHistory, withRedraft = false) {
|
|||||||
dispatch(deleteStatusFail(id, error));
|
dispatch(deleteStatusFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function deleteStatusRequest(id) {
|
export function deleteStatusRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_DELETE_REQUEST,
|
type: STATUS_DELETE_REQUEST,
|
||||||
id: id,
|
id : id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function deleteStatusSuccess(id) {
|
export function deleteStatusSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_DELETE_SUCCESS,
|
type: STATUS_DELETE_SUCCESS,
|
||||||
id: id,
|
id : id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function deleteStatusFail(id, error) {
|
export function deleteStatusFail(id, error) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_DELETE_FAIL,
|
type : STATUS_DELETE_FAIL,
|
||||||
id: id,
|
id : id,
|
||||||
error: error,
|
error: error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchContext(id) {
|
export function fetchContext(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(fetchContextRequest(id));
|
dispatch(fetchContextRequest(id));
|
||||||
|
|
||||||
api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
|
api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
|
||||||
dispatch(importFetchedStatuses(response.data.ancestors.concat(response.data.descendants)));
|
/**
|
||||||
|
* TODO
|
||||||
|
* the goal here is to get a way to have all the status of a conversation somewhere
|
||||||
|
*/
|
||||||
|
const statusConcat = response.data.ancestors.concat(response.data.descendants);
|
||||||
|
console.log('statusConcat', statusConcat);
|
||||||
|
|
||||||
|
dispatch(importFetchedStatuses(statusConcat));
|
||||||
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
|
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
|
||||||
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -147,33 +155,33 @@ export function fetchContext(id) {
|
|||||||
dispatch(fetchContextFail(id, error));
|
dispatch(fetchContextFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchContextRequest(id) {
|
export function fetchContextRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: CONTEXT_FETCH_REQUEST,
|
type: CONTEXT_FETCH_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchContextSuccess(id, ancestors, descendants) {
|
export function fetchContextSuccess(id, ancestors, descendants) {
|
||||||
return {
|
return {
|
||||||
type: CONTEXT_FETCH_SUCCESS,
|
type : CONTEXT_FETCH_SUCCESS,
|
||||||
id,
|
id,
|
||||||
ancestors,
|
ancestors,
|
||||||
descendants,
|
descendants,
|
||||||
statuses: ancestors.concat(descendants),
|
statuses: ancestors.concat(descendants),
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchContextFail(id, error) {
|
export function fetchContextFail(id, error) {
|
||||||
return {
|
return {
|
||||||
type: CONTEXT_FETCH_FAIL,
|
type : CONTEXT_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipAlert: true,
|
skipAlert: true,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteStatus(id) {
|
export function muteStatus(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -185,21 +193,21 @@ export function muteStatus(id) {
|
|||||||
dispatch(muteStatusFail(id, error));
|
dispatch(muteStatusFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteStatusRequest(id) {
|
export function muteStatusRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_MUTE_REQUEST,
|
type: STATUS_MUTE_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteStatusSuccess(id) {
|
export function muteStatusSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_MUTE_SUCCESS,
|
type: STATUS_MUTE_SUCCESS,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function muteStatusFail(id, error) {
|
export function muteStatusFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -207,7 +215,7 @@ export function muteStatusFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteStatus(id) {
|
export function unmuteStatus(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -219,21 +227,21 @@ export function unmuteStatus(id) {
|
|||||||
dispatch(unmuteStatusFail(id, error));
|
dispatch(unmuteStatusFail(id, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteStatusRequest(id) {
|
export function unmuteStatusRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_UNMUTE_REQUEST,
|
type: STATUS_UNMUTE_REQUEST,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteStatusSuccess(id) {
|
export function unmuteStatusSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_UNMUTE_SUCCESS,
|
type: STATUS_UNMUTE_SUCCESS,
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function unmuteStatusFail(id, error) {
|
export function unmuteStatusFail(id, error) {
|
||||||
return {
|
return {
|
||||||
@ -241,7 +249,7 @@ export function unmuteStatusFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function hideStatus(ids) {
|
export function hideStatus(ids) {
|
||||||
if (!Array.isArray(ids)) {
|
if (!Array.isArray(ids)) {
|
||||||
@ -252,7 +260,7 @@ export function hideStatus(ids) {
|
|||||||
type: STATUS_HIDE,
|
type: STATUS_HIDE,
|
||||||
ids,
|
ids,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function revealStatus(ids) {
|
export function revealStatus(ids) {
|
||||||
if (!Array.isArray(ids)) {
|
if (!Array.isArray(ids)) {
|
||||||
@ -263,7 +271,7 @@ export function revealStatus(ids) {
|
|||||||
type: STATUS_REVEAL,
|
type: STATUS_REVEAL,
|
||||||
ids,
|
ids,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function toggleStatusCollapse(id, isCollapsed) {
|
export function toggleStatusCollapse(id, isCollapsed) {
|
||||||
return {
|
return {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
||||||
import { submitMarkers } from './markers';
|
import { submitMarkers } from './markers';
|
||||||
import api, { getLinks } from 'mastodon/api';
|
import api, { getLinks } from 'mastodon/api';
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||||
import compareId from 'mastodon/compare_id';
|
import compareId from 'mastodon/compare_id';
|
||||||
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
|
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ export function updateTimeline(timeline, status, accept) {
|
|||||||
dispatch(submitMarkers());
|
dispatch(submitMarkers());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function deleteFromTimelines(id) {
|
export function deleteFromTimelines(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -58,13 +58,13 @@ export function deleteFromTimelines(id) {
|
|||||||
reblogOf,
|
reblogOf,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function clearTimeline(timeline) {
|
export function clearTimeline(timeline) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch({ type: TIMELINE_CLEAR, timeline });
|
dispatch({ type: TIMELINE_CLEAR, timeline });
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
const noOp = () => {};
|
const noOp = () => {};
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
|
export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
|
||||||
export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote } = {}, done = noOp) => expandTimeline(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, max_id: maxId, only_media: !!onlyMedia }, done);
|
export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote } = {}, done = noOp) => expandTimeline(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, max_id: maxId, only_media: !!onlyMedia }, done);
|
||||||
@ -138,7 +138,7 @@ export function expandTimelineRequest(timeline, isLoadingMore) {
|
|||||||
timeline,
|
timeline,
|
||||||
skipLoading: !isLoadingMore,
|
skipLoading: !isLoadingMore,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingRecent, isLoadingMore, usePendingItems) {
|
export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingRecent, isLoadingMore, usePendingItems) {
|
||||||
return {
|
return {
|
||||||
@ -151,17 +151,17 @@ export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadi
|
|||||||
usePendingItems,
|
usePendingItems,
|
||||||
skipLoading: !isLoadingMore,
|
skipLoading: !isLoadingMore,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandTimelineFail(timeline, error, isLoadingMore) {
|
export function expandTimelineFail(timeline, error, isLoadingMore) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_EXPAND_FAIL,
|
type : TIMELINE_EXPAND_FAIL,
|
||||||
timeline,
|
timeline,
|
||||||
error,
|
error,
|
||||||
skipLoading: !isLoadingMore,
|
skipLoading : !isLoadingMore,
|
||||||
skipNotFound: timeline.startsWith('account:'),
|
skipNotFound: timeline.startsWith('account:'),
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function scrollTopTimeline(timeline, top) {
|
export function scrollTopTimeline(timeline, top) {
|
||||||
return {
|
return {
|
||||||
@ -169,14 +169,14 @@ export function scrollTopTimeline(timeline, top) {
|
|||||||
timeline,
|
timeline,
|
||||||
top,
|
top,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function connectTimeline(timeline) {
|
export function connectTimeline(timeline) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_CONNECT,
|
type: TIMELINE_CONNECT,
|
||||||
timeline,
|
timeline,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export const disconnectTimeline = timeline => ({
|
export const disconnectTimeline = timeline => ({
|
||||||
type: TIMELINE_DISCONNECT,
|
type: TIMELINE_DISCONNECT,
|
||||||
|
@ -9,4 +9,4 @@ export function start() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If called twice
|
// If called twice
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
@ -11,7 +11,7 @@ import classNames from 'classnames';
|
|||||||
const textAtCursorMatchesToken = (str, caretPosition) => {
|
const textAtCursorMatchesToken = (str, caretPosition) => {
|
||||||
let word;
|
let word;
|
||||||
|
|
||||||
let left = str.slice(0, caretPosition).search(/\S+$/);
|
let left = str.slice(0, caretPosition).search(/\S+$/);
|
||||||
let right = str.slice(caretPosition).search(/\s/);
|
let right = str.slice(caretPosition).search(/\s/);
|
||||||
|
|
||||||
if (right < 0) {
|
if (right < 0) {
|
||||||
@ -36,34 +36,37 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
|
|||||||
export default class AutosuggestTextarea extends ImmutablePureComponent {
|
export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value : PropTypes.string,
|
||||||
suggestions: ImmutablePropTypes.list,
|
suggestions : ImmutablePropTypes.list,
|
||||||
disabled: PropTypes.bool,
|
disabled : PropTypes.bool,
|
||||||
placeholder: PropTypes.string,
|
placeholder : PropTypes.string,
|
||||||
onSuggestionSelected: PropTypes.func.isRequired,
|
onSuggestionSelected : PropTypes.func.isRequired,
|
||||||
onSuggestionsClearRequested: PropTypes.func.isRequired,
|
onSuggestionsClearRequested: PropTypes.func.isRequired,
|
||||||
onSuggestionsFetchRequested: PropTypes.func.isRequired,
|
onSuggestionsFetchRequested: PropTypes.func.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange : PropTypes.func.isRequired,
|
||||||
onKeyUp: PropTypes.func,
|
onKeyUp : PropTypes.func,
|
||||||
onKeyDown: PropTypes.func,
|
onKeyDown : PropTypes.func,
|
||||||
onPaste: PropTypes.func.isRequired,
|
onPaste : PropTypes.func.isRequired,
|
||||||
autoFocus: PropTypes.bool,
|
autoFocus : PropTypes.bool,
|
||||||
|
directMessage : PropTypes.bool,
|
||||||
|
directMessageRecipient : PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
autoFocus: true,
|
autoFocus : true,
|
||||||
|
directMessage: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
suggestionsHidden: true,
|
suggestionsHidden : true,
|
||||||
focused: false,
|
focused : false,
|
||||||
selectedSuggestion: 0,
|
selectedSuggestion: 0,
|
||||||
lastToken: null,
|
lastToken : null,
|
||||||
tokenStart: 0,
|
tokenStart : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
onChange = (e) => {
|
onChange = (e) => {
|
||||||
const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
|
const [tokenStart, token] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
|
||||||
|
|
||||||
if (token !== null && this.state.lastToken !== token) {
|
if (token !== null && this.state.lastToken !== token) {
|
||||||
this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart });
|
this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart });
|
||||||
@ -74,7 +77,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.props.onChange(e);
|
this.props.onChange(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
onKeyDown = (e) => {
|
onKeyDown = (e) => {
|
||||||
const { suggestions, disabled } = this.props;
|
const { suggestions, disabled } = this.props;
|
||||||
@ -91,7 +94,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(e.key) {
|
switch (e.key) {
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
if (suggestions.size === 0 || suggestionsHidden) {
|
if (suggestions.size === 0 || suggestionsHidden) {
|
||||||
document.querySelector('.ui').parentElement.focus();
|
document.querySelector('.ui').parentElement.focus();
|
||||||
@ -123,7 +126,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion));
|
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,27 +134,27 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.props.onKeyDown(e);
|
this.props.onKeyDown(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
this.setState({ suggestionsHidden: true, focused: false });
|
this.setState({ suggestionsHidden: true, focused: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
onFocus = (e) => {
|
onFocus = (e) => {
|
||||||
this.setState({ focused: true });
|
this.setState({ focused: true });
|
||||||
if (this.props.onFocus) {
|
if (this.props.onFocus) {
|
||||||
this.props.onFocus(e);
|
this.props.onFocus(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionClick = (e) => {
|
onSuggestionClick = (e) => {
|
||||||
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
|
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
||||||
this.textarea.focus();
|
this.textarea.focus();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
||||||
this.setState({ suggestionsHidden: false });
|
this.setState({ suggestionsHidden: false });
|
||||||
}
|
}
|
||||||
@ -160,14 +162,14 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
|
|
||||||
setTextarea = (c) => {
|
setTextarea = (c) => {
|
||||||
this.textarea = c;
|
this.textarea = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
onPaste = (e) => {
|
onPaste = (e) => {
|
||||||
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
||||||
this.props.onPaste(e.clipboardData.files);
|
this.props.onPaste(e.clipboardData.files);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
renderSuggestion = (suggestion, i) => {
|
renderSuggestion = (suggestion, i) => {
|
||||||
const { selectedSuggestion } = this.state;
|
const { selectedSuggestion } = this.state;
|
||||||
@ -175,31 +177,41 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
|
|
||||||
if (suggestion.type === 'emoji') {
|
if (suggestion.type === 'emoji') {
|
||||||
inner = <AutosuggestEmoji emoji={suggestion} />;
|
inner = <AutosuggestEmoji emoji={suggestion} />;
|
||||||
key = suggestion.id;
|
key = suggestion.id;
|
||||||
} else if (suggestion.type === 'hashtag') {
|
} else if (suggestion.type === 'hashtag') {
|
||||||
inner = <AutosuggestHashtag tag={suggestion} />;
|
inner = <AutosuggestHashtag tag={suggestion} />;
|
||||||
key = suggestion.name;
|
key = suggestion.name;
|
||||||
} else if (suggestion.type === 'account') {
|
} else if (suggestion.type === 'account') {
|
||||||
inner = <AutosuggestAccountContainer id={suggestion.id} />;
|
inner = <AutosuggestAccountContainer id={suggestion.id} />;
|
||||||
key = suggestion.id;
|
key = suggestion.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div role='button' tabIndex='0' key={key} data-index={i} className={classNames('autosuggest-textarea__suggestions__item', { selected: i === selectedSuggestion })} onMouseDown={this.onSuggestionClick}>
|
<div
|
||||||
|
role='button'
|
||||||
|
tabIndex='0'
|
||||||
|
key={key}
|
||||||
|
data-index={i}
|
||||||
|
className={classNames('autosuggest-textarea__suggestions__item', { selected: i === selectedSuggestion })}
|
||||||
|
onMouseDown={this.onSuggestionClick}
|
||||||
|
>
|
||||||
{inner}
|
{inner}
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
|
||||||
const { suggestionsHidden } = this.state;
|
const { suggestionsHidden } = this.state;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<div className='compose-form__autosuggest-wrapper' key='autosuggest-wrapper'>
|
<div
|
||||||
|
className='compose-form__autosuggest-wrapper'
|
||||||
|
key='autosuggest-wrapper'
|
||||||
|
>
|
||||||
<div className='autosuggest-textarea'>
|
<div className='autosuggest-textarea'>
|
||||||
<label>
|
<label >
|
||||||
<span style={{ display: 'none' }}>{placeholder}</span>
|
<span style={{ display: 'none' }}>{placeholder}</span >
|
||||||
|
|
||||||
<Textarea
|
<Textarea
|
||||||
ref={this.setTextarea}
|
ref={this.setTextarea}
|
||||||
@ -217,16 +229,21 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
dir='auto'
|
dir='auto'
|
||||||
aria-autocomplete='list'
|
aria-autocomplete='list'
|
||||||
/>
|
/>
|
||||||
</label>
|
</label >
|
||||||
</div>
|
</div >
|
||||||
{children}
|
{children}
|
||||||
</div>,
|
</div >,
|
||||||
|
|
||||||
<div className='autosuggest-textarea__suggestions-wrapper' key='suggestions-wrapper'>
|
<div
|
||||||
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
|
className='autosuggest-textarea__suggestions-wrapper'
|
||||||
|
key='suggestions-wrapper'
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}
|
||||||
|
>
|
||||||
{suggestions.map(this.renderSuggestion)}
|
{suggestions.map(this.renderSuggestion)}
|
||||||
</div>
|
</div >
|
||||||
</div>,
|
</div >,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@ import { autoPlayGif } from 'mastodon/initial_state';
|
|||||||
export default class DisplayName extends React.PureComponent {
|
export default class DisplayName extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
account: ImmutablePropTypes.map.isRequired,
|
account : ImmutablePropTypes.map.isRequired,
|
||||||
others: ImmutablePropTypes.list,
|
others : ImmutablePropTypes.list,
|
||||||
localDomain: PropTypes.string,
|
localDomain: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
_updateEmojis () {
|
_updateEmojis() {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
|
|
||||||
if (!node || autoPlayGif) {
|
if (!node || autoPlayGif) {
|
||||||
@ -32,33 +32,40 @@ export default class DisplayName extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount() {
|
||||||
this._updateEmojis();
|
this._updateEmojis();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate () {
|
componentDidUpdate() {
|
||||||
this._updateEmojis();
|
this._updateEmojis();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEmojiMouseEnter = ({ target }) => {
|
handleEmojiMouseEnter = ({ target }) => {
|
||||||
target.src = target.getAttribute('data-original');
|
target.src = target.getAttribute('data-original');
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEmojiMouseLeave = ({ target }) => {
|
handleEmojiMouseLeave = ({ target }) => {
|
||||||
target.src = target.getAttribute('data-static');
|
target.src = target.getAttribute('data-static');
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { others, localDomain } = this.props;
|
const { others, localDomain } = this.props;
|
||||||
|
|
||||||
let displayName, suffix, account;
|
let displayName, suffix, account;
|
||||||
|
|
||||||
if (others && others.size > 1) {
|
if (others && others.size > 1) {
|
||||||
displayName = others.take(2).map(a => <bdi key={a.get('id')}><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi>).reduce((prev, cur) => [prev, ', ', cur]);
|
displayName = others.take(2).map(a =>
|
||||||
|
(<bdi key={a.get('id')}>
|
||||||
|
<strong
|
||||||
|
className='display-name__html'
|
||||||
|
dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</bdi >)).reduce((prev, cur) => [prev, ', ', cur]);
|
||||||
|
|
||||||
if (others.size - 2 > 0) {
|
if (others.size - 2 > 0) {
|
||||||
suffix = `+${others.size - 2}`;
|
suffix = `+${others.size - 2}`;
|
||||||
@ -76,14 +83,22 @@ export default class DisplayName extends React.PureComponent {
|
|||||||
acct = `${acct}@${localDomain}`;
|
acct = `${acct}@${localDomain}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayName = <bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi>;
|
displayName = (<bdi ><strong
|
||||||
suffix = <span className='display-name__account'>@{acct}</span>;
|
className='display-name__html'
|
||||||
|
dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</bdi >);
|
||||||
|
suffix = <span className='display-name__account'>@{acct}</span >;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className='display-name' ref={this.setRef}>
|
<span
|
||||||
|
className='display-name'
|
||||||
|
ref={this.setRef}
|
||||||
|
>
|
||||||
{displayName} {suffix}
|
{displayName} {suffix}
|
||||||
</span>
|
</span >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class Account extends ImmutablePureComponent {
|
|||||||
|
|
||||||
handleDomainUnblock = () => {
|
handleDomainUnblock = () => {
|
||||||
this.props.onUnblockDomain(this.props.domain);
|
this.props.onUnblockDomain(this.props.domain);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { domain, intl } = this.props;
|
const { domain, intl } = this.props;
|
||||||
|
@ -128,11 +128,13 @@ class DropdownMenu extends React.PureComponent {
|
|||||||
return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
|
return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { text, href = '#', target = '_blank', method } = option;
|
const { text, href = '#', target = '_blank', method, iconName } = option;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className='dropdown-menu__item' key={`${text}-${i}`}>
|
<li className='dropdown-menu__item' key={`${text}-${i}`}>
|
||||||
<a href={href} target={target} data-method={method} rel='noopener noreferrer' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
|
<a href={href} target={target} data-method={method} rel='noopener noreferrer' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
|
||||||
|
|
||||||
|
<i className={'fa fa-'+iconName} />
|
||||||
{text}
|
{text}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
133
app/javascript/mastodon/components/gallery.js
Normal file
133
app/javascript/mastodon/components/gallery.js
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import { debounce } from 'lodash';
|
||||||
|
import React from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import StatusContainer from '../containers/status_container';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
|
import LoadGap from './load_gap';
|
||||||
|
import ScrollableList from './scrollable_list';
|
||||||
|
import RegenerationIndicator from 'mastodon/components/regeneration_indicator';
|
||||||
|
|
||||||
|
export default class Gallery extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
scrollKey : PropTypes.string.isRequired,
|
||||||
|
statusIds : ImmutablePropTypes.list.isRequired,
|
||||||
|
featuredStatusIds : ImmutablePropTypes.list,
|
||||||
|
onLoadMore : PropTypes.func,
|
||||||
|
onScrollToTop : PropTypes.func,
|
||||||
|
onScroll : PropTypes.func,
|
||||||
|
trackScroll : PropTypes.bool,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
|
isLoading : PropTypes.bool,
|
||||||
|
isPartial : PropTypes.bool,
|
||||||
|
hasMore : PropTypes.bool,
|
||||||
|
prepend : PropTypes.node,
|
||||||
|
emptyMessage : PropTypes.node,
|
||||||
|
alwaysPrepend : PropTypes.bool,
|
||||||
|
timelineId : PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
trackScroll: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
getFeaturedStatusCount = () => {
|
||||||
|
return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
getCurrentStatusIndex = (id, featured) => {
|
||||||
|
if (featured) {
|
||||||
|
return this.props.featuredStatusIds.indexOf(id);
|
||||||
|
} else {
|
||||||
|
return this.props.statusIds.indexOf(id) + this.getFeaturedStatusCount();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleMoveUp = (id, featured) => {
|
||||||
|
const elementIndex = this.getCurrentStatusIndex(id, featured) - 1;
|
||||||
|
this._selectChild(elementIndex, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleMoveDown = (id, featured) => {
|
||||||
|
const elementIndex = this.getCurrentStatusIndex(id, featured) + 1;
|
||||||
|
this._selectChild(elementIndex, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleLoadOlder = debounce(() => {
|
||||||
|
this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
|
||||||
|
}, 300, { leading: true });
|
||||||
|
|
||||||
|
_selectChild(index, align_top) {
|
||||||
|
const container = this.node.node;
|
||||||
|
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
if (align_top && container.scrollTop > element.offsetTop) {
|
||||||
|
element.scrollIntoView(true);
|
||||||
|
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
|
||||||
|
element.scrollIntoView(false);
|
||||||
|
}
|
||||||
|
element.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setRef = c => {
|
||||||
|
this.node = c;
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { statusIds, featuredStatusIds, shouldUpdateScroll, onLoadMore, timelineId, ...other } = this.props;
|
||||||
|
const { isLoading, isPartial } = other;
|
||||||
|
|
||||||
|
if (isPartial) {
|
||||||
|
return <RegenerationIndicator />;
|
||||||
|
}
|
||||||
|
|
||||||
|
let scrollableContent = (isLoading || statusIds.size > 0) ? (
|
||||||
|
statusIds.map((statusId, index) => statusId === null ? (
|
||||||
|
<LoadGap
|
||||||
|
key={'gap:' + statusIds.get(index + 1)}
|
||||||
|
disabled={isLoading}
|
||||||
|
maxId={index > 0 ? statusIds.get(index - 1) : null}
|
||||||
|
onClick={onLoadMore}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<StatusContainer
|
||||||
|
key={statusId}
|
||||||
|
id={statusId}
|
||||||
|
onMoveUp={this.handleMoveUp}
|
||||||
|
onMoveDown={this.handleMoveDown}
|
||||||
|
contextType={timelineId}
|
||||||
|
showThread
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
if (scrollableContent && featuredStatusIds) {
|
||||||
|
scrollableContent = featuredStatusIds.map(statusId => (
|
||||||
|
<StatusContainer
|
||||||
|
key={`f-${statusId}`}
|
||||||
|
id={statusId}
|
||||||
|
featured
|
||||||
|
onMoveUp={this.handleMoveUp}
|
||||||
|
onMoveDown={this.handleMoveDown}
|
||||||
|
contextType={timelineId}
|
||||||
|
showThread
|
||||||
|
/>
|
||||||
|
)).concat(scrollableContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollableList
|
||||||
|
{...other} showLoading={isLoading && statusIds.size === 0}
|
||||||
|
onLoadMore={onLoadMore && this.handleLoadOlder}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
|
ref={this.setRef}
|
||||||
|
>
|
||||||
|
{scrollableContent}
|
||||||
|
</ScrollableList >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -120,7 +120,7 @@ export default class IconButton extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (typeof counter !== 'undefined') {
|
if (typeof counter !== 'undefined') {
|
||||||
style.width = 'auto';
|
style.width = '100%';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -98,7 +98,7 @@ class ScrollableList extends PureComponent {
|
|||||||
} else {
|
} else {
|
||||||
return this.node;
|
return this.node;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setScrollTop = newScrollTop => {
|
setScrollTop = newScrollTop => {
|
||||||
if (this.getScrollTop() !== newScrollTop) {
|
if (this.getScrollTop() !== newScrollTop) {
|
||||||
@ -144,7 +144,7 @@ class ScrollableList extends PureComponent {
|
|||||||
|
|
||||||
this.mouseMovedRecently = false;
|
this.mouseMovedRecently = false;
|
||||||
this.scrollToTopOnMouseIdle = false;
|
this.scrollToTopOnMouseIdle = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.attachScrollListener();
|
this.attachScrollListener();
|
||||||
@ -162,25 +162,25 @@ class ScrollableList extends PureComponent {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getScrollTop = () => {
|
getScrollTop = () => {
|
||||||
return this._getScrollingElement().scrollTop;
|
return this._getScrollingElement().scrollTop;
|
||||||
}
|
};
|
||||||
|
|
||||||
getScrollHeight = () => {
|
getScrollHeight = () => {
|
||||||
return this._getScrollingElement().scrollHeight;
|
return this._getScrollingElement().scrollHeight;
|
||||||
}
|
};
|
||||||
|
|
||||||
getClientHeight = () => {
|
getClientHeight = () => {
|
||||||
return this._getScrollingElement().clientHeight;
|
return this._getScrollingElement().clientHeight;
|
||||||
}
|
};
|
||||||
|
|
||||||
updateScrollBottom = (snapshot) => {
|
updateScrollBottom = (snapshot) => {
|
||||||
const newScrollTop = this.getScrollHeight() - snapshot;
|
const newScrollTop = this.getScrollHeight() - snapshot;
|
||||||
|
|
||||||
this.setScrollTop(newScrollTop);
|
this.setScrollTop(newScrollTop);
|
||||||
}
|
};
|
||||||
|
|
||||||
getSnapshotBeforeUpdate (prevProps) {
|
getSnapshotBeforeUpdate (prevProps) {
|
||||||
const someItemInserted = React.Children.count(prevProps.children) > 0 &&
|
const someItemInserted = React.Children.count(prevProps.children) > 0 &&
|
||||||
@ -207,7 +207,7 @@ class ScrollableList extends PureComponent {
|
|||||||
if (width && this.state.cachedMediaWidth !== width) {
|
if (width && this.state.cachedMediaWidth !== width) {
|
||||||
this.setState({ cachedMediaWidth: width });
|
this.setState({ cachedMediaWidth: width });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
this.clearMouseIdleTimer();
|
this.clearMouseIdleTimer();
|
||||||
@ -219,7 +219,7 @@ class ScrollableList extends PureComponent {
|
|||||||
|
|
||||||
onFullScreenChange = () => {
|
onFullScreenChange = () => {
|
||||||
this.setState({ fullscreen: isFullscreen() });
|
this.setState({ fullscreen: isFullscreen() });
|
||||||
}
|
};
|
||||||
|
|
||||||
attachIntersectionObserver () {
|
attachIntersectionObserver () {
|
||||||
let nodeOptions = {
|
let nodeOptions = {
|
||||||
@ -270,12 +270,12 @@ class ScrollableList extends PureComponent {
|
|||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = e => {
|
handleLoadMore = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onLoadMore();
|
this.props.onLoadMore();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadPending = e => {
|
handleLoadPending = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -287,7 +287,7 @@ class ScrollableList extends PureComponent {
|
|||||||
this.clearMouseIdleTimer();
|
this.clearMouseIdleTimer();
|
||||||
this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
|
this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
|
||||||
this.mouseMovedRecently = true;
|
this.mouseMovedRecently = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, numPending, prepend, alwaysPrepend, append, emptyMessage, onLoadMore } = this.props;
|
const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, numPending, prepend, alwaysPrepend, append, emptyMessage, onLoadMore } = this.props;
|
||||||
|
@ -6,41 +6,41 @@ import IconButton from './icon_button';
|
|||||||
import DropdownMenuContainer from '../containers/dropdown_menu_container';
|
import DropdownMenuContainer from '../containers/dropdown_menu_container';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { me, isStaff } from '../initial_state';
|
import { isStaff, me } from '../initial_state';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
delete : { id: 'status.delete', defaultMessage: 'Delete' },
|
||||||
redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
|
redraft : { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
|
||||||
direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
|
direct : { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
|
||||||
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
mention : { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
||||||
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
mute : { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||||
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
block : { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||||
reply: { id: 'status.reply', defaultMessage: 'Reply' },
|
reply : { id: 'status.reply', defaultMessage: 'Reply' },
|
||||||
share: { id: 'status.share', defaultMessage: 'Share' },
|
share : { id: 'status.share', defaultMessage: 'Share' },
|
||||||
more: { id: 'status.more', defaultMessage: 'More' },
|
more : { id: 'status.more', defaultMessage: 'More' },
|
||||||
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
|
replyAll : { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
|
||||||
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
reblog : { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||||
reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' },
|
reblog_private : { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' },
|
||||||
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
|
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
|
||||||
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
|
cannot_reblog : { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
|
||||||
favourite: { id: 'status.favourite', defaultMessage: 'Favourite' },
|
favourite : { id: 'status.favourite', defaultMessage: 'Favourite' },
|
||||||
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
bookmark : { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
||||||
removeBookmark: { id: 'status.remove_bookmark', defaultMessage: 'Remove bookmark' },
|
removeBookmark : { id: 'status.remove_bookmark', defaultMessage: 'Remove bookmark' },
|
||||||
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
open : { id: 'status.open', defaultMessage: 'Expand this status' },
|
||||||
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
|
report : { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||||
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
muteConversation : { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||||
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
unmuteConversation : { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||||
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
pin : { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
||||||
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
|
unpin : { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
|
||||||
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
embed : { id: 'status.embed', defaultMessage: 'Embed' },
|
||||||
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
admin_account : { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||||
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
|
admin_status : { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
|
||||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
|
copy : { id: 'status.copy', defaultMessage: 'Copy link to status' },
|
||||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
blockDomain : { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
unblockDomain : { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
unmute : { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||||
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
unblock : { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state, { status }) => ({
|
const mapStateToProps = (state, { status }) => ({
|
||||||
@ -56,28 +56,29 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status : ImmutablePropTypes.map.isRequired,
|
||||||
relationship: ImmutablePropTypes.map,
|
relationship : ImmutablePropTypes.map,
|
||||||
onReply: PropTypes.func,
|
onReply : PropTypes.func,
|
||||||
onFavourite: PropTypes.func,
|
onFavourite : PropTypes.func,
|
||||||
onReblog: PropTypes.func,
|
onReblog : PropTypes.func,
|
||||||
onDelete: PropTypes.func,
|
onDelete : PropTypes.func,
|
||||||
onDirect: PropTypes.func,
|
onDirect : PropTypes.func,
|
||||||
onMention: PropTypes.func,
|
onMention : PropTypes.func,
|
||||||
onMute: PropTypes.func,
|
onMute : PropTypes.func,
|
||||||
onUnmute: PropTypes.func,
|
onUnmute : PropTypes.func,
|
||||||
onBlock: PropTypes.func,
|
onBlock : PropTypes.func,
|
||||||
onUnblock: PropTypes.func,
|
onUnblock : PropTypes.func,
|
||||||
onBlockDomain: PropTypes.func,
|
onBlockDomain : PropTypes.func,
|
||||||
onUnblockDomain: PropTypes.func,
|
onUnblockDomain : PropTypes.func,
|
||||||
onReport: PropTypes.func,
|
onReport : PropTypes.func,
|
||||||
onEmbed: PropTypes.func,
|
onEmbed : PropTypes.func,
|
||||||
onMuteConversation: PropTypes.func,
|
onMuteConversation : PropTypes.func,
|
||||||
onPin: PropTypes.func,
|
onPin : PropTypes.func,
|
||||||
onBookmark: PropTypes.func,
|
onBookmark : PropTypes.func,
|
||||||
withDismiss: PropTypes.bool,
|
withDismiss : PropTypes.bool,
|
||||||
scrollKey: PropTypes.string,
|
enableSoMuchAnswersWow: PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
scrollKey : PropTypes.string,
|
||||||
|
intl : PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Avoid checking props that are functions (and whose equality will always
|
// Avoid checking props that are functions (and whose equality will always
|
||||||
@ -86,7 +87,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
'status',
|
'status',
|
||||||
'relationship',
|
'relationship',
|
||||||
'withDismiss',
|
'withDismiss',
|
||||||
]
|
];
|
||||||
|
|
||||||
handleReplyClick = () => {
|
handleReplyClick = () => {
|
||||||
if (me) {
|
if (me) {
|
||||||
@ -94,16 +95,16 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
} else {
|
} else {
|
||||||
this._openInteractionDialog('reply');
|
this._openInteractionDialog('reply');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleShareClick = () => {
|
handleShareClick = () => {
|
||||||
navigator.share({
|
navigator.share({
|
||||||
text: this.props.status.get('search_index'),
|
text: this.props.status.get('search_index'),
|
||||||
url: this.props.status.get('url'),
|
url : this.props.status.get('url'),
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
if (e.name !== 'AbortError') console.error(e);
|
if (e.name !== 'AbortError') console.error(e);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFavouriteClick = () => {
|
handleFavouriteClick = () => {
|
||||||
if (me) {
|
if (me) {
|
||||||
@ -111,7 +112,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
} else {
|
} else {
|
||||||
this._openInteractionDialog('favourite');
|
this._openInteractionDialog('favourite');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReblogClick = e => {
|
handleReblogClick = e => {
|
||||||
if (me) {
|
if (me) {
|
||||||
@ -119,35 +120,35 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
} else {
|
} else {
|
||||||
this._openInteractionDialog('reblog');
|
this._openInteractionDialog('reblog');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_openInteractionDialog = type => {
|
_openInteractionDialog = type => {
|
||||||
window.open(`/interact/${this.props.status.get('id')}?type=${type}`, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
window.open(`/interact/${this.props.status.get('id')}?type=${type}`, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBookmarkClick = () => {
|
handleBookmarkClick = () => {
|
||||||
this.props.onBookmark(this.props.status);
|
this.props.onBookmark(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDeleteClick = () => {
|
handleDeleteClick = () => {
|
||||||
this.props.onDelete(this.props.status, this.context.router.history);
|
this.props.onDelete(this.props.status, this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRedraftClick = () => {
|
handleRedraftClick = () => {
|
||||||
this.props.onDelete(this.props.status, this.context.router.history, true);
|
this.props.onDelete(this.props.status, this.context.router.history, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handlePinClick = () => {
|
handlePinClick = () => {
|
||||||
this.props.onPin(this.props.status);
|
this.props.onPin(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMentionClick = () => {
|
handleMentionClick = () => {
|
||||||
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDirectClick = () => {
|
handleDirectClick = () => {
|
||||||
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
|
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMuteClick = () => {
|
handleMuteClick = () => {
|
||||||
const { status, relationship, onMute, onUnmute } = this.props;
|
const { status, relationship, onMute, onUnmute } = this.props;
|
||||||
@ -158,7 +159,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
} else {
|
} else {
|
||||||
onMute(account);
|
onMute(account);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlockClick = () => {
|
handleBlockClick = () => {
|
||||||
const { status, relationship, onBlock, onUnblock } = this.props;
|
const { status, relationship, onBlock, onUnblock } = this.props;
|
||||||
@ -169,43 +170,43 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
} else {
|
} else {
|
||||||
onBlock(status);
|
onBlock(status);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlockDomain = () => {
|
handleBlockDomain = () => {
|
||||||
const { status, onBlockDomain } = this.props;
|
const { status, onBlockDomain } = this.props;
|
||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
|
|
||||||
onBlockDomain(account.get('acct').split('@')[1]);
|
onBlockDomain(account.get('acct').split('@')[1]);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleUnblockDomain = () => {
|
handleUnblockDomain = () => {
|
||||||
const { status, onUnblockDomain } = this.props;
|
const { status, onUnblockDomain } = this.props;
|
||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
|
|
||||||
onUnblockDomain(account.get('acct').split('@')[1]);
|
onUnblockDomain(account.get('acct').split('@')[1]);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpen = () => {
|
handleOpen = () => {
|
||||||
this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
|
this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEmbed = () => {
|
handleEmbed = () => {
|
||||||
this.props.onEmbed(this.props.status);
|
this.props.onEmbed(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReport = () => {
|
handleReport = () => {
|
||||||
this.props.onReport(this.props.status);
|
this.props.onReport(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleConversationMuteClick = () => {
|
handleConversationMuteClick = () => {
|
||||||
this.props.onMuteConversation(this.props.status);
|
this.props.onMuteConversation(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleCopy = () => {
|
handleCopy = () => {
|
||||||
const url = this.props.status.get('url');
|
const url = this.props.status.get('url');
|
||||||
const textarea = document.createElement('textarea');
|
const textarea = document.createElement('textarea');
|
||||||
|
|
||||||
textarea.textContent = url;
|
textarea.textContent = url;
|
||||||
textarea.style.position = 'fixed';
|
textarea.style.position = 'fixed';
|
||||||
|
|
||||||
document.body.appendChild(textarea);
|
document.body.appendChild(textarea);
|
||||||
@ -218,58 +219,97 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
} finally {
|
} finally {
|
||||||
document.body.removeChild(textarea);
|
document.body.removeChild(textarea);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { status, relationship, intl, withDismiss, scrollKey } = this.props;
|
const { status, relationship, intl, withDismiss, scrollKey } = this.props;
|
||||||
|
|
||||||
const mutingConversation = status.get('muted');
|
const mutingConversation = status.get('muted');
|
||||||
const anonymousAccess = !me;
|
const anonymousAccess = !me;
|
||||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
|
|
||||||
let menu = [];
|
let menu = [];
|
||||||
|
|
||||||
menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen });
|
menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen, iconName: 'arrow-right' });
|
||||||
|
|
||||||
if (publicStatus) {
|
if (publicStatus) {
|
||||||
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
|
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy, iconName: 'copy' });
|
||||||
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed, iconName: 'screen' });
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.push({ text: intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark), action: this.handleBookmarkClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark),
|
||||||
|
action : this.handleBookmarkClick,
|
||||||
|
iconName: 'bookmark',
|
||||||
|
});
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
|
||||||
if (status.getIn(['account', 'id']) === me || withDismiss) {
|
if (status.getIn(['account', 'id']) === me || withDismiss) {
|
||||||
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
||||||
|
action: this.handleConversationMuteClick, iconName: 'hide',
|
||||||
|
});
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.getIn(['account', 'id']) === me) {
|
if (status.getIn(['account', 'id']) === me) {
|
||||||
if (publicStatus) {
|
if (publicStatus) {
|
||||||
menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin),
|
||||||
|
action : this.handlePinClick,
|
||||||
|
iconName: 'gears',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||||
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick });
|
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick });
|
||||||
} else {
|
} else {
|
||||||
menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.handleMentionClick });
|
menu.push({
|
||||||
menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.handleDirectClick });
|
text : intl.formatMessage(messages.mention, { name: account.get('username') }),
|
||||||
|
action : this.handleMentionClick,
|
||||||
|
iconName: 'plane',
|
||||||
|
});
|
||||||
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.direct, { name: account.get('username') }),
|
||||||
|
action : this.handleDirectClick,
|
||||||
|
iconName: 'enveloppe-o',
|
||||||
|
});
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
|
||||||
if (relationship && relationship.get('muting')) {
|
if (relationship && relationship.get('muting')) {
|
||||||
menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.handleMuteClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.unmute, { name: account.get('username') }),
|
||||||
|
action : this.handleMuteClick,
|
||||||
|
iconName: 'times',
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.handleMuteClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.mute, { name: account.get('username') }),
|
||||||
|
action : this.handleMuteClick,
|
||||||
|
iconName: 'times',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relationship && relationship.get('blocking')) {
|
if (relationship && relationship.get('blocking')) {
|
||||||
menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.handleBlockClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.unblock, { name: account.get('username') }),
|
||||||
|
action : this.handleBlockClick,
|
||||||
|
iconName: 'plus',
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.handleBlockClick });
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.block, { name: account.get('username') }),
|
||||||
|
action : this.handleBlockClick,
|
||||||
|
iconName: 'times',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.handleReport });
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.report, { name: account.get('username') }),
|
||||||
|
action : this.handleReport,
|
||||||
|
iconName: 'flag',
|
||||||
|
});
|
||||||
|
|
||||||
if (account.get('acct') !== account.get('username')) {
|
if (account.get('acct') !== account.get('username')) {
|
||||||
const domain = account.get('acct').split('@')[1];
|
const domain = account.get('acct').split('@')[1];
|
||||||
@ -285,8 +325,18 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
|
|
||||||
if (isStaff) {
|
if (isStaff) {
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
menu.push({
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
text : intl.formatMessage(messages.admin_account,
|
||||||
|
{ name: account.get('username') }),
|
||||||
|
href : `/admin/accounts/${status.getIn(['account', 'id'])}`,
|
||||||
|
iconName: 'gears',
|
||||||
|
|
||||||
|
});
|
||||||
|
menu.push({
|
||||||
|
text : intl.formatMessage(messages.admin_status),
|
||||||
|
href : `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}`,
|
||||||
|
iconName: 'menu',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,14 +364,48 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const shareButton = ('share' in navigator) && publicStatus && (
|
const shareButton = ('share' in navigator) && publicStatus && (
|
||||||
<IconButton className='status__action-bar-button' title={intl.formatMessage(messages.share)} icon='share-alt' onClick={this.handleShareClick} />
|
<IconButton
|
||||||
|
className='status__action-bar-button'
|
||||||
|
title={intl.formatMessage(messages.share)}
|
||||||
|
icon='share-alt'
|
||||||
|
onClick={this.handleShareClick}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
let countAnswers = status.get('replies_count') * 1;
|
||||||
|
|
||||||
|
const enableSoMuchAnswersWOW = false;
|
||||||
|
if (enableSoMuchAnswersWOW) {
|
||||||
|
countAnswers += Math.floor(Math.random() * Math.floor(500000));
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='status__action-bar'>
|
<div className='status__action-bar'>
|
||||||
<IconButton className='status__action-bar-button' title={replyTitle} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} counter={status.get('replies_count')} obfuscateCount />
|
<IconButton
|
||||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} pressed={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} />
|
className='status__action-bar-button reply_button'
|
||||||
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />
|
title={replyTitle}
|
||||||
|
icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon}
|
||||||
|
onClick={this.handleReplyClick}
|
||||||
|
counter={countAnswers}
|
||||||
|
obfuscateCount={false}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
className={classNames('status__action-bar-button', { reblogPrivate })}
|
||||||
|
disabled={!publicStatus && !reblogPrivate}
|
||||||
|
active={status.get('reblogged')}
|
||||||
|
pressed={status.get('reblogged')}
|
||||||
|
title={reblogTitle}
|
||||||
|
icon='retweet'
|
||||||
|
onClick={this.handleReblogClick}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
className='status__action-bar-button star-icon'
|
||||||
|
animate
|
||||||
|
active={status.get('favourited')}
|
||||||
|
pressed={status.get('favourited')}
|
||||||
|
title={intl.formatMessage(messages.favourite)}
|
||||||
|
icon='star'
|
||||||
|
onClick={this.handleFavouriteClick}
|
||||||
|
/>
|
||||||
|
|
||||||
{shareButton}
|
{shareButton}
|
||||||
|
|
||||||
@ -336,8 +420,8 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
direction='right'
|
direction='right'
|
||||||
title={intl.formatMessage(messages.more)}
|
title={intl.formatMessage(messages.more)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div >
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import { FormattedMessage } from 'react-intl';
|
|||||||
import Permalink from './permalink';
|
import Permalink from './permalink';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import PollContainer from 'mastodon/containers/poll_container';
|
import PollContainer from 'mastodon/containers/poll_container';
|
||||||
import Icon from 'mastodon/components/icon';
|
|
||||||
import { autoPlayGif } from 'mastodon/initial_state';
|
import { autoPlayGif } from 'mastodon/initial_state';
|
||||||
|
|
||||||
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
|
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
|
||||||
@ -17,12 +16,12 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status : ImmutablePropTypes.map.isRequired,
|
||||||
expanded: PropTypes.bool,
|
expanded : PropTypes.bool,
|
||||||
showThread: PropTypes.bool,
|
showThread : PropTypes.bool,
|
||||||
onExpandedToggle: PropTypes.func,
|
onExpandedToggle : PropTypes.func,
|
||||||
onClick: PropTypes.func,
|
onClick : PropTypes.func,
|
||||||
collapsable: PropTypes.bool,
|
collapsable : PropTypes.bool,
|
||||||
onCollapsedToggle: PropTypes.func,
|
onCollapsedToggle: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
_updateStatusLinks () {
|
_updateStatusLinks() {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@ -64,18 +63,18 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
|
|
||||||
if (this.props.status.get('collapsed', null) === null) {
|
if (this.props.status.get('collapsed', null) === null) {
|
||||||
let collapsed =
|
let collapsed =
|
||||||
this.props.collapsable
|
this.props.collapsable
|
||||||
&& this.props.onClick
|
&& this.props.onClick
|
||||||
&& node.clientHeight > MAX_HEIGHT
|
&& node.clientHeight > MAX_HEIGHT
|
||||||
&& this.props.status.get('spoiler_text').length === 0;
|
&& this.props.status.get('spoiler_text').length === 0;
|
||||||
|
|
||||||
if(this.props.onCollapsedToggle) this.props.onCollapsedToggle(collapsed);
|
if (this.props.onCollapsedToggle) this.props.onCollapsedToggle(collapsed);
|
||||||
|
|
||||||
this.props.status.set('collapsed', collapsed);
|
this.props.status.set('collapsed', collapsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateStatusEmojis () {
|
_updateStatusEmojis() {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
|
|
||||||
if (!node || autoPlayGif) {
|
if (!node || autoPlayGif) {
|
||||||
@ -96,12 +95,12 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount() {
|
||||||
this._updateStatusLinks();
|
this._updateStatusLinks();
|
||||||
this._updateStatusEmojis();
|
this._updateStatusEmojis();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate () {
|
componentDidUpdate() {
|
||||||
this._updateStatusLinks();
|
this._updateStatusLinks();
|
||||||
this._updateStatusEmojis();
|
this._updateStatusEmojis();
|
||||||
}
|
}
|
||||||
@ -111,7 +110,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/accounts/${mention.get('id')}`);
|
this.context.router.history.push(`/accounts/${mention.get('id')}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onHashtagClick = (hashtag, e) => {
|
onHashtagClick = (hashtag, e) => {
|
||||||
hashtag = hashtag.replace(/^#/, '');
|
hashtag = hashtag.replace(/^#/, '');
|
||||||
@ -120,27 +119,27 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/timelines/tag/${hashtag}`);
|
this.context.router.history.push(`/timelines/tag/${hashtag}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEmojiMouseEnter = ({ target }) => {
|
handleEmojiMouseEnter = ({ target }) => {
|
||||||
target.src = target.getAttribute('data-original');
|
target.src = target.getAttribute('data-original');
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEmojiMouseLeave = ({ target }) => {
|
handleEmojiMouseLeave = ({ target }) => {
|
||||||
target.src = target.getAttribute('data-static');
|
target.src = target.getAttribute('data-static');
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseDown = (e) => {
|
handleMouseDown = (e) => {
|
||||||
this.startXY = [e.clientX, e.clientY];
|
this.startXY = [e.clientX, e.clientY];
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseUp = (e) => {
|
handleMouseUp = (e) => {
|
||||||
if (!this.startXY) {
|
if (!this.startXY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [ startX, startY ] = this.startXY;
|
const [startX, startY] = this.startXY;
|
||||||
const [ deltaX, deltaY ] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
|
const [deltaX, deltaY] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
|
||||||
|
|
||||||
let element = e.target;
|
let element = e.target;
|
||||||
while (element) {
|
while (element) {
|
||||||
@ -155,7 +154,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.startXY = null;
|
this.startXY = null;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSpoilerClick = (e) => {
|
handleSpoilerClick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -166,13 +165,13 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
} else {
|
} else {
|
||||||
this.setState({ hidden: !this.state.hidden });
|
this.setState({ hidden: !this.state.hidden });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { status } = this.props;
|
const { status } = this.props;
|
||||||
|
|
||||||
if (status.get('content').length === 0) {
|
if (status.get('content').length === 0) {
|
||||||
@ -186,36 +185,67 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
const content = { __html: status.get('contentHtml') };
|
const content = { __html: status.get('contentHtml') };
|
||||||
const spoilerContent = { __html: status.get('spoilerHtml') };
|
const spoilerContent = { __html: status.get('spoilerHtml') };
|
||||||
const classNames = classnames('status__content', {
|
const classNames = classnames('status__content', {
|
||||||
'status__content--with-action': this.props.onClick && this.context.router,
|
'status__content--with-action' : this.props.onClick && this.context.router,
|
||||||
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
|
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
|
||||||
'status__content--collapsed': renderReadMore,
|
'status__content--collapsed' : renderReadMore,
|
||||||
});
|
});
|
||||||
|
|
||||||
const showThreadButton = (
|
const showThreadButton = (
|
||||||
<button className='status__content__read-more-button' onClick={this.props.onClick}>
|
<button
|
||||||
<FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
|
className='status__content__read-more-button'
|
||||||
</button>
|
onClick={this.props.onClick}
|
||||||
|
>
|
||||||
|
<i className='fa fa-arrow-right' />
|
||||||
|
<span className='see-more'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='status.show_thread'
|
||||||
|
defaultMessage='Show thread'
|
||||||
|
/>
|
||||||
|
</span >
|
||||||
|
</button >
|
||||||
);
|
);
|
||||||
|
|
||||||
const readMoreButton = (
|
const readMoreButton = (
|
||||||
<button className='status__content__read-more-button' onClick={this.props.onClick} key='read-more'>
|
<button
|
||||||
<FormattedMessage id='status.read_more' defaultMessage='Read more' /><Icon id='angle-right' fixedWidth />
|
className='status__content__read-more-button'
|
||||||
</button>
|
onClick={this.props.onClick}
|
||||||
|
key='read-more'
|
||||||
|
>
|
||||||
|
<i className='fa fa-comment' />
|
||||||
|
<span className='see-more'>
|
||||||
|
|
||||||
|
<FormattedMessage
|
||||||
|
id='status.read_more'
|
||||||
|
defaultMessage='Read more'
|
||||||
|
/>
|
||||||
|
</span >
|
||||||
|
</button >
|
||||||
);
|
);
|
||||||
|
|
||||||
if (status.get('spoiler_text').length > 0) {
|
if (status.get('spoiler_text').length > 0) {
|
||||||
let mentionsPlaceholder = '';
|
let mentionsPlaceholder = '';
|
||||||
|
|
||||||
const mentionLinks = status.get('mentions').map(item => (
|
const mentionLinks = status.get('mentions').map(item => (
|
||||||
<Permalink to={`/accounts/${item.get('id')}`} href={item.get('url')} key={item.get('id')} className='mention'>
|
<Permalink
|
||||||
@<span>{item.get('username')}</span>
|
to={`/accounts/${item.get('id')}`}
|
||||||
</Permalink>
|
href={item.get('url')}
|
||||||
|
key={item.get('id')}
|
||||||
|
className='mention'
|
||||||
|
>
|
||||||
|
@<span >{item.get('username')}</span >
|
||||||
|
</Permalink >
|
||||||
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
|
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
|
||||||
|
|
||||||
const toggleText = hidden ? <FormattedMessage id='status.show_more' defaultMessage='Show more' /> : <FormattedMessage id='status.show_less' defaultMessage='Show less' />;
|
const toggleText = hidden ? (<FormattedMessage
|
||||||
|
id='status.show_more'
|
||||||
|
defaultMessage='Show more'
|
||||||
|
/>) : (<FormattedMessage
|
||||||
|
id='status.show_less'
|
||||||
|
defaultMessage='Show less'
|
||||||
|
/>);
|
||||||
|
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
mentionsPlaceholder = <div>{mentionLinks}</div>;
|
mentionsPlaceholder = <div >{mentionLinks}</div >;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -223,8 +253,12 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
<p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}>
|
<p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}>
|
||||||
<span dangerouslySetInnerHTML={spoilerContent} />
|
<span dangerouslySetInnerHTML={spoilerContent} />
|
||||||
{' '}
|
{' '}
|
||||||
<button tabIndex='0' className={`status__content__spoiler-link ${hidden ? 'status__content__spoiler-link--show-more' : 'status__content__spoiler-link--show-less'}`} onClick={this.handleSpoilerClick}>{toggleText}</button>
|
<button
|
||||||
</p>
|
tabIndex='0'
|
||||||
|
className={`status__content__spoiler-link ${hidden ? 'status__content__spoiler-link--show-more' : 'status__content__spoiler-link--show-less'}`}
|
||||||
|
onClick={this.handleSpoilerClick}
|
||||||
|
>{toggleText}</button >
|
||||||
|
</p >
|
||||||
|
|
||||||
{mentionsPlaceholder}
|
{mentionsPlaceholder}
|
||||||
|
|
||||||
@ -233,7 +267,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
{!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
{!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
||||||
|
|
||||||
{renderViewThread && showThreadButton}
|
{renderViewThread && showThreadButton}
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
} else if (this.props.onClick) {
|
} else if (this.props.onClick) {
|
||||||
const output = [
|
const output = [
|
||||||
@ -243,7 +277,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
||||||
|
|
||||||
{renderViewThread && showThreadButton}
|
{renderViewThread && showThreadButton}
|
||||||
</div>,
|
</div >,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (renderReadMore) {
|
if (renderReadMore) {
|
||||||
@ -259,7 +293,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
||||||
|
|
||||||
{renderViewThread && showThreadButton}
|
{renderViewThread && showThreadButton}
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { blockDomain, unblockDomain } from '../actions/domain_blocks';
|
import { blockDomain, unblockDomain } from '../actions/domain_blocks';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import Domain from '../components/domain';
|
import Domain from '../components/domain';
|
||||||
import { openModal } from '../actions/modal';
|
import { openModal } from '../actions/modal';
|
||||||
|
|
||||||
|
43
app/javascript/mastodon/containers/gallery_container.js
Normal file
43
app/javascript/mastodon/containers/gallery_container.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import initialState from '../initial_state';
|
||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import configureStore from '../store/configureStore';
|
||||||
|
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { hydrateStore } from '../actions/store';
|
||||||
|
import { addLocaleData, IntlProvider } from 'react-intl';
|
||||||
|
import { getLocale } from '../locales';
|
||||||
|
|
||||||
|
const { localeData, messages } = getLocale();
|
||||||
|
addLocaleData(localeData);
|
||||||
|
|
||||||
|
const store = configureStore();
|
||||||
|
|
||||||
|
if (initialState) {
|
||||||
|
store.dispatch(hydrateStore(initialState));
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class GalleryContainer extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
locale: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { locale } = this.props;
|
||||||
|
return (
|
||||||
|
|
||||||
|
<IntlProvider
|
||||||
|
locale={locale}
|
||||||
|
messages={messages}
|
||||||
|
>
|
||||||
|
<Provider store={store}>
|
||||||
|
<Fragment >
|
||||||
|
<Gallery ></Gallery >
|
||||||
|
</Fragment >
|
||||||
|
</Provider >
|
||||||
|
|
||||||
|
</IntlProvider >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -5,18 +5,18 @@ import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
|
|||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
edit_profile : { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
||||||
pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
|
pins : { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences : { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
||||||
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
|
favourites : { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
|
||||||
lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
|
lists : { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
|
||||||
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
blocks : { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
||||||
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
|
domain_blocks : { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
|
||||||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
mutes : { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||||
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
filters : { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
||||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
logout : { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||||
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
|
bookmarks : { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
@ -30,7 +30,7 @@ class ActionBar extends React.PureComponent {
|
|||||||
|
|
||||||
handleLogout = () => {
|
handleLogout = () => {
|
||||||
this.props.onLogout();
|
this.props.onLogout();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
@ -21,13 +21,17 @@ import { length } from 'stringz';
|
|||||||
import { countableText } from '../util/counter';
|
import { countableText } from '../util/counter';
|
||||||
import Icon from 'mastodon/components/icon';
|
import Icon from 'mastodon/components/icon';
|
||||||
|
|
||||||
|
// import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
||||||
|
// import { mascot } from '../../initial_state';
|
||||||
|
|
||||||
|
|
||||||
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
|
placeholder : { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
|
||||||
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
|
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
|
||||||
publish: { id: 'compose_form.publish', defaultMessage: 'Toot' },
|
publish : { id: 'compose_form.publish', defaultMessage: 'Toot' },
|
||||||
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
|
publishLoud : { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
@ -38,44 +42,46 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl : PropTypes.object.isRequired,
|
||||||
text: PropTypes.string.isRequired,
|
text : PropTypes.string.isRequired,
|
||||||
suggestions: ImmutablePropTypes.list,
|
suggestions : ImmutablePropTypes.list,
|
||||||
spoiler: PropTypes.bool,
|
spoiler : PropTypes.bool,
|
||||||
privacy: PropTypes.string,
|
privacy : PropTypes.string,
|
||||||
spoilerText: PropTypes.string,
|
spoilerText : PropTypes.string,
|
||||||
focusDate: PropTypes.instanceOf(Date),
|
focusDate : PropTypes.instanceOf(Date),
|
||||||
caretPosition: PropTypes.number,
|
caretPosition : PropTypes.number,
|
||||||
preselectDate: PropTypes.instanceOf(Date),
|
maxTootCharsLimit : PropTypes.number,
|
||||||
isSubmitting: PropTypes.bool,
|
preselectDate : PropTypes.instanceOf(Date),
|
||||||
isChangingUpload: PropTypes.bool,
|
isSubmitting : PropTypes.bool,
|
||||||
isUploading: PropTypes.bool,
|
isChangingUpload : PropTypes.bool,
|
||||||
onChange: PropTypes.func.isRequired,
|
isUploading : PropTypes.bool,
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onChange : PropTypes.func.isRequired,
|
||||||
onClearSuggestions: PropTypes.func.isRequired,
|
onSubmit : PropTypes.func.isRequired,
|
||||||
onFetchSuggestions: PropTypes.func.isRequired,
|
onClearSuggestions : PropTypes.func.isRequired,
|
||||||
|
onFetchSuggestions : PropTypes.func.isRequired,
|
||||||
onSuggestionSelected: PropTypes.func.isRequired,
|
onSuggestionSelected: PropTypes.func.isRequired,
|
||||||
onChangeSpoilerText: PropTypes.func.isRequired,
|
onChangeSpoilerText : PropTypes.func.isRequired,
|
||||||
onPaste: PropTypes.func.isRequired,
|
onPaste : PropTypes.func.isRequired,
|
||||||
onPickEmoji: PropTypes.func.isRequired,
|
onPickEmoji : PropTypes.func.isRequired,
|
||||||
showSearch: PropTypes.bool,
|
showSearch : PropTypes.bool,
|
||||||
anyMedia: PropTypes.bool,
|
anyMedia : PropTypes.bool,
|
||||||
singleColumn: PropTypes.bool,
|
singleColumn : PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
showSearch: false,
|
showSearch : false,
|
||||||
|
maxTootCharsLimit: 7777,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChange = (e) => {
|
handleChange = (e) => {
|
||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = (e) => {
|
handleKeyDown = (e) => {
|
||||||
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
||||||
this.handleSubmit();
|
this.handleSubmit();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getFulltextForCharacterCounting = () => {
|
getFulltextForCharacterCounting = () => {
|
||||||
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
||||||
@ -101,27 +107,27 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.props.onSubmit(this.context.router ? this.context.router.history : null);
|
this.props.onSubmit(this.context.router ? this.context.router.history : null);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsClearRequested = () => {
|
onSuggestionsClearRequested = () => {
|
||||||
this.props.onClearSuggestions();
|
this.props.onClearSuggestions();
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsFetchRequested = (token) => {
|
onSuggestionsFetchRequested = (token) => {
|
||||||
this.props.onFetchSuggestions(token);
|
this.props.onFetchSuggestions(token);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionSelected = (tokenStart, token, value) => {
|
onSuggestionSelected = (tokenStart, token, value) => {
|
||||||
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
|
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSpoilerSuggestionSelected = (tokenStart, token, value) => {
|
onSpoilerSuggestionSelected = (tokenStart, token, value) => {
|
||||||
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
|
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChangeSpoilerText = (e) => {
|
handleChangeSpoilerText = (e) => {
|
||||||
this.props.onChangeSpoilerText(e.target.value);
|
this.props.onChangeSpoilerText(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFocus = () => {
|
handleFocus = () => {
|
||||||
if (this.composeForm && !this.props.singleColumn) {
|
if (this.composeForm && !this.props.singleColumn) {
|
||||||
@ -130,9 +136,9 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
this.composeForm.scrollIntoView();
|
this.composeForm.scrollIntoView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
// This statement does several things:
|
// This statement does several things:
|
||||||
// - If we're beginning a reply, and,
|
// - If we're beginning a reply, and,
|
||||||
// - Replying to zero or one users, places the cursor at the end of the textbox.
|
// - Replying to zero or one users, places the cursor at the end of the textbox.
|
||||||
@ -142,19 +148,19 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
let selectionEnd, selectionStart;
|
let selectionEnd, selectionStart;
|
||||||
|
|
||||||
if (this.props.preselectDate !== prevProps.preselectDate) {
|
if (this.props.preselectDate !== prevProps.preselectDate) {
|
||||||
selectionEnd = this.props.text.length;
|
selectionEnd = this.props.text.length;
|
||||||
selectionStart = this.props.text.search(/\s/) + 1;
|
selectionStart = this.props.text.search(/\s/) + 1;
|
||||||
} else if (typeof this.props.caretPosition === 'number') {
|
} else if (typeof this.props.caretPosition === 'number') {
|
||||||
selectionStart = this.props.caretPosition;
|
selectionStart = this.props.caretPosition;
|
||||||
selectionEnd = this.props.caretPosition;
|
selectionEnd = this.props.caretPosition;
|
||||||
} else {
|
} else {
|
||||||
selectionEnd = this.props.text.length;
|
selectionEnd = this.props.text.length;
|
||||||
selectionStart = selectionEnd;
|
selectionStart = selectionEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd);
|
this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd);
|
||||||
this.autosuggestTextarea.textarea.focus();
|
this.autosuggestTextarea.textarea.focus();
|
||||||
} else if(prevProps.isSubmitting && !this.props.isSubmitting) {
|
} else if (prevProps.isSubmitting && !this.props.isSubmitting) {
|
||||||
this.autosuggestTextarea.textarea.focus();
|
this.autosuggestTextarea.textarea.focus();
|
||||||
} else if (this.props.spoiler !== prevProps.spoiler) {
|
} else if (this.props.spoiler !== prevProps.spoiler) {
|
||||||
if (this.props.spoiler) {
|
if (this.props.spoiler) {
|
||||||
@ -167,23 +173,23 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
|
|
||||||
setAutosuggestTextarea = (c) => {
|
setAutosuggestTextarea = (c) => {
|
||||||
this.autosuggestTextarea = c;
|
this.autosuggestTextarea = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setSpoilerText = (c) => {
|
setSpoilerText = (c) => {
|
||||||
this.spoilerText = c;
|
this.spoilerText = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.composeForm = c;
|
this.composeForm = c;
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEmojiPick = (data) => {
|
handleEmojiPick = (data) => {
|
||||||
const { text } = this.props;
|
const { text } = this.props;
|
||||||
const position = this.autosuggestTextarea.textarea.selectionStart;
|
const position = this.autosuggestTextarea.textarea.selectionStart;
|
||||||
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
|
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
|
||||||
|
|
||||||
this.props.onPickEmoji(position, data, needsSpace);
|
this.props.onPickEmoji(position, data, needsSpace);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, onPaste, showSearch } = this.props;
|
const { intl, onPaste, showSearch } = this.props;
|
||||||
@ -191,7 +197,8 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
let publishText = '';
|
let publishText = '';
|
||||||
|
|
||||||
if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
|
if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
|
||||||
publishText = <span className='compose-form__publish-private'><Icon id='lock' /> {intl.formatMessage(messages.publish)}</span>;
|
publishText =
|
||||||
|
<span className='compose-form__publish-private'><Icon id='lock' /> {intl.formatMessage(messages.publish)}</span >;
|
||||||
} else {
|
} else {
|
||||||
publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
|
publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
|
||||||
}
|
}
|
||||||
@ -202,7 +209,10 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
|
|
||||||
<ReplyIndicatorContainer />
|
<ReplyIndicatorContainer />
|
||||||
|
|
||||||
<div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef}>
|
<div
|
||||||
|
className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`}
|
||||||
|
ref={this.setRef}
|
||||||
|
>
|
||||||
<AutosuggestInput
|
<AutosuggestInput
|
||||||
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
|
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
|
||||||
value={this.props.spoilerText}
|
value={this.props.spoilerText}
|
||||||
@ -218,7 +228,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
id='cw-spoiler-input'
|
id='cw-spoiler-input'
|
||||||
className='spoiler-input__input'
|
className='spoiler-input__input'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div >
|
||||||
|
|
||||||
<AutosuggestTextarea
|
<AutosuggestTextarea
|
||||||
ref={this.setAutosuggestTextarea}
|
ref={this.setAutosuggestTextarea}
|
||||||
@ -239,8 +249,8 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
<div className='compose-form__modifiers'>
|
<div className='compose-form__modifiers'>
|
||||||
<UploadFormContainer />
|
<UploadFormContainer />
|
||||||
<PollFormContainer />
|
<PollFormContainer />
|
||||||
</div>
|
</div >
|
||||||
</AutosuggestTextarea>
|
</AutosuggestTextarea >
|
||||||
|
|
||||||
<div className='compose-form__buttons-wrapper'>
|
<div className='compose-form__buttons-wrapper'>
|
||||||
<div className='compose-form__buttons'>
|
<div className='compose-form__buttons'>
|
||||||
|
@ -11,32 +11,57 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||||||
export default class NavigationBar extends ImmutablePureComponent {
|
export default class NavigationBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
account: ImmutablePropTypes.map.isRequired,
|
account : ImmutablePropTypes.map.isRequired,
|
||||||
onLogout: PropTypes.func.isRequired,
|
onLogout: PropTypes.func.isRequired,
|
||||||
onClose: PropTypes.func,
|
onClose : PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className='navigation-bar'>
|
<div className='navigation-bar'>
|
||||||
<Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}>
|
<Permalink
|
||||||
<span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
|
href={this.props.account.get('url')}
|
||||||
<Avatar account={this.props.account} size={48} />
|
to={`/accounts/${this.props.account.get('id')}`}
|
||||||
</Permalink>
|
>
|
||||||
|
<span style={{ display: 'none' }}>{this.props.account.get('acct')}</span >
|
||||||
|
<Avatar
|
||||||
|
account={this.props.account}
|
||||||
|
size={48}
|
||||||
|
/>
|
||||||
|
</Permalink >
|
||||||
|
|
||||||
<div className='navigation-bar__profile'>
|
<div className='navigation-bar__profile'>
|
||||||
<Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}>
|
<Permalink
|
||||||
<strong className='navigation-bar__profile-account'>@{this.props.account.get('acct')}</strong>
|
href={this.props.account.get('url')}
|
||||||
</Permalink>
|
to={`/accounts/${this.props.account.get('id')}`}
|
||||||
|
>
|
||||||
|
<strong className='navigation-bar__profile-account'>@{this.props.account.get('acct')}</strong >
|
||||||
|
</Permalink >
|
||||||
|
|
||||||
<a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
|
<a
|
||||||
</div>
|
href='/settings/profile'
|
||||||
|
className='navigation-bar__profile-edit'
|
||||||
|
>
|
||||||
|
<i className='fa fa-pencil' />
|
||||||
|
<FormattedMessage
|
||||||
|
id='navigation_bar.edit_profile'
|
||||||
|
defaultMessage='Edit profile'
|
||||||
|
/></a >
|
||||||
|
</div >
|
||||||
|
|
||||||
<div className='navigation-bar__actions'>
|
<div className='navigation-bar__actions'>
|
||||||
<IconButton className='close' title='' icon='close' onClick={this.props.onClose} />
|
<IconButton
|
||||||
<ActionBar account={this.props.account} onLogout={this.props.onLogout} />
|
className='close'
|
||||||
</div>
|
title=''
|
||||||
</div>
|
icon='close'
|
||||||
|
onClick={this.props.onClose}
|
||||||
|
/>
|
||||||
|
<ActionBar
|
||||||
|
account={this.props.account}
|
||||||
|
onLogout={this.props.onLogout}
|
||||||
|
/>
|
||||||
|
</div >
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import IconButton from 'mastodon/components/icon_button';
|
import IconButton from 'mastodon/components/icon_button';
|
||||||
import Icon from 'mastodon/components/icon';
|
import Icon from 'mastodon/components/icon';
|
||||||
import AutosuggestInput from 'mastodon/components/autosuggest_input';
|
import AutosuggestInput from 'mastodon/components/autosuggest_input';
|
||||||
@ -57,19 +57,19 @@ class Option extends React.PureComponent {
|
|||||||
if (e.key === 'Enter' || e.key === ' ') {
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
this.handleToggleMultiple(e);
|
this.handleToggleMultiple(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsClearRequested = () => {
|
onSuggestionsClearRequested = () => {
|
||||||
this.props.onClearSuggestions();
|
this.props.onClearSuggestions();
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsFetchRequested = (token) => {
|
onSuggestionsFetchRequested = (token) => {
|
||||||
this.props.onFetchSuggestions(token);
|
this.props.onFetchSuggestions(token);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionSelected = (tokenStart, token, value) => {
|
onSuggestionSelected = (tokenStart, token, value) => {
|
||||||
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
|
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { isPollMultiple, title, index, autoFocus, intl } = this.props;
|
const { isPollMultiple, title, index, autoFocus, intl } = this.props;
|
||||||
|
@ -48,7 +48,7 @@ class ReplyIndicator extends ImmutablePureComponent {
|
|||||||
return (
|
return (
|
||||||
<div className='reply-indicator'>
|
<div className='reply-indicator'>
|
||||||
<div className='reply-indicator__header'>
|
<div className='reply-indicator__header'>
|
||||||
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} inverted /></div>
|
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} inverted obfuscate='false' /></div>
|
||||||
|
|
||||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
|
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
|
||||||
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
||||||
|
@ -4,35 +4,34 @@ import NavigationContainer from './containers/navigation_container';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { mountCompose, unmountCompose } from '../../actions/compose';
|
import { changeComposing, mountCompose, unmountCompose } from '../../actions/compose';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { injectIntl, defineMessages } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import SearchContainer from './containers/search_container';
|
import SearchContainer from './containers/search_container';
|
||||||
import Motion from '../ui/util/optional_motion';
|
import Motion from '../ui/util/optional_motion';
|
||||||
import spring from 'react-motion/lib/spring';
|
import spring from 'react-motion/lib/spring';
|
||||||
import SearchResultsContainer from './containers/search_results_container';
|
import SearchResultsContainer from './containers/search_results_container';
|
||||||
import { changeComposing } from '../../actions/compose';
|
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
import cipherblissLogo from '../../../images/logo_cipherbliss.png';
|
||||||
import { mascot } from '../../initial_state';
|
import { mascot } from '../../initial_state';
|
||||||
import Icon from 'mastodon/components/icon';
|
import Icon from 'mastodon/components/icon';
|
||||||
import { logOut } from 'mastodon/utils/log_out';
|
import { logOut } from 'mastodon/utils/log_out';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
start : { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||||
home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
|
home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
|
||||||
notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
|
notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
|
||||||
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
public : { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||||
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
community : { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences : { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
logout : { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||||
compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
|
compose : { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
|
||||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
||||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => ({
|
const mapStateToProps = (state, ownProps) => ({
|
||||||
columns: state.getIn(['settings', 'columns']),
|
columns : state.getIn(['settings', 'columns']),
|
||||||
showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage,
|
showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -41,15 +40,15 @@ export default @connect(mapStateToProps)
|
|||||||
class Compose extends React.PureComponent {
|
class Compose extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch : PropTypes.func.isRequired,
|
||||||
columns: ImmutablePropTypes.list.isRequired,
|
columns : ImmutablePropTypes.list.isRequired,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn : PropTypes.bool,
|
||||||
showSearch: PropTypes.bool,
|
showSearch : PropTypes.bool,
|
||||||
isSearchPage: PropTypes.bool,
|
isSearchPage: PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
intl : PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount() {
|
||||||
const { isSearchPage } = this.props;
|
const { isSearchPage } = this.props;
|
||||||
|
|
||||||
if (!isSearchPage) {
|
if (!isSearchPage) {
|
||||||
@ -57,7 +56,7 @@ class Compose extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount() {
|
||||||
const { isSearchPage } = this.props;
|
const { isSearchPage } = this.props;
|
||||||
|
|
||||||
if (!isSearchPage) {
|
if (!isSearchPage) {
|
||||||
@ -72,23 +71,23 @@ class Compose extends React.PureComponent {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
message: intl.formatMessage(messages.logoutMessage),
|
message : intl.formatMessage(messages.logoutMessage),
|
||||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
confirm : intl.formatMessage(messages.logoutConfirm),
|
||||||
onConfirm: () => logOut(),
|
onConfirm: () => logOut(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
onFocus = () => {
|
onFocus = () => {
|
||||||
this.props.dispatch(changeComposing(true));
|
this.props.dispatch(changeComposing(true));
|
||||||
}
|
};
|
||||||
|
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
this.props.dispatch(changeComposing(false));
|
this.props.dispatch(changeComposing(false));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { multiColumn, showSearch, isSearchPage, intl } = this.props;
|
const { multiColumn, showSearch, isSearchPage, intl } = this.props;
|
||||||
|
|
||||||
let header = '';
|
let header = '';
|
||||||
@ -97,51 +96,126 @@ class Compose extends React.PureComponent {
|
|||||||
const { columns } = this.props;
|
const { columns } = this.props;
|
||||||
header = (
|
header = (
|
||||||
<nav className='drawer__header'>
|
<nav className='drawer__header'>
|
||||||
<Link to='/getting-started' className='drawer__tab' title={intl.formatMessage(messages.start)} aria-label={intl.formatMessage(messages.start)}><Icon id='bars' fixedWidth /></Link>
|
<Link
|
||||||
|
to='/getting-started'
|
||||||
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.start)}
|
||||||
|
aria-label={intl.formatMessage(messages.start)}
|
||||||
|
><Icon
|
||||||
|
id='bars'
|
||||||
|
fixedWidth
|
||||||
|
/></Link >
|
||||||
{!columns.some(column => column.get('id') === 'HOME') && (
|
{!columns.some(column => column.get('id') === 'HOME') && (
|
||||||
<Link to='/timelines/home' className='drawer__tab' title={intl.formatMessage(messages.home_timeline)} aria-label={intl.formatMessage(messages.home_timeline)}><Icon id='home' fixedWidth /></Link>
|
<Link
|
||||||
|
to='/timelines/home'
|
||||||
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.home_timeline)}
|
||||||
|
aria-label={intl.formatMessage(messages.home_timeline)}
|
||||||
|
><Icon
|
||||||
|
id='home'
|
||||||
|
fixedWidth
|
||||||
|
/></Link >
|
||||||
)}
|
)}
|
||||||
{!columns.some(column => column.get('id') === 'NOTIFICATIONS') && (
|
{!columns.some(column => column.get('id') === 'NOTIFICATIONS') && (
|
||||||
<Link to='/notifications' className='drawer__tab' title={intl.formatMessage(messages.notifications)} aria-label={intl.formatMessage(messages.notifications)}><Icon id='bell' fixedWidth /></Link>
|
<Link
|
||||||
|
to='/notifications'
|
||||||
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.notifications)}
|
||||||
|
aria-label={intl.formatMessage(messages.notifications)}
|
||||||
|
><Icon
|
||||||
|
id='bell'
|
||||||
|
fixedWidth
|
||||||
|
/></Link >
|
||||||
)}
|
)}
|
||||||
{!columns.some(column => column.get('id') === 'COMMUNITY') && (
|
{!columns.some(column => column.get('id') === 'COMMUNITY') && (
|
||||||
<Link to='/timelines/public/local' className='drawer__tab' title={intl.formatMessage(messages.community)} aria-label={intl.formatMessage(messages.community)}><Icon id='users' fixedWidth /></Link>
|
<Link
|
||||||
|
to='/timelines/public/local'
|
||||||
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.community)}
|
||||||
|
aria-label={intl.formatMessage(messages.community)}
|
||||||
|
><Icon
|
||||||
|
id='users'
|
||||||
|
fixedWidth
|
||||||
|
/></Link >
|
||||||
)}
|
)}
|
||||||
{!columns.some(column => column.get('id') === 'PUBLIC') && (
|
{!columns.some(column => column.get('id') === 'PUBLIC') && (
|
||||||
<Link to='/timelines/public' className='drawer__tab' title={intl.formatMessage(messages.public)} aria-label={intl.formatMessage(messages.public)}><Icon id='globe' fixedWidth /></Link>
|
<Link
|
||||||
|
to='/timelines/public'
|
||||||
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.public)}
|
||||||
|
aria-label={intl.formatMessage(messages.public)}
|
||||||
|
><Icon
|
||||||
|
id='globe'
|
||||||
|
fixedWidth
|
||||||
|
/></Link >
|
||||||
)}
|
)}
|
||||||
<a href='/settings/preferences' className='drawer__tab' title={intl.formatMessage(messages.preferences)} aria-label={intl.formatMessage(messages.preferences)}><Icon id='cog' fixedWidth /></a>
|
<a
|
||||||
<a href='/auth/sign_out' className='drawer__tab' title={intl.formatMessage(messages.logout)} aria-label={intl.formatMessage(messages.logout)} onClick={this.handleLogoutClick}><Icon id='sign-out' fixedWidth /></a>
|
href='/settings/preferences'
|
||||||
</nav>
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.preferences)}
|
||||||
|
aria-label={intl.formatMessage(messages.preferences)}
|
||||||
|
><Icon
|
||||||
|
id='cog'
|
||||||
|
fixedWidth
|
||||||
|
/></a >
|
||||||
|
<a
|
||||||
|
href='/auth/sign_out'
|
||||||
|
className='drawer__tab'
|
||||||
|
title={intl.formatMessage(messages.logout)}
|
||||||
|
aria-label={intl.formatMessage(messages.logout)}
|
||||||
|
onClick={this.handleLogoutClick}
|
||||||
|
><Icon
|
||||||
|
id='sign-out'
|
||||||
|
fixedWidth
|
||||||
|
/></a >
|
||||||
|
</nav >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>
|
<div
|
||||||
|
className='drawer'
|
||||||
|
role='region'
|
||||||
|
aria-label={intl.formatMessage(messages.compose)}
|
||||||
|
>
|
||||||
{header}
|
{header}
|
||||||
|
|
||||||
{(multiColumn || isSearchPage) && <SearchContainer /> }
|
{(multiColumn || isSearchPage) && <SearchContainer />}
|
||||||
|
|
||||||
<div className='drawer__pager'>
|
<div className='drawer__pager'>
|
||||||
{!isSearchPage && <div className='drawer__inner' onFocus={this.onFocus}>
|
{!isSearchPage && <div
|
||||||
|
className='drawer__inner'
|
||||||
|
onFocus={this.onFocus}
|
||||||
|
>
|
||||||
<NavigationContainer onClose={this.onBlur} />
|
<NavigationContainer onClose={this.onBlur} />
|
||||||
|
|
||||||
<ComposeFormContainer />
|
<ComposeFormContainer />
|
||||||
|
|
||||||
<div className='drawer__inner__mastodon'>
|
<div className='drawer__inner__mastodon'>
|
||||||
<img alt='' draggable='false' src={mascot || elephantUIPlane} />
|
<img
|
||||||
</div>
|
className='cipherbliss_logo'
|
||||||
</div>}
|
src={mascot || cipherblissLogo}
|
||||||
|
alt='logo'
|
||||||
|
/>
|
||||||
|
{/*<img alt='' draggable='false' src={mascot || elephantUIPlane} />*/}
|
||||||
|
</div >
|
||||||
|
</div >}
|
||||||
|
|
||||||
<Motion defaultStyle={{ x: isSearchPage ? 0 : -100 }} style={{ x: spring(showSearch || isSearchPage ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
<Motion
|
||||||
|
defaultStyle={{ x: isSearchPage ? 0 : -100 }}
|
||||||
|
style={{ x: spring(showSearch || isSearchPage ? 0 : -100, { stiffness: 210, damping: 20 }) }}
|
||||||
|
>
|
||||||
{({ x }) => (
|
{({ x }) => (
|
||||||
<div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}>
|
<div
|
||||||
|
className='drawer__inner darker'
|
||||||
|
style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}
|
||||||
|
>
|
||||||
<SearchResultsContainer />
|
<SearchResultsContainer />
|
||||||
</div>
|
</div >
|
||||||
)}
|
)}
|
||||||
</Motion>
|
</Motion >
|
||||||
</div>
|
</div >
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,26 +224,31 @@ class AccountCard extends ImmutablePureComponent {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='directory__card__bar'>
|
<div className='columns'>
|
||||||
<Permalink
|
<div className='column'>
|
||||||
className='directory__card__bar__name'
|
<div className='directory__card__bar'>
|
||||||
href={account.get('url')}
|
<Permalink
|
||||||
to={`/accounts/${account.get('id')}`}
|
className='directory__card__bar__name'
|
||||||
>
|
href={account.get('url')}
|
||||||
<Avatar account={account} size={48} />
|
to={`/accounts/${account.get('id')}`}
|
||||||
<DisplayName account={account} />
|
>
|
||||||
</Permalink>
|
<Avatar account={account} size={48} />
|
||||||
|
<DisplayName account={account} />
|
||||||
|
</Permalink>
|
||||||
|
|
||||||
<div className='directory__card__bar__relationship account__relationship'>
|
<div className='directory__card__bar__relationship account__relationship'>
|
||||||
{buttons}
|
{buttons}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='column'>
|
||||||
|
<div className='directory__card__extra' ref={this.setRef}>
|
||||||
|
<div
|
||||||
|
className='account__header__content'
|
||||||
|
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='directory__card__extra' ref={this.setRef}>
|
|
||||||
<div
|
|
||||||
className='account__header__content'
|
|
||||||
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='directory__card__extra'>
|
<div className='directory__card__extra'>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
@ -9,7 +9,7 @@ import LoadingIndicator from '../../components/loading_indicator';
|
|||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import DomainContainer from '../../containers/domain_container';
|
import DomainContainer from '../../containers/domain_container';
|
||||||
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
|
import { expandDomainBlocks, fetchDomainBlocks } from '../../actions/domain_blocks';
|
||||||
import ScrollableList from '../../components/scrollable_list';
|
import ScrollableList from '../../components/scrollable_list';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
@ -55,7 +55,10 @@ class Blocks extends ImmutablePureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />;
|
const emptyMessage = <FormattedMessage
|
||||||
|
id='empty_column.domain_blocks'
|
||||||
|
defaultMessage='There are no blocked domains yet.'
|
||||||
|
/>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column bindToDocument={!multiColumn} icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
|
<Column bindToDocument={!multiColumn} icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
|
||||||
|
@ -5,44 +5,112 @@ import Permalink from '../../../components/permalink';
|
|||||||
import Avatar from '../../../components/avatar';
|
import Avatar from '../../../components/avatar';
|
||||||
import DisplayName from '../../../components/display_name';
|
import DisplayName from '../../../components/display_name';
|
||||||
import IconButton from '../../../components/icon_button';
|
import IconButton from '../../../components/icon_button';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { NavLink } from 'react-router-dom';
|
||||||
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
|
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
|
||||||
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
|
reject : { id: 'follow_request.reject', defaultMessage: 'Reject' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
class AccountAuthorize extends ImmutablePureComponent {
|
class AccountAuthorize extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
account: ImmutablePropTypes.map.isRequired,
|
account : ImmutablePropTypes.map.isRequired,
|
||||||
onAuthorize: PropTypes.func.isRequired,
|
onAuthorize: PropTypes.func.isRequired,
|
||||||
onReject: PropTypes.func.isRequired,
|
onReject : PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl : PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { intl, account, onAuthorize, onReject } = this.props;
|
const { intl, account, onAuthorize, onReject } = this.props;
|
||||||
const content = { __html: account.get('note_emojified') };
|
const content = { __html: account.get('note_emojified') };
|
||||||
|
|
||||||
|
const fields = account.get('fields');
|
||||||
return (
|
return (
|
||||||
<div className='account-authorize__wrapper'>
|
<div className='account-authorize__wrapper'>
|
||||||
<div className='account-authorize'>
|
<div className='account-authorize'>
|
||||||
<Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name'>
|
<Permalink
|
||||||
<div className='account-authorize__avatar'><Avatar account={account} size={48} /></div>
|
href={account.get('url')}
|
||||||
|
to={`/accounts/${account.get('id')}`}
|
||||||
|
className='status__display-name'
|
||||||
|
>
|
||||||
|
<div className='account-authorize__avatar'><Avatar
|
||||||
|
account={account}
|
||||||
|
size={48}
|
||||||
|
/></div >
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Permalink>
|
</Permalink >
|
||||||
|
<div className='more'>
|
||||||
|
{account.get('remote_url')}
|
||||||
|
</div >
|
||||||
|
|
||||||
<div className='account__header__content' dangerouslySetInnerHTML={content} />
|
<div
|
||||||
</div>
|
className='account__header__content'
|
||||||
|
dangerouslySetInnerHTML={content}
|
||||||
|
/>
|
||||||
|
</div >
|
||||||
|
<span className='account-authorize--more-data'>
|
||||||
|
<NavLink
|
||||||
|
isActive={this.isStatusesPageActive}
|
||||||
|
activeClassName='active'
|
||||||
|
to={`/accounts/${account.get('id')}`}
|
||||||
|
title={intl.formatNumber(account.get('statuses_count'))}
|
||||||
|
>
|
||||||
|
<i className='fa fa-comment' />
|
||||||
|
<strong >{(account.get('statuses_count'))}</strong > <FormattedMessage
|
||||||
|
id='account.posts'
|
||||||
|
defaultMessage='Toots'
|
||||||
|
/>
|
||||||
|
</NavLink >
|
||||||
|
|
||||||
|
<NavLink
|
||||||
|
exact
|
||||||
|
activeClassName='active'
|
||||||
|
to={`/accounts/${account.get('id')}/following`}
|
||||||
|
title={intl.formatNumber(account.get('following_count'))}
|
||||||
|
>
|
||||||
|
<strong >{(account.get('following_count'))}</strong > <FormattedMessage
|
||||||
|
id='account.follows'
|
||||||
|
defaultMessage='Follows'
|
||||||
|
/>
|
||||||
|
</NavLink >
|
||||||
|
|
||||||
|
<NavLink
|
||||||
|
exact
|
||||||
|
activeClassName='active'
|
||||||
|
to={`/accounts/${account.get('id')}/followers`}
|
||||||
|
title={intl.formatNumber(account.get('followers_count'))}
|
||||||
|
>
|
||||||
|
<strong >{(account.get('followers_count'))}</strong >
|
||||||
|
<FormattedMessage
|
||||||
|
id='account.followers'
|
||||||
|
defaultMessage='Followers'
|
||||||
|
/>
|
||||||
|
</NavLink >
|
||||||
|
|
||||||
|
</span >
|
||||||
|
|
||||||
<div className='account--panel'>
|
<div className='account--panel'>
|
||||||
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} /></div>
|
<div className='account--panel__button text-center'>
|
||||||
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} /></div>
|
<IconButton
|
||||||
</div>
|
title={intl.formatMessage(messages.authorize)}
|
||||||
</div>
|
size='50'
|
||||||
|
icon='check'
|
||||||
|
onClick={onAuthorize}
|
||||||
|
/>
|
||||||
|
</div >
|
||||||
|
<div className='account--panel__button text-center'>
|
||||||
|
<IconButton
|
||||||
|
title={intl.formatMessage(messages.reject)}
|
||||||
|
size='50'
|
||||||
|
icon='times'
|
||||||
|
onClick={onReject}
|
||||||
|
/></div >
|
||||||
|
</div >
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { addReaction, removeReaction, dismissAnnouncement } from 'mastodon/actions/announcements';
|
import { addReaction, dismissAnnouncement, removeReaction } from 'mastodon/actions/announcements';
|
||||||
import Announcements from '../components/announcements';
|
import Announcements from '../components/announcements';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
@ -13,8 +13,8 @@ const mapStateToProps = state => ({
|
|||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
dismissAnnouncement: id => dispatch(dismissAnnouncement(id)),
|
dismissAnnouncement: id => dispatch(dismissAnnouncement(id)),
|
||||||
addReaction: (id, name) => dispatch(addReaction(id, name)),
|
addReaction : (id, name) => dispatch(addReaction(id, name)),
|
||||||
removeReaction: (id, name) => dispatch(removeReaction(id, name)),
|
removeReaction : (id, name) => dispatch(removeReaction(id, name)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Announcements);
|
export default connect(mapStateToProps, mapDispatchToProps)(Announcements);
|
||||||
|
@ -5,8 +5,8 @@ import PropTypes from 'prop-types';
|
|||||||
import StatusListContainer from '../ui/containers/status_list_container';
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
import Column from '../../components/column';
|
import Column from '../../components/column';
|
||||||
import ColumnHeader from '../../components/column_header';
|
import ColumnHeader from '../../components/column_header';
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, moveColumn, removeColumn } from '../../actions/columns';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/announcements';
|
import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/announcements';
|
||||||
@ -15,17 +15,17 @@ import classNames from 'classnames';
|
|||||||
import IconWithBadge from 'mastodon/components/icon_with_badge';
|
import IconWithBadge from 'mastodon/components/icon_with_badge';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'column.home', defaultMessage: 'Home' },
|
title : { id: 'column.home', defaultMessage: 'Home' },
|
||||||
show_announcements: { id: 'home.show_announcements', defaultMessage: 'Show announcements' },
|
show_announcements: { id: 'home.show_announcements', defaultMessage: 'Show announcements' },
|
||||||
hide_announcements: { id: 'home.hide_announcements', defaultMessage: 'Hide announcements' },
|
hide_announcements: { id: 'home.hide_announcements', defaultMessage: 'Hide announcements' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
hasUnread : state.getIn(['timelines', 'home', 'unread']) > 0,
|
||||||
isPartial: state.getIn(['timelines', 'home', 'isPartial']),
|
isPartial : state.getIn(['timelines', 'home', 'isPartial']),
|
||||||
hasAnnouncements: !state.getIn(['announcements', 'items']).isEmpty(),
|
hasAnnouncements : !state.getIn(['announcements', 'items']).isEmpty(),
|
||||||
unreadAnnouncements: state.getIn(['announcements', 'items']).count(item => !item.get('read')),
|
unreadAnnouncements: state.getIn(['announcements', 'items']).count(item => !item.get('read')),
|
||||||
showAnnouncements: state.getIn(['announcements', 'show']),
|
showAnnouncements : state.getIn(['announcements', 'show']),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @connect(mapStateToProps)
|
export default @connect(mapStateToProps)
|
||||||
@ -53,24 +53,24 @@ class HomeTimeline extends React.PureComponent {
|
|||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('HOME', {}));
|
dispatch(addColumn('HOME', {}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
this.props.dispatch(expandHomeTimeline({ maxId }));
|
this.props.dispatch(expandHomeTimeline({ maxId }));
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.props.dispatch(fetchAnnouncements());
|
this.props.dispatch(fetchAnnouncements());
|
||||||
@ -89,7 +89,7 @@ class HomeTimeline extends React.PureComponent {
|
|||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
|
||||||
if (wasPartial === isPartial) {
|
if (wasPartial === isPartial) {
|
||||||
return;
|
|
||||||
} else if (!wasPartial && isPartial) {
|
} else if (!wasPartial && isPartial) {
|
||||||
this.polling = setInterval(() => {
|
this.polling = setInterval(() => {
|
||||||
dispatch(expandHomeTimeline());
|
dispatch(expandHomeTimeline());
|
||||||
@ -109,7 +109,7 @@ class HomeTimeline extends React.PureComponent {
|
|||||||
handleToggleAnnouncementsClick = (e) => {
|
handleToggleAnnouncementsClick = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.props.dispatch(toggleShowAnnouncements());
|
this.props.dispatch(toggleShowAnnouncements());
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props;
|
const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props;
|
||||||
|
@ -273,8 +273,8 @@ class ActionBar extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='detailed-status__action-bar'>
|
<div className='detailed-status__action-bar'>
|
||||||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /></div>
|
<div className='detailed-status__button button_reply'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /></div>
|
||||||
<div className='detailed-status__button' ><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} /></div>
|
<div className='detailed-status__button button_reblog' ><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} /></div>
|
||||||
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
|
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
|
||||||
{shareButton}
|
{shareButton}
|
||||||
<div className='detailed-status__button'><IconButton className='bookmark-icon' active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} /></div>
|
<div className='detailed-status__button'><IconButton className='bookmark-icon' active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} /></div>
|
||||||
|
@ -6,7 +6,7 @@ import DisplayName from '../../../components/display_name';
|
|||||||
import StatusContent from '../../../components/status_content';
|
import StatusContent from '../../../components/status_content';
|
||||||
import MediaGallery from '../../../components/media_gallery';
|
import MediaGallery from '../../../components/media_gallery';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { injectIntl, defineMessages, FormattedDate } from 'react-intl';
|
import { defineMessages, FormattedDate, injectIntl } from 'react-intl';
|
||||||
import Card from './card';
|
import Card from './card';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import Video from '../../video';
|
import Video from '../../video';
|
||||||
@ -18,13 +18,13 @@ import AnimatedNumber from 'mastodon/components/animated_number';
|
|||||||
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
|
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
|
public_short : { id: 'privacy.public.short', defaultMessage: 'Public' },
|
||||||
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
|
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
|
||||||
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
|
private_short : { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
|
||||||
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
|
direct_short : { id: 'privacy.direct.short', defaultMessage: 'Direct' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
class DetailedStatus extends ImmutablePureComponent {
|
class DetailedStatus extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -59,7 +59,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpenVideo = (options) => {
|
handleOpenVideo = (options) => {
|
||||||
this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options);
|
this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options);
|
||||||
@ -67,9 +67,9 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||||||
|
|
||||||
handleExpandedToggle = () => {
|
handleExpandedToggle = () => {
|
||||||
this.props.onToggleHidden(this.props.status);
|
this.props.onToggleHidden(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
_measureHeight (heightJustChanged) {
|
_measureHeight(heightJustChanged) {
|
||||||
if (this.props.measureHeight && this.node) {
|
if (this.props.measureHeight && this.node) {
|
||||||
scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 }));
|
scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 }));
|
||||||
|
|
||||||
@ -82,9 +82,9 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
this._measureHeight();
|
this._measureHeight();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidUpdate (prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
this._measureHeight(prevState.height !== this.state.height);
|
this._measureHeight(prevState.height !== this.state.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,10 +100,13 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
|
||||||
|
render() {
|
||||||
const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
|
const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
|
||||||
|
console.log('status in render ', status);
|
||||||
|
|
||||||
const outerStyle = { boxSizing: 'border-box' };
|
const outerStyle = { boxSizing: 'border-box' };
|
||||||
const { intl, compact, pictureInPicture } = this.props;
|
const { intl, compact, pictureInPicture } = this.props;
|
||||||
|
|
||||||
@ -111,7 +114,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let media = '';
|
let media = '';
|
||||||
let applicationLink = '';
|
let applicationLink = '';
|
||||||
let reblogLink = '';
|
let reblogLink = '';
|
||||||
let reblogIcon = 'retweet';
|
let reblogIcon = 'retweet';
|
||||||
@ -172,90 +175,165 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (status.get('spoiler_text').length === 0) {
|
} else if (status.get('spoiler_text').length === 0) {
|
||||||
media = <Card sensitive={status.get('sensitive')} onOpenMedia={this.props.onOpenMedia} card={status.get('card', null)} />;
|
media = <Card
|
||||||
|
sensitive={status.get('sensitive')}
|
||||||
|
onOpenMedia={this.props.onOpenMedia}
|
||||||
|
card={status.get('card', null)}
|
||||||
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.get('application')) {
|
if (status.get('application')) {
|
||||||
applicationLink = <React.Fragment> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></React.Fragment>;
|
applicationLink = <React.Fragment > · <a
|
||||||
|
className='detailed-status__application'
|
||||||
|
href={status.getIn(['application', 'website'])}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
>{status.getIn(['application', 'name'])}</a ></React.Fragment >;
|
||||||
}
|
}
|
||||||
|
|
||||||
const visibilityIconInfo = {
|
const visibilityIconInfo = {
|
||||||
'public': { icon: 'globe', text: intl.formatMessage(messages.public_short) },
|
'public' : { icon: 'globe', text: intl.formatMessage(messages.public_short) },
|
||||||
'unlisted': { icon: 'unlock', text: intl.formatMessage(messages.unlisted_short) },
|
'unlisted': { icon: 'unlock', text: intl.formatMessage(messages.unlisted_short) },
|
||||||
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
'private' : { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
||||||
'direct': { icon: 'envelope', text: intl.formatMessage(messages.direct_short) },
|
'direct' : { icon: 'envelope', text: intl.formatMessage(messages.direct_short) },
|
||||||
};
|
};
|
||||||
|
|
||||||
const visibilityIcon = visibilityIconInfo[status.get('visibility')];
|
const visibilityIcon = visibilityIconInfo[status.get('visibility')];
|
||||||
const visibilityLink = <React.Fragment> · <Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></React.Fragment>;
|
const visibilityLink = <React.Fragment > · <Icon
|
||||||
|
id={visibilityIcon.icon}
|
||||||
|
title={visibilityIcon.text}
|
||||||
|
/></React.Fragment >;
|
||||||
|
|
||||||
if (['private', 'direct'].includes(status.get('visibility'))) {
|
if (['private', 'direct'].includes(status.get('visibility'))) {
|
||||||
reblogLink = '';
|
reblogLink = '';
|
||||||
} else if (this.context.router) {
|
} else if (this.context.router) {
|
||||||
reblogLink = (
|
reblogLink = (
|
||||||
<React.Fragment>
|
<React.Fragment >
|
||||||
<React.Fragment> · </React.Fragment>
|
<React.Fragment > · </React.Fragment >
|
||||||
<Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
|
<Link
|
||||||
|
to={`/statuses/${status.get('id')}/reblogs`}
|
||||||
|
className='detailed-status__link'
|
||||||
|
>
|
||||||
<Icon id={reblogIcon} />
|
<Icon id={reblogIcon} />
|
||||||
<span className='detailed-status__reblogs'>
|
<span className='detailed-status__reblogs'>
|
||||||
<AnimatedNumber value={status.get('reblogs_count')} />
|
<AnimatedNumber value={status.get('reblogs_count')} />
|
||||||
</span>
|
</span >
|
||||||
</Link>
|
</Link >
|
||||||
</React.Fragment>
|
</React.Fragment >
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
reblogLink = (
|
reblogLink = (
|
||||||
<React.Fragment>
|
<React.Fragment >
|
||||||
<React.Fragment> · </React.Fragment>
|
<React.Fragment > · </React.Fragment >
|
||||||
<a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
|
<a
|
||||||
|
href={`/interact/${status.get('id')}?type=reblog`}
|
||||||
|
className='detailed-status__link'
|
||||||
|
onClick={this.handleModalLink}
|
||||||
|
>
|
||||||
<Icon id={reblogIcon} />
|
<Icon id={reblogIcon} />
|
||||||
<span className='detailed-status__reblogs'>
|
<span className='detailed-status__reblogs'>
|
||||||
<AnimatedNumber value={status.get('reblogs_count')} />
|
<AnimatedNumber value={status.get('reblogs_count')} />
|
||||||
</span>
|
</span >
|
||||||
</a>
|
</a >
|
||||||
</React.Fragment>
|
</React.Fragment >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.context.router) {
|
if (this.context.router) {
|
||||||
favouriteLink = (
|
favouriteLink = (
|
||||||
<Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
|
<Link
|
||||||
|
to={`/statuses/${status.get('id')}/favourites`}
|
||||||
|
className='detailed-status__link'
|
||||||
|
>
|
||||||
<Icon id='star' />
|
<Icon id='star' />
|
||||||
<span className='detailed-status__favorites'>
|
<span className='detailed-status__favorites'>
|
||||||
<AnimatedNumber value={status.get('favourites_count')} />
|
<AnimatedNumber value={status.get('favourites_count')} />
|
||||||
</span>
|
</span >
|
||||||
</Link>
|
</Link >
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
favouriteLink = (
|
favouriteLink = (
|
||||||
<a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
|
<a
|
||||||
|
href={`/interact/${status.get('id')}?type=favourite`}
|
||||||
|
className='detailed-status__link'
|
||||||
|
onClick={this.handleModalLink}
|
||||||
|
>
|
||||||
<Icon id='star' />
|
<Icon id='star' />
|
||||||
<span className='detailed-status__favorites'>
|
<span className='detailed-status__favorites'>
|
||||||
<AnimatedNumber value={status.get('favourites_count')} />
|
<AnimatedNumber value={status.get('favourites_count')} />
|
||||||
</span>
|
</span >
|
||||||
</a>
|
</a >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
* - find a way to list correctly all the other status of the conversation
|
||||||
|
* - display the correct number of replies
|
||||||
|
* - use a style left padded to show which answer is for the first status
|
||||||
|
* - group the posts answering to the first status if the user is the same, to show properly a "thread".
|
||||||
|
* */
|
||||||
|
console.log('status', status)
|
||||||
|
|
||||||
|
// console.log('status.get(\'descendants\')', status.get('descendants'));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={outerStyle}>
|
<div style={outerStyle}>
|
||||||
<div ref={this.setRef} className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })}>
|
<div
|
||||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
|
ref={this.setRef}
|
||||||
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
|
className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })}
|
||||||
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
|
>
|
||||||
</a>
|
{/*<div className='detailed-status__meta_topic'> conversation_id : {status.get('conversation_id')} </div >*/}
|
||||||
|
{/*<div className='detailed-status__meta_topic'> replies : {status.get('replies_count')} </div >*/}
|
||||||
|
<a
|
||||||
|
href={status.getIn(['account', 'url'])}
|
||||||
|
onClick={this.handleAccountClick}
|
||||||
|
className='detailed-status__display-name'
|
||||||
|
>
|
||||||
|
<div className='detailed-status__display-avatar'><Avatar
|
||||||
|
account={status.get('account')}
|
||||||
|
size={48}
|
||||||
|
/></div >
|
||||||
|
<DisplayName
|
||||||
|
account={status.get('account')}
|
||||||
|
localDomain={this.props.domain}
|
||||||
|
/>
|
||||||
|
</a >
|
||||||
|
|
||||||
<StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
|
<StatusContent
|
||||||
|
status={status}
|
||||||
|
expanded={!status.get('hidden')}
|
||||||
|
onExpandedToggle={this.handleExpandedToggle}
|
||||||
|
/>
|
||||||
|
|
||||||
{media}
|
{media}
|
||||||
|
|
||||||
<div className='detailed-status__meta'>
|
<div className='detailed-status__meta'>
|
||||||
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener noreferrer'>
|
<a
|
||||||
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
|
className='detailed-status__datetime'
|
||||||
</a>{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}
|
href={status.get('url')}
|
||||||
</div>
|
target='_blank'
|
||||||
</div>
|
rel='noopener noreferrer'
|
||||||
</div>
|
>
|
||||||
|
<FormattedDate
|
||||||
|
value={new Date(status.get('created_at'))}
|
||||||
|
hour12={false}
|
||||||
|
year='numeric'
|
||||||
|
month='short'
|
||||||
|
day='2-digit'
|
||||||
|
hour='2-digit'
|
||||||
|
minute='2-digit'
|
||||||
|
/>
|
||||||
|
</a >{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}
|
||||||
|
·
|
||||||
|
<Icon id='reply' />
|
||||||
|
<span >
|
||||||
|
|
||||||
|
<AnimatedNumber value={status.get('replies_count')} />
|
||||||
|
</span >
|
||||||
|
|
||||||
|
</div >
|
||||||
|
</div >
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link, NavLink } from 'react-router-dom';
|
||||||
import { invitesEnabled, version, repository, source_url } from 'mastodon/initial_state';
|
import { invitesEnabled, repository, source_url, version } from 'mastodon/initial_state';
|
||||||
import { logOut } from 'mastodon/utils/log_out';
|
import { logOut } from 'mastodon/utils/log_out';
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
|
import { isStaff } from '../../../initial_state';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
||||||
@ -13,23 +14,38 @@ const messages = defineMessages({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
onLogout () {
|
onLogout() {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
message: intl.formatMessage(messages.logoutMessage),
|
message : intl.formatMessage(messages.logoutMessage),
|
||||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
confirm : intl.formatMessage(messages.logoutConfirm),
|
||||||
onConfirm: () => logOut(),
|
onConfirm: () => logOut(),
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// const themeIsDark = true;
|
||||||
|
const displayMoreLinks = false;
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
@connect(null, mapDispatchToProps)
|
@connect(null, mapDispatchToProps)
|
||||||
class LinkFooter extends React.PureComponent {
|
class LinkFooter extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
withHotkeys: PropTypes.bool,
|
displayMoreLinks : PropTypes.bool,
|
||||||
onLogout: PropTypes.func.isRequired,
|
enableChristmasSnow : PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
minimumWeekToShowSnow: PropTypes.number,
|
||||||
|
snowActive : PropTypes.bool,
|
||||||
|
withHotkeys : PropTypes.bool,
|
||||||
|
snow : PropTypes.func,
|
||||||
|
themeIsDark : PropTypes.bool,
|
||||||
|
theme : PropTypes.string,
|
||||||
|
onLogout : PropTypes.func.isRequired,
|
||||||
|
intl : PropTypes.object.isRequired,
|
||||||
|
};
|
||||||
|
static defaultProps = {
|
||||||
|
displayMoreLinks : displayMoreLinks,
|
||||||
|
enableChristmasSnow : true,
|
||||||
|
themeIsDark : true,
|
||||||
|
minimumWeekToShowSnow: 48,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleLogoutClick = e => {
|
handleLogoutClick = e => {
|
||||||
@ -39,33 +55,256 @@ class LinkFooter extends React.PureComponent {
|
|||||||
this.props.onLogout();
|
this.props.onLogout();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
Date.prototype.getWeek = function () {
|
||||||
|
var onejan = new Date(this.getFullYear(), 0, 1);
|
||||||
|
return Math.ceil((((this - onejan) / 86400000) + onejan.getDay() + 1) / 7);
|
||||||
|
};
|
||||||
|
|
||||||
|
var weekNumber = (new Date()).getWeek();
|
||||||
|
console.log('we are the week number weekNumber', weekNumber);
|
||||||
|
// display snow during the last two weeks of the year
|
||||||
|
const shouldWeDisplaySnow = (weekNumber > props.minimumWeekToShowSnow) && props.enableChristmasSnow;
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
displayMoreLinks : props.displayMoreLinks,
|
||||||
|
enableChristmasSnow: shouldWeDisplaySnow,
|
||||||
|
theme : props.theme,
|
||||||
|
};
|
||||||
|
|
||||||
|
// make snow effect
|
||||||
|
if (shouldWeDisplaySnow) {
|
||||||
|
import('../../../utils/snowstorm-min')
|
||||||
|
.then((snowstorm) => {
|
||||||
|
Window.snowstorm = snowstorm.default;
|
||||||
|
this.state.snow = Window.snowstorm;
|
||||||
|
// snowstorm.start();
|
||||||
|
this.state.snowActive = true;
|
||||||
|
})
|
||||||
|
.catch((err) => console.error(err));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
toggleMoreLinks = () => {
|
||||||
|
this.setState({ displayMoreLinks: !this.state.displayMoreLinks });
|
||||||
|
console.log('this.state.displayMoreLinks', this.state.displayMoreLinks);
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleSnow = () => {
|
||||||
|
if (this.state.snow) {
|
||||||
|
if (this.state.snowActive) {
|
||||||
|
this.state.snow.stop();
|
||||||
|
this.state.enableChristmasSnow = false;
|
||||||
|
} else {
|
||||||
|
this.state.snow.start();
|
||||||
|
this.state.enableChristmasSnow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
changeTheme(newTheme) {
|
||||||
|
console.log('change theme en ', newTheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const HashTagNavlinks = ['Mastoart', 'OpenStreetMaps', 'Ironèmes', 'vélo'];
|
||||||
const { withHotkeys } = this.props;
|
const { withHotkeys } = this.props;
|
||||||
|
var snowClasses = this.props.enableChristmasSnow ? 'snow-button active' : 'snow-button ';
|
||||||
|
const navToTags = HashTagNavlinks.map(element => {
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
className='tag-element'
|
||||||
|
key={element}
|
||||||
|
>
|
||||||
|
|
||||||
|
<NavLink
|
||||||
|
exact
|
||||||
|
activeClassName='active'
|
||||||
|
to={'/timelines/tag/' + element}
|
||||||
|
title='Mastoart'
|
||||||
|
>
|
||||||
|
#{element}
|
||||||
|
</NavLink >
|
||||||
|
</li >
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='getting-started__footer'>
|
|
||||||
<ul>
|
|
||||||
{invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
|
|
||||||
{withHotkeys && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
|
|
||||||
<li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>
|
|
||||||
<li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>
|
|
||||||
<li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
|
|
||||||
<li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
|
|
||||||
<li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>
|
|
||||||
<li><a href='https://docs.joinmastodon.org' target='_blank'><FormattedMessage id='getting_started.documentation' defaultMessage='Documentation' /></a> · </li>
|
|
||||||
<li><a href='/auth/sign_out' onClick={this.handleLogoutClick}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
<div className='links-started__footer desktop-only'>
|
||||||
<FormattedMessage
|
|
||||||
id='getting_started.open_source_notice'
|
<a href='https://mastodon.cipherbliss.com/@tykayn'>
|
||||||
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
<i className='fa fa-paper-plane' />
|
||||||
values={{ github: <span><a href={source_url} rel='noopener noreferrer' target='_blank'>{repository}</a> (v{version})</span> }}
|
contactez l'admin
|
||||||
/>
|
</a >
|
||||||
</p>
|
<a href='https://liberapay.com/cipherbliss'>
|
||||||
</div>
|
<i className='fa fa-coffee' /> Supportez
|
||||||
|
Cipherbliss</a >
|
||||||
|
<div className='extras'>
|
||||||
|
|
||||||
|
{this.state.enableChristmasSnow && (
|
||||||
|
<div
|
||||||
|
onClick={this.toggleSnow}
|
||||||
|
className='christmas-snow'
|
||||||
|
>
|
||||||
|
<div className={snowClasses}>
|
||||||
|
<i
|
||||||
|
className='icon fa fa-snowflake-o'
|
||||||
|
aria-hidden='true'
|
||||||
|
/>
|
||||||
|
</div >
|
||||||
|
<div > Joyeuses fêtes!</div >
|
||||||
|
|
||||||
|
</div >
|
||||||
|
)}
|
||||||
|
{isStaff && (
|
||||||
|
<span className='staff-actions'>
|
||||||
|
|
||||||
|
<a
|
||||||
|
className='btn-warning'
|
||||||
|
href='/admin/tags?pending_review=1'
|
||||||
|
>
|
||||||
|
<i className='fa fa-fire' />
|
||||||
|
Trending hashtags
|
||||||
|
</a >
|
||||||
|
<a
|
||||||
|
className='btn-warning'
|
||||||
|
href='/admin/accounts'
|
||||||
|
>
|
||||||
|
<i className='fa fa-users' />
|
||||||
|
Comptes
|
||||||
|
</a >
|
||||||
|
</span >
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
{this.state.displayMoreLinks && (
|
||||||
|
|
||||||
|
<div
|
||||||
|
className='external-utilities'
|
||||||
|
id='#external_utilities'
|
||||||
|
>
|
||||||
|
<div >
|
||||||
|
|
||||||
|
<a href='https://events.cipherbliss.com'> <i className='fa fa-calendar ' /> Mobilizon</a >
|
||||||
|
<a href='https://peertube.cipherbliss.com'> <i className='fa fa-play ' /> Videos</a >
|
||||||
|
<a href='https://framadate.org/'> <i className='fa fa-calendar' /> Rdv</a >
|
||||||
|
<a href='https://framapad.org/'> <i className='fa fa-file-text' /> Pad</a >
|
||||||
|
<a href='https://framacalc.org/'> <i className='fa fa-cone' /> Calc</a >
|
||||||
|
<a href='https://framagit.org/tykayn/mastodon'> <i className='fa fa-gitlab' /> Source</a >
|
||||||
|
|
||||||
|
</div >
|
||||||
|
<div className='suggested-tags'>
|
||||||
|
<ul >
|
||||||
|
{navToTags}
|
||||||
|
</ul >
|
||||||
|
</div >
|
||||||
|
<div className='usual_links'>
|
||||||
|
<ul>
|
||||||
|
<li ><a href='/auth/edit'><FormattedMessage
|
||||||
|
id='getting_started.security'
|
||||||
|
defaultMessage='Security'
|
||||||
|
/></a > ·
|
||||||
|
</li >
|
||||||
|
<li ><a
|
||||||
|
href='/about/more'
|
||||||
|
target='_blank'
|
||||||
|
><FormattedMessage
|
||||||
|
id='navigation_bar.info'
|
||||||
|
defaultMessage='About this server'
|
||||||
|
/></a > ·
|
||||||
|
</li >
|
||||||
|
<li ><a
|
||||||
|
href='https://joinmastodon.org/apps'
|
||||||
|
target='_blank'
|
||||||
|
><FormattedMessage
|
||||||
|
id='navigation_bar.apps'
|
||||||
|
defaultMessage='Mobile apps'
|
||||||
|
/></a > ·
|
||||||
|
</li >
|
||||||
|
<li ><a
|
||||||
|
href='/terms'
|
||||||
|
target='_blank'
|
||||||
|
><FormattedMessage
|
||||||
|
id='getting_started.terms'
|
||||||
|
defaultMessage='Terms of service'
|
||||||
|
/></a > ·
|
||||||
|
</li >
|
||||||
|
<li ><a
|
||||||
|
href='/settings/applications'
|
||||||
|
target='_blank'
|
||||||
|
><FormattedMessage
|
||||||
|
id='getting_started.developers'
|
||||||
|
defaultMessage='Developers'
|
||||||
|
/></a > ·
|
||||||
|
</li >
|
||||||
|
<li ><a
|
||||||
|
href='https://docs.joinmastodon.org'
|
||||||
|
target='_blank'
|
||||||
|
><FormattedMessage
|
||||||
|
id='getting_started.documentation'
|
||||||
|
defaultMessage='Documentation'
|
||||||
|
/></a > ·
|
||||||
|
</li >
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p >
|
||||||
|
<FormattedMessage
|
||||||
|
id='getting_started.open_source_notice'
|
||||||
|
defaultMessage='Mastodon is open source software. You can contribute or report issues on the forge at {forge}.'
|
||||||
|
values={{
|
||||||
|
forge: <span ><a
|
||||||
|
href={source_url}
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
target='_blank'
|
||||||
|
>{repository}</a > (v{version})</span >,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</p >
|
||||||
|
</div >
|
||||||
|
|
||||||
|
)}
|
||||||
|
</div >
|
||||||
|
|
||||||
|
<ul >
|
||||||
|
{invitesEnabled && <li ><a
|
||||||
|
href='/invites'
|
||||||
|
target='_blank'
|
||||||
|
><FormattedMessage
|
||||||
|
id='getting_started.invite'
|
||||||
|
defaultMessage='Invite people'
|
||||||
|
/></a > · </li >}
|
||||||
|
{withHotkeys && <li >
|
||||||
|
<Link to='/keyboard-shortcuts'><FormattedMessage
|
||||||
|
id='navigation_bar.keyboard_shortcuts'
|
||||||
|
defaultMessage='Hotkeys'
|
||||||
|
/></Link > · </li >}
|
||||||
|
|
||||||
|
<li ><a
|
||||||
|
href='/auth/sign_out'
|
||||||
|
onClick={this.handleLogoutClick}
|
||||||
|
><FormattedMessage
|
||||||
|
id='navigation_bar.logout'
|
||||||
|
defaultMessage='Logout'
|
||||||
|
/></a ></li >
|
||||||
|
</ul >
|
||||||
|
<a
|
||||||
|
className='toggle_links '
|
||||||
|
data-active={this.state.displayMoreLinks }
|
||||||
|
|
||||||
|
|
||||||
|
href='#external_utilities'
|
||||||
|
onClick={this.toggleMoreLinks}
|
||||||
|
>
|
||||||
|
<i className='fa fa-list-ul' />
|
||||||
|
</a >
|
||||||
|
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default class ContactsList extends React.PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
showList : PropTypes.bool,
|
||||||
|
contactList : PropTypes.array,
|
||||||
|
conversationList: PropTypes.array,
|
||||||
|
};
|
||||||
|
static defaultProps = {
|
||||||
|
showList : true,
|
||||||
|
contactList: ['machin', 'bidule', 'chuck norris'],
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
showList : true,
|
||||||
|
contactList : ['machin', 'bidule', 'chuck norris'],
|
||||||
|
conversationList: ['machin', 'bidule', 'chuck norris'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
submitCompose() {
|
||||||
|
console.log('submit message');
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleList = () => {
|
||||||
|
console.log('toggle');
|
||||||
|
this.setState((state) => {
|
||||||
|
console.log('state.showList', state.showList);
|
||||||
|
return {
|
||||||
|
showList: !state.showList,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div >
|
||||||
|
// liste de contacts
|
||||||
|
// </div >
|
||||||
|
// );
|
||||||
|
|
||||||
|
const renderedList = this.state.contactList.forEach(elem => {
|
||||||
|
return (
|
||||||
|
<li className='contact-item'>
|
||||||
|
{elem}
|
||||||
|
</li >
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div className='messaging-container'>
|
||||||
|
<div className='messaging-box'>
|
||||||
|
<div className='title column-header'>
|
||||||
|
<i
|
||||||
|
role='img'
|
||||||
|
className='fa fa-envelope column-header__icon fa-fw'
|
||||||
|
/>
|
||||||
|
Messaging box
|
||||||
|
|
||||||
|
</div >
|
||||||
|
<div className='user-list column-header'>
|
||||||
|
<h2 className='title'>la liste de {this.state.contactList.lengh} contacts
|
||||||
|
|
||||||
|
<button
|
||||||
|
className='btn btn-primary'
|
||||||
|
onClick={this.toggleList}
|
||||||
|
>
|
||||||
|
<i className='fa fa-caret-up' />
|
||||||
|
</button >
|
||||||
|
</h2 >
|
||||||
|
{this.state.showList && (
|
||||||
|
<div className='contact-list-container'>
|
||||||
|
<h3 >show list</h3 >
|
||||||
|
<ul className='contact-list'>
|
||||||
|
{renderedList}
|
||||||
|
</ul >
|
||||||
|
</div >
|
||||||
|
)}
|
||||||
|
</div >
|
||||||
|
|
||||||
|
</div >
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default class ConversationItem extends React.PureComponent {
|
||||||
|
|
||||||
|
following = [];
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
const list = (
|
||||||
|
<li className='conversations_item has-new-message'>
|
||||||
|
<div className='title'>
|
||||||
|
<i
|
||||||
|
role='img'
|
||||||
|
className='fa fa-envelope column-header__icon fa-fw'
|
||||||
|
/>
|
||||||
|
Un Gens
|
||||||
|
<span className='new-message-counter'>
|
||||||
|
(3)</span >
|
||||||
|
<button className='btn-small'>
|
||||||
|
<i
|
||||||
|
role='img'
|
||||||
|
className='fa fa-caret-down column-header__icon fa-fw'
|
||||||
|
/>
|
||||||
|
</button >
|
||||||
|
</div >
|
||||||
|
<div className='conversation_stream'>
|
||||||
|
<div className='message theirs'>
|
||||||
|
<p >oh hello there! 😋 </p >
|
||||||
|
<div className='arrow-down' />
|
||||||
|
</div >
|
||||||
|
<div className='message mine'>
|
||||||
|
<p >General Emoji</p >
|
||||||
|
<div className='arrow-down' />
|
||||||
|
</div >
|
||||||
|
<div className='message theirs'>
|
||||||
|
<p >we just achieved comedy</p >
|
||||||
|
<div className='arrow-down' />
|
||||||
|
</div >
|
||||||
|
</div >
|
||||||
|
<div className='conversation_input'>
|
||||||
|
<form
|
||||||
|
action='#'
|
||||||
|
onSubmit={this.submitCompose()}
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
name='messager'
|
||||||
|
id=''
|
||||||
|
cols='15'
|
||||||
|
rows='3'
|
||||||
|
className='messager-textarea'
|
||||||
|
placeholder='allez dis nous tout'
|
||||||
|
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type='submit'
|
||||||
|
name='submit'
|
||||||
|
value='Send'
|
||||||
|
/>
|
||||||
|
</form >
|
||||||
|
</div >
|
||||||
|
</li >
|
||||||
|
);
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default class ConversationStream extends React.PureComponent {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div class='conversation-stream'>
|
||||||
|
ConversationStream todo
|
||||||
|
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const following = ['bidule', 'chose', 'truc'];
|
||||||
|
|
||||||
|
export default class Conversation extends React.Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
following: PropTypes.array,
|
||||||
|
// conversations: PropTypes.array,
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
following: following,
|
||||||
|
};
|
||||||
|
|
||||||
|
openConversationWith(name) {
|
||||||
|
console.log('openConversationWith name', name);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return this.props.following.map(elem =>
|
||||||
|
|
||||||
|
(<li className='user-item'>
|
||||||
|
<div
|
||||||
|
className='username'
|
||||||
|
onClick={this.openConversationWith(elem)}
|
||||||
|
>
|
||||||
|
Machin {elem}
|
||||||
|
</div >
|
||||||
|
<div className='last-active'>3 min</div >
|
||||||
|
</li >),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ContactsList from './contacts-list';
|
||||||
|
|
||||||
|
export default class InstantMessaging extends React.PureComponent {
|
||||||
|
|
||||||
|
// static propTypes = {
|
||||||
|
// following : PropTypes.array,
|
||||||
|
// conversations: PropTypes.array,
|
||||||
|
// };
|
||||||
|
// static defaultProps = {
|
||||||
|
// threadsCompile: true,
|
||||||
|
// };
|
||||||
|
// openConversationWith(account) {
|
||||||
|
// let conversationFound = account;
|
||||||
|
// if conversation exist, focus on it
|
||||||
|
// if (conversationFound) {
|
||||||
|
//
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// else, create conversation and focus on it
|
||||||
|
// };
|
||||||
|
|
||||||
|
// submitCompose() {
|
||||||
|
//
|
||||||
|
// };
|
||||||
|
|
||||||
|
// constructor() {
|
||||||
|
// super();
|
||||||
|
//
|
||||||
|
// this.props.conversations = [
|
||||||
|
// {
|
||||||
|
// withAccount: '@machin',
|
||||||
|
// messages : [],
|
||||||
|
// opened : true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// withAccount: '@chuck',
|
||||||
|
// messages : [],
|
||||||
|
// opened : false,
|
||||||
|
// },
|
||||||
|
// ];
|
||||||
|
// this.props.following = [
|
||||||
|
// { username: 'wulfila', handle: '@wulfila' },
|
||||||
|
// { username: 'machin', handle: '@machin' },
|
||||||
|
// { username: 'chuck norris', handle: '@chuck' },
|
||||||
|
// ];
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div >
|
||||||
|
<div className='debug'>
|
||||||
|
|
||||||
|
messagerie todo
|
||||||
|
|
||||||
|
<ContactsList />
|
||||||
|
</div >
|
||||||
|
{/*<Conversation />*/}
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -10,27 +10,154 @@ import TrendsContainer from 'mastodon/features/getting_started/containers/trends
|
|||||||
|
|
||||||
const NavigationPanel = () => (
|
const NavigationPanel = () => (
|
||||||
<div className='navigation-panel'>
|
<div className='navigation-panel'>
|
||||||
<NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
|
<div className='small-texts timelines'>
|
||||||
<NavLink className='column-link column-link--transparent' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon className='column-link__icon' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/timelines/home'
|
||||||
|
data-preview-title-id='column.home'
|
||||||
|
data-preview-icon='home'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='home'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.home'
|
||||||
|
defaultMessage='Home'
|
||||||
|
/></NavLink >
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/timelines/public/local'
|
||||||
|
data-preview-title-id='column.community'
|
||||||
|
data-preview-icon='users'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='users'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.local_timeline'
|
||||||
|
defaultMessage='Local'
|
||||||
|
/></NavLink >
|
||||||
|
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
exact
|
||||||
|
to='/timelines/public'
|
||||||
|
data-preview-title-id='column.public'
|
||||||
|
data-preview-icon='globe'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='globe'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.federated_timeline'
|
||||||
|
defaultMessage='Federated'
|
||||||
|
/></NavLink >
|
||||||
|
|
||||||
|
</div >
|
||||||
|
<div className='spacer' />
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/notifications'
|
||||||
|
data-preview-title-id='column.notifications'
|
||||||
|
data-preview-icon='bell'
|
||||||
|
><NotificationsCounterIcon
|
||||||
|
className='column-link__icon'
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.notifications'
|
||||||
|
defaultMessage='Notifications'
|
||||||
|
/></NavLink >
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/timelines/direct'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='envelope'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='navigation_bar.direct'
|
||||||
|
defaultMessage='Direct messages'
|
||||||
|
/></NavLink >
|
||||||
<FollowRequestsNavLink />
|
<FollowRequestsNavLink />
|
||||||
<NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
|
|
||||||
<NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
|
<div className='spacer' />
|
||||||
<NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' id='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
|
|
||||||
<NavLink className='column-link column-link--transparent' to='/favourites'><Icon className='column-link__icon' id='star' fixedWidth /><FormattedMessage id='navigation_bar.favourites' defaultMessage='Favourites' /></NavLink>
|
<NavLink
|
||||||
<NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' id='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></NavLink>
|
className='column-link column-link--transparent'
|
||||||
<NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' id='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
|
to='/favourites'
|
||||||
{profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='star'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='navigation_bar.favourites'
|
||||||
|
defaultMessage='Favourites'
|
||||||
|
/></NavLink >
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/bookmarks'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='bookmark'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='navigation_bar.bookmarks'
|
||||||
|
defaultMessage='Bookmarks'
|
||||||
|
/></NavLink >
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/lists'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='list-ul'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='navigation_bar.lists'
|
||||||
|
defaultMessage='Lists'
|
||||||
|
/></NavLink >
|
||||||
|
{profile_directory &&
|
||||||
|
<NavLink
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
to='/directory'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='address-book-o'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='getting_started.directory'
|
||||||
|
defaultMessage='Profile directory'
|
||||||
|
/></NavLink >}
|
||||||
|
|
||||||
<ListPanel />
|
<ListPanel />
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<a className='column-link column-link--transparent' href='/settings/preferences'><Icon className='column-link__icon' id='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>
|
<a
|
||||||
<a className='column-link column-link--transparent' href='/relationships'><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>
|
className='column-link column-link--transparent'
|
||||||
|
href='/settings/preferences'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='cog'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='navigation_bar.preferences'
|
||||||
|
defaultMessage='Preferences'
|
||||||
|
/></a >
|
||||||
|
<a
|
||||||
|
className='column-link column-link--transparent'
|
||||||
|
href='/relationships'
|
||||||
|
><Icon
|
||||||
|
className='column-link__icon'
|
||||||
|
id='users'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='navigation_bar.follows_and_followers'
|
||||||
|
defaultMessage='Follows and followers'
|
||||||
|
/></a >
|
||||||
|
|
||||||
{showTrends && <div className='flex-spacer' />}
|
{showTrends && <div className='flex-spacer' />}
|
||||||
{showTrends && <TrendsContainer />}
|
{showTrends && <TrendsContainer />}
|
||||||
</div>
|
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
|
|
||||||
export default withRouter(NavigationPanel);
|
export default withRouter(NavigationPanel);
|
||||||
|
@ -8,19 +8,81 @@ import Icon from 'mastodon/components/icon';
|
|||||||
import NotificationsCounterIcon from './notifications_counter_icon';
|
import NotificationsCounterIcon from './notifications_counter_icon';
|
||||||
|
|
||||||
export const links = [
|
export const links = [
|
||||||
<NavLink className='tabs-bar__link' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
|
<NavLink
|
||||||
<NavLink className='tabs-bar__link' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>,
|
className='tabs-bar__link'
|
||||||
<NavLink className='tabs-bar__link' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
|
to='/timelines/home'
|
||||||
<NavLink className='tabs-bar__link' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
|
data-preview-title-id='column.home'
|
||||||
<NavLink className='tabs-bar__link optional' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><Icon id='search' fixedWidth /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
|
data-preview-icon='home'
|
||||||
<NavLink className='tabs-bar__link' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='bars' ><Icon id='bars' fixedWidth /></NavLink>,
|
><Icon
|
||||||
|
id='home'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.home'
|
||||||
|
defaultMessage='Home'
|
||||||
|
/></NavLink >,
|
||||||
|
<NavLink
|
||||||
|
className='tabs-bar__link'
|
||||||
|
to='/notifications'
|
||||||
|
data-preview-title-id='column.notifications'
|
||||||
|
data-preview-icon='bell'
|
||||||
|
><NotificationsCounterIcon /><FormattedMessage
|
||||||
|
id='tabs_bar.notifications'
|
||||||
|
defaultMessage='Notifications'
|
||||||
|
/></NavLink >,
|
||||||
|
<NavLink
|
||||||
|
className='tabs-bar__link'
|
||||||
|
to='/timelines/public/local'
|
||||||
|
data-preview-title-id='column.community'
|
||||||
|
data-preview-icon='users'
|
||||||
|
><Icon
|
||||||
|
id='users'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.local_timeline'
|
||||||
|
defaultMessage='Local'
|
||||||
|
/></NavLink >,
|
||||||
|
<NavLink
|
||||||
|
className='tabs-bar__link'
|
||||||
|
exact
|
||||||
|
to='/timelines/public'
|
||||||
|
data-preview-title-id='column.public'
|
||||||
|
data-preview-icon='globe'
|
||||||
|
><Icon
|
||||||
|
id='globe'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.federated_timeline'
|
||||||
|
defaultMessage='Federated'
|
||||||
|
/></NavLink >,
|
||||||
|
<NavLink
|
||||||
|
className='tabs-bar__link optional'
|
||||||
|
to='/search'
|
||||||
|
data-preview-title-id='tabs_bar.search'
|
||||||
|
data-preview-icon='bell'
|
||||||
|
><Icon
|
||||||
|
id='search'
|
||||||
|
fixedWidth
|
||||||
|
/><FormattedMessage
|
||||||
|
id='tabs_bar.search'
|
||||||
|
defaultMessage='Search'
|
||||||
|
/></NavLink >,
|
||||||
|
<NavLink
|
||||||
|
className='tabs-bar__link'
|
||||||
|
style={{ flexGrow: '0', flexBasis: '30px' }}
|
||||||
|
to='/getting-started'
|
||||||
|
data-preview-title-id='getting_started.heading'
|
||||||
|
data-preview-icon='bars'
|
||||||
|
><Icon
|
||||||
|
id='bars'
|
||||||
|
fixedWidth
|
||||||
|
/></NavLink >,
|
||||||
];
|
];
|
||||||
|
|
||||||
export function getIndex (path) {
|
export function getIndex(path) {
|
||||||
return links.findIndex(link => link.props.to === path);
|
return links.findIndex(link => link.props.to === path);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLink (index) {
|
export function getLink(index) {
|
||||||
return links[index].props.to;
|
return links[index].props.to;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,13 +91,13 @@ export default @injectIntl
|
|||||||
class TabsBar extends React.PureComponent {
|
class TabsBar extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl : PropTypes.object.isRequired,
|
||||||
history: PropTypes.object.isRequired,
|
history: PropTypes.object.isRequired,
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = ref => {
|
setRef = ref => {
|
||||||
this.node = ref;
|
this.node = ref;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = (e) => {
|
handleClick = (e) => {
|
||||||
// Only apply optimization for touch devices, which we assume are slower
|
// Only apply optimization for touch devices, which we assume are slower
|
||||||
@ -50,7 +112,6 @@ class TabsBar extends React.PureComponent {
|
|||||||
const nextTab = tabs.find(tab => tab.contains(e.target));
|
const nextTab = tabs.find(tab => tab.contains(e.target));
|
||||||
const { props: { to } } = links[Array(...this.node.childNodes).indexOf(nextTab)];
|
const { props: { to } } = links[Array(...this.node.childNodes).indexOf(nextTab)];
|
||||||
|
|
||||||
|
|
||||||
if (currentTab !== nextTab) {
|
if (currentTab !== nextTab) {
|
||||||
if (currentTab) {
|
if (currentTab) {
|
||||||
currentTab.classList.remove('active');
|
currentTab.classList.remove('active');
|
||||||
@ -67,19 +128,28 @@ class TabsBar extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { intl: { formatMessage } } = this.props;
|
const { intl: { formatMessage } } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='tabs-bar__wrapper'>
|
<div className='tabs-bar__wrapper'>
|
||||||
<nav className='tabs-bar' ref={this.setRef}>
|
|
||||||
{links.map(link => React.cloneElement(link, { key: link.props.to, onClick: this.handleClick, 'aria-label': formatMessage({ id: link.props['data-preview-title-id'] }) }))}
|
<nav
|
||||||
</nav>
|
className='tabs-bar'
|
||||||
|
ref={this.setRef}
|
||||||
|
>
|
||||||
|
{links.map(link => React.cloneElement(link, {
|
||||||
|
key : link.props.to,
|
||||||
|
onClick : this.handleClick,
|
||||||
|
'aria-label': formatMessage({ id: link.props['data-preview-title-id'] }),
|
||||||
|
}))}
|
||||||
|
</nav >
|
||||||
|
|
||||||
<div id='tabs-bar__portal' />
|
<div id='tabs-bar__portal' />
|
||||||
</div>
|
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ class ReducedMotion extends React.Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
defaultStyle: PropTypes.object,
|
defaultStyle: PropTypes.object,
|
||||||
style: PropTypes.object,
|
style : PropTypes.object,
|
||||||
children: PropTypes.func,
|
children : PropTypes.func,
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
@ -33,9 +33,12 @@ class ReducedMotion extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Motion style={style} defaultStyle={defaultStyle}>
|
<Motion
|
||||||
|
style={style}
|
||||||
|
defaultStyle={defaultStyle}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Motion>
|
</Motion >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import {
|
import {
|
||||||
ANNOUNCEMENTS_FETCH_REQUEST,
|
|
||||||
ANNOUNCEMENTS_FETCH_SUCCESS,
|
|
||||||
ANNOUNCEMENTS_FETCH_FAIL,
|
|
||||||
ANNOUNCEMENTS_UPDATE,
|
|
||||||
ANNOUNCEMENTS_REACTION_UPDATE,
|
|
||||||
ANNOUNCEMENTS_REACTION_ADD_REQUEST,
|
|
||||||
ANNOUNCEMENTS_REACTION_ADD_FAIL,
|
|
||||||
ANNOUNCEMENTS_REACTION_REMOVE_REQUEST,
|
|
||||||
ANNOUNCEMENTS_REACTION_REMOVE_FAIL,
|
|
||||||
ANNOUNCEMENTS_TOGGLE_SHOW,
|
|
||||||
ANNOUNCEMENTS_DELETE,
|
ANNOUNCEMENTS_DELETE,
|
||||||
ANNOUNCEMENTS_DISMISS_SUCCESS,
|
ANNOUNCEMENTS_DISMISS_SUCCESS,
|
||||||
|
ANNOUNCEMENTS_FETCH_FAIL,
|
||||||
|
ANNOUNCEMENTS_FETCH_REQUEST,
|
||||||
|
ANNOUNCEMENTS_FETCH_SUCCESS,
|
||||||
|
ANNOUNCEMENTS_REACTION_ADD_FAIL,
|
||||||
|
ANNOUNCEMENTS_REACTION_ADD_REQUEST,
|
||||||
|
ANNOUNCEMENTS_REACTION_REMOVE_FAIL,
|
||||||
|
ANNOUNCEMENTS_REACTION_REMOVE_REQUEST,
|
||||||
|
ANNOUNCEMENTS_REACTION_UPDATE,
|
||||||
|
ANNOUNCEMENTS_TOGGLE_SHOW,
|
||||||
|
ANNOUNCEMENTS_UPDATE,
|
||||||
} from '../actions/announcements';
|
} from '../actions/announcements';
|
||||||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
import { fromJS, List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
items: ImmutableList(),
|
items: ImmutableList(),
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
import {
|
import {
|
||||||
REBLOG_REQUEST,
|
|
||||||
REBLOG_FAIL,
|
|
||||||
FAVOURITE_REQUEST,
|
|
||||||
FAVOURITE_FAIL,
|
|
||||||
UNFAVOURITE_SUCCESS,
|
|
||||||
BOOKMARK_REQUEST,
|
|
||||||
BOOKMARK_FAIL,
|
BOOKMARK_FAIL,
|
||||||
|
BOOKMARK_REQUEST,
|
||||||
|
FAVOURITE_FAIL,
|
||||||
|
FAVOURITE_REQUEST,
|
||||||
|
REBLOG_FAIL,
|
||||||
|
REBLOG_REQUEST,
|
||||||
|
UNFAVOURITE_SUCCESS,
|
||||||
} from '../actions/interactions';
|
} from '../actions/interactions';
|
||||||
import {
|
import {
|
||||||
STATUS_MUTE_SUCCESS,
|
|
||||||
STATUS_UNMUTE_SUCCESS,
|
|
||||||
STATUS_REVEAL,
|
|
||||||
STATUS_HIDE,
|
|
||||||
STATUS_COLLAPSE,
|
STATUS_COLLAPSE,
|
||||||
|
STATUS_HIDE,
|
||||||
|
STATUS_MUTE_SUCCESS,
|
||||||
|
STATUS_REVEAL,
|
||||||
|
STATUS_UNMUTE_SUCCESS,
|
||||||
} from '../actions/statuses';
|
} from '../actions/statuses';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||||
import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer';
|
import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer';
|
||||||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
import { fromJS, Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
const importStatus = (state, status) => state.set(status.id, fromJS(status));
|
const importStatus = (state, status) => state.set(status.id, fromJS(status));
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ const deleteStatus = (state, id, references) => {
|
|||||||
const initialState = ImmutableMap();
|
const initialState = ImmutableMap();
|
||||||
|
|
||||||
export default function statuses(state = initialState, action) {
|
export default function statuses(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch (action.type) {
|
||||||
case STATUS_IMPORT:
|
case STATUS_IMPORT:
|
||||||
return importStatus(state, action.status);
|
return importStatus(state, action.status);
|
||||||
case STATUSES_IMPORT:
|
case STATUSES_IMPORT:
|
||||||
|
@ -17,6 +17,8 @@ export default () => new Promise((resolve, reject) => {
|
|||||||
const accounts = target.result.createObjectStore('accounts', { autoIncrement: true });
|
const accounts = target.result.createObjectStore('accounts', { autoIncrement: true });
|
||||||
const statuses = target.result.createObjectStore('statuses', { autoIncrement: true });
|
const statuses = target.result.createObjectStore('statuses', { autoIncrement: true });
|
||||||
|
|
||||||
|
console.log('statuses onupgradeneeded', statuses);
|
||||||
|
|
||||||
accounts.createIndex('id', 'id', { unique: true });
|
accounts.createIndex('id', 'id', { unique: true });
|
||||||
accounts.createIndex('moved', 'moved');
|
accounts.createIndex('moved', 'moved');
|
||||||
|
|
||||||
|
121
app/javascript/mastodon/utils/snowstorm-min.js
vendored
Normal file
121
app/javascript/mastodon/utils/snowstorm-min.js
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/** @license
|
||||||
|
|
||||||
|
DHTML Snowstorm! JavaScript-based snow for web pages
|
||||||
|
Making it snow on the internets since 2003. You're welcome.
|
||||||
|
-----------------------------------------------------------
|
||||||
|
Version 1.44.20131208 (Previous rev: 1.44.20131125)
|
||||||
|
Copyright (c) 2007, Scott Schiller. All rights reserved.
|
||||||
|
Code provided under the BSD License
|
||||||
|
http://schillmania.com/projects/snowstorm/license.txt
|
||||||
|
*/
|
||||||
|
var snowStorm=function(g, f){
|
||||||
|
function k(a, d){
|
||||||
|
isNaN(d)&&(d=0);return Math.random()*a+d;
|
||||||
|
}function x(){
|
||||||
|
g.setTimeout(function(){
|
||||||
|
a.start(!0);
|
||||||
|
}, 20);a.events.remove(m?f:g, 'mousemove', x);
|
||||||
|
}function y(){
|
||||||
|
(!a.excludeMobile||!D)&&x();a.events.remove(g, 'load', y);
|
||||||
|
}this.excludeMobile=this.autoStart=!0;this.flakesMax=128;this.flakesMaxActive=64;this.animationInterval=33;this.useGPU=!0;this.className=null;this.excludeMobile=!0;this.flakeBottom=null;this.followMouse=!0;this.snowColor='#fff';this.snowCharacter='•';this.snowStick=
|
||||||
|
!0;this.targetElement=null;this.useMeltEffect=!0;this.usePixelPosition=this.usePositionFixed=this.useTwinkleEffect=!1;this.freezeOnBlur=!0;this.flakeRightOffset=this.flakeLeftOffset=0;this.flakeHeight=this.flakeWidth=8;this.vMaxX=5;this.vMaxY=4;this.zIndex=0;var a=this, q, m=navigator.userAgent.match(/msie/i), E=navigator.userAgent.match(/msie 6/i), D=navigator.userAgent.match(/mobile|opera m(ob|in)/i), r=m&&'BackCompat'===f.compatMode||E, h=null, n=null, l=null, p=null, s=null, z=null, A=null, v=1, t=!1, w=!1,
|
||||||
|
u;a:{
|
||||||
|
try{
|
||||||
|
f.createElement('div').style.opacity='0.5';
|
||||||
|
}catch(F){
|
||||||
|
u=!1;break a;
|
||||||
|
}u=!0;
|
||||||
|
}var B=!1, C=f.createDocumentFragment();q=function(){
|
||||||
|
function c(b){
|
||||||
|
g.setTimeout(b, 1E3/(a.animationInterval||20));
|
||||||
|
}function d(a){
|
||||||
|
return void 0!==h.style[a]?a:null;
|
||||||
|
}var e, b=g.requestAnimationFrame||g.webkitRequestAnimationFrame||g.mozRequestAnimationFrame||g.oRequestAnimationFrame||g.msRequestAnimationFrame||c;e=b?function(){
|
||||||
|
return b.apply(g, arguments);
|
||||||
|
}:null;var h;h=f.createElement('div');e={ transform:{ ie:d('-ms-transform'),
|
||||||
|
moz:d('MozTransform'), opera:d('OTransform'), webkit:d('webkitTransform'), w3:d('transform'), prop:null }, getAnimationFrame:e };e.transform.prop=e.transform.w3||e.transform.moz||e.transform.webkit||e.transform.ie||e.transform.opera;h=null;return e;
|
||||||
|
}();this.timer=null;this.flakes=[];this.active=this.disabled=!1;this.meltFrameCount=20;this.meltFrames=[];this.setXY=function(c, d, e){
|
||||||
|
if(!c)return!1;a.usePixelPosition||w?(c.style.left=d-a.flakeWidth+'px', c.style.top=e-a.flakeHeight+'px'):r?(c.style.right=100-100*
|
||||||
|
(d/h)+'%', c.style.top=Math.min(e, s-a.flakeHeight)+'px'):a.flakeBottom?(c.style.right=100-100*(d/h)+'%', c.style.top=Math.min(e, s-a.flakeHeight)+'px'):(c.style.right=100-100*(d/h)+'%', c.style.bottom=100-100*(e/l)+'%');
|
||||||
|
};this.events=function(){
|
||||||
|
function a(c){
|
||||||
|
c=b.call(c);var d=c.length;e?(c[1]='on'+c[1], 3<d&&c.pop()):3===d&&c.push(!1);return c;
|
||||||
|
}function d(a, b){
|
||||||
|
var c=a.shift(), d=[f[b]];if(e)c[d](a[0], a[1]);else c[d].apply(c, a);
|
||||||
|
}var e=!g.addEventListener&&g.attachEvent, b=Array.prototype.slice, f={ add:e?'attachEvent':
|
||||||
|
'addEventListener', remove:e?'detachEvent':'removeEventListener' };return{ add:function(){
|
||||||
|
d(a(arguments), 'add');
|
||||||
|
}, remove:function(){
|
||||||
|
d(a(arguments), 'remove');
|
||||||
|
} };
|
||||||
|
}();this.randomizeWind=function(){
|
||||||
|
var c;c=k(a.vMaxX, 0.2);z=1===parseInt(k(2), 10)?-1*c:c;A=k(a.vMaxY, 0.2);if(this.flakes)for(c=0;c<this.flakes.length;c++)this.flakes[c].active&&this.flakes[c].setVelocities();
|
||||||
|
};this.scrollHandler=function(){
|
||||||
|
var c;p=a.flakeBottom?0:parseInt(g.scrollY||f.documentElement.scrollTop||(r?f.body.scrollTop:0), 10);isNaN(p)&&
|
||||||
|
(p=0);if(!t&&!a.flakeBottom&&a.flakes)for(c=0;c<a.flakes.length;c++)0===a.flakes[c].active&&a.flakes[c].stick();
|
||||||
|
};this.resizeHandler=function(){
|
||||||
|
g.innerWidth||g.innerHeight?(h=g.innerWidth-16-a.flakeRightOffset, l=a.flakeBottom||g.innerHeight):(h=(f.documentElement.clientWidth||f.body.clientWidth||f.body.scrollWidth)-(!m?8:0)-a.flakeRightOffset, l=a.flakeBottom||f.documentElement.clientHeight||f.body.clientHeight||f.body.scrollHeight);s=f.body.offsetHeight;n=parseInt(h/2, 10);
|
||||||
|
};this.resizeHandlerAlt=function(){
|
||||||
|
h=
|
||||||
|
a.targetElement.offsetWidth-a.flakeRightOffset;l=a.flakeBottom||a.targetElement.offsetHeight;n=parseInt(h/2, 10);s=f.body.offsetHeight;
|
||||||
|
};this.freeze=function(){
|
||||||
|
if(a.disabled)return!1;a.disabled=1;a.timer=null;
|
||||||
|
};this.resume=function(){
|
||||||
|
if(a.disabled)a.disabled=0;else return!1;a.timerInit();
|
||||||
|
};this.toggleSnow=function(){
|
||||||
|
a.flakes.length?(a.active=!a.active, a.active?(a.show(), a.resume()):(a.stop(), a.freeze())):a.start();
|
||||||
|
};this.stop=function(){
|
||||||
|
var c;this.freeze();for(c=0;c<this.flakes.length;c++)this.flakes[c].o.style.display=
|
||||||
|
'none';a.events.remove(g, 'scroll', a.scrollHandler);a.events.remove(g, 'resize', a.resizeHandler);a.freezeOnBlur&&(m?(a.events.remove(f, 'focusout', a.freeze), a.events.remove(f, 'focusin', a.resume)):(a.events.remove(g, 'blur', a.freeze), a.events.remove(g, 'focus', a.resume)));
|
||||||
|
};this.show=function(){
|
||||||
|
var a;for(a=0;a<this.flakes.length;a++)this.flakes[a].o.style.display='block';
|
||||||
|
};this.SnowFlake=function(c, d, e){
|
||||||
|
var b=this;this.type=c;this.x=d||parseInt(k(h-20), 10);this.y=!isNaN(e)?e:-k(l)-12;this.vY=this.vX=null;
|
||||||
|
this.vAmpTypes=[1, 1.2, 1.4, 1.6, 1.8];this.vAmp=this.vAmpTypes[this.type]||1;this.melting=!1;this.meltFrameCount=a.meltFrameCount;this.meltFrames=a.meltFrames;this.twinkleFrame=this.meltFrame=0;this.active=1;this.fontSize=10+10*(this.type/5);this.o=f.createElement('div');this.o.innerHTML=a.snowCharacter;a.className&&this.o.setAttribute('class', a.className);this.o.style.color=a.snowColor;this.o.style.position=t?'fixed':'absolute';a.useGPU&&q.transform.prop&&(this.o.style[q.transform.prop]='translate3d(0px, 0px, 0px)');
|
||||||
|
this.o.style.width=a.flakeWidth+'px';this.o.style.height=a.flakeHeight+'px';this.o.style.fontFamily='arial,verdana';this.o.style.cursor='default';this.o.style.overflow='hidden';this.o.style.fontWeight='normal';this.o.style.zIndex=a.zIndex;C.appendChild(this.o);this.refresh=function(){
|
||||||
|
if(isNaN(b.x)||isNaN(b.y))return!1;a.setXY(b.o, b.x, b.y);
|
||||||
|
};this.stick=function(){
|
||||||
|
r||a.targetElement!==f.documentElement&&a.targetElement!==f.body?b.o.style.top=l+p-a.flakeHeight+'px':a.flakeBottom?b.o.style.top=a.flakeBottom+
|
||||||
|
'px':(b.o.style.display='none', b.o.style.bottom='0%', b.o.style.position='fixed', b.o.style.display='block');
|
||||||
|
};this.vCheck=function(){
|
||||||
|
0<=b.vX&&0.2>b.vX?b.vX=0.2:0>b.vX&&-0.2<b.vX&&(b.vX=-0.2);0<=b.vY&&0.2>b.vY&&(b.vY=0.2);
|
||||||
|
};this.move=function(){
|
||||||
|
var c=b.vX*v;b.x+=c;b.y+=b.vY*b.vAmp;b.x>=h||h-b.x<a.flakeWidth?b.x=0:0>c&&b.x-a.flakeLeftOffset<-a.flakeWidth&&(b.x=h-a.flakeWidth-1);b.refresh();l+p-b.y+a.flakeHeight<a.flakeHeight?(b.active=0, a.snowStick?b.stick():b.recycle()):(a.useMeltEffect&&(b.active&&3>
|
||||||
|
b.type&&!b.melting&&0.998<Math.random())&&(b.melting=!0, b.melt()), a.useTwinkleEffect&&(0>b.twinkleFrame?0.97<Math.random()&&(b.twinkleFrame=parseInt(8*Math.random(), 10)):(b.twinkleFrame--, u?b.o.style.opacity=b.twinkleFrame&&0===b.twinkleFrame%2?0:1:b.o.style.visibility=b.twinkleFrame&&0===b.twinkleFrame%2?'hidden':'visible')));
|
||||||
|
};this.animate=function(){
|
||||||
|
b.move();
|
||||||
|
};this.setVelocities=function(){
|
||||||
|
b.vX=z+k(0.12*a.vMaxX, 0.1);b.vY=A+k(0.12*a.vMaxY, 0.1);
|
||||||
|
};this.setOpacity=function(a, b){
|
||||||
|
if(!u)return!1;a.style.opacity=
|
||||||
|
b;
|
||||||
|
};this.melt=function(){
|
||||||
|
!a.useMeltEffect||!b.melting?b.recycle():b.meltFrame<b.meltFrameCount?(b.setOpacity(b.o, b.meltFrames[b.meltFrame]), b.o.style.fontSize=b.fontSize-b.fontSize*(b.meltFrame/b.meltFrameCount)+'px', b.o.style.lineHeight=a.flakeHeight+2+0.75*a.flakeHeight*(b.meltFrame/b.meltFrameCount)+'px', b.meltFrame++):b.recycle();
|
||||||
|
};this.recycle=function(){
|
||||||
|
b.o.style.display='none';b.o.style.position=t?'fixed':'absolute';b.o.style.bottom='auto';b.setVelocities();b.vCheck();b.meltFrame=0;b.melting=
|
||||||
|
!1;b.setOpacity(b.o, 1);b.o.style.padding='0px';b.o.style.margin='0px';b.o.style.fontSize=b.fontSize+'px';b.o.style.lineHeight=a.flakeHeight+2+'px';b.o.style.textAlign='center';b.o.style.verticalAlign='baseline';b.x=parseInt(k(h-a.flakeWidth-20), 10);b.y=parseInt(-1*k(l), 10)-a.flakeHeight;b.refresh();b.o.style.display='block';b.active=1;
|
||||||
|
};this.recycle();this.refresh();
|
||||||
|
};this.snow=function(){
|
||||||
|
var c=0, d=null, e, d=0;for(e=a.flakes.length;d<e;d++)1===a.flakes[d].active&&(a.flakes[d].move(), c++), a.flakes[d].melting&&
|
||||||
|
a.flakes[d].melt();c<a.flakesMaxActive&&(d=a.flakes[parseInt(k(a.flakes.length), 10)], 0===d.active&&(d.melting=!0));a.timer&&q.getAnimationFrame(a.snow);
|
||||||
|
};this.mouseMove=function(c){
|
||||||
|
if(!a.followMouse)return!0;c=parseInt(c.clientX, 10);c<n?v=-2+2*(c/n):(c-=n, v=2*(c/n));
|
||||||
|
};this.createSnow=function(c, d){
|
||||||
|
var e;for(e=0;e<c;e++)if(a.flakes[a.flakes.length]=new a.SnowFlake(parseInt(k(6), 10)), d||e>a.flakesMaxActive)a.flakes[a.flakes.length-1].active=-1;a.targetElement.appendChild(C);
|
||||||
|
};this.timerInit=function(){
|
||||||
|
a.timer=
|
||||||
|
!0;a.snow();
|
||||||
|
};this.init=function(){
|
||||||
|
var c;for(c=0;c<a.meltFrameCount;c++)a.meltFrames.push(1-c/a.meltFrameCount);a.randomizeWind();a.createSnow(a.flakesMax);a.events.add(g, 'resize', a.resizeHandler);a.events.add(g, 'scroll', a.scrollHandler);a.freezeOnBlur&&(m?(a.events.add(f, 'focusout', a.freeze), a.events.add(f, 'focusin', a.resume)):(a.events.add(g, 'blur', a.freeze), a.events.add(g, 'focus', a.resume)));a.resizeHandler();a.scrollHandler();a.followMouse&&a.events.add(m?f:g, 'mousemove', a.mouseMove);a.animationInterval=
|
||||||
|
Math.max(20, a.animationInterval);a.timerInit();
|
||||||
|
};this.start=function(c){
|
||||||
|
if(B){
|
||||||
|
if(c)return!0;
|
||||||
|
}else B=!0;if('string'===typeof a.targetElement&&(c=a.targetElement, a.targetElement=f.getElementById(c), !a.targetElement))throw Error('Snowstorm: Unable to get targetElement "'+c+'"');a.targetElement||(a.targetElement=f.body||f.documentElement);a.targetElement!==f.documentElement&&a.targetElement!==f.body&&(a.resizeHandler=a.resizeHandlerAlt, a.usePixelPosition=!0);a.resizeHandler();a.usePositionFixed=a.usePositionFixed&&
|
||||||
|
!r&&!a.flakeBottom;if(g.getComputedStyle)try{
|
||||||
|
w='relative'===g.getComputedStyle(a.targetElement, null).getPropertyValue('position');
|
||||||
|
}catch(d){
|
||||||
|
w=!1;
|
||||||
|
}t=a.usePositionFixed;h&&(l&&!a.disabled)&&(a.init(), a.active=!0);
|
||||||
|
};a.autoStart&&a.events.add(g, 'load', y, !1);return this;
|
||||||
|
}(window, document);
|
@ -36,7 +36,7 @@ delegate(document, '.filter-subset--with-select select', 'change', ({ target })
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onDomainBlockSeverityChange = (target) => {
|
const onDomainBlockSeverityChange = (target) => {
|
||||||
const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media');
|
const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media');
|
||||||
const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports');
|
const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports');
|
||||||
|
|
||||||
if (rejectMediaDiv) {
|
if (rejectMediaDiv) {
|
||||||
|
33
app/javascript/styles/bliss.scss
Normal file
33
app/javascript/styles/bliss.scss
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//@import 'mastodon/variables';
|
||||||
|
@import 'bliss/variables';
|
||||||
|
@import 'bliss/mixins';
|
||||||
|
@import 'fonts/roboto';
|
||||||
|
@import 'fonts/roboto-mono';
|
||||||
|
@import 'fonts/montserrat';
|
||||||
|
|
||||||
|
@import 'bliss/reset';
|
||||||
|
@import 'bliss/messaging';
|
||||||
|
@import 'bliss/general_overrides';
|
||||||
|
@import 'bliss/basics';
|
||||||
|
@import 'bliss/containers';
|
||||||
|
@import 'bliss/lists';
|
||||||
|
@import 'bliss/footer';
|
||||||
|
@import 'bliss/compact_header';
|
||||||
|
@import 'bliss/widgets';
|
||||||
|
@import 'bliss/forms';
|
||||||
|
@import 'bliss/accounts';
|
||||||
|
@import 'bliss/statuses';
|
||||||
|
@import 'bliss/boost';
|
||||||
|
@import 'bliss/components';
|
||||||
|
@import 'bliss/polls';
|
||||||
|
@import 'bliss/introduction';
|
||||||
|
@import 'bliss/modal';
|
||||||
|
@import 'bliss/emoji_picker';
|
||||||
|
@import 'bliss/about';
|
||||||
|
@import 'bliss/tables';
|
||||||
|
@import 'bliss/admin';
|
||||||
|
@import 'bliss/dashboard';
|
||||||
|
@import 'bliss/rtl';
|
||||||
|
@import 'bliss/accessibility';
|
||||||
|
|
||||||
|
|
161
app/javascript/styles/bliss/_general_overrides.scss
Normal file
161
app/javascript/styles/bliss/_general_overrides.scss
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
@import './variables';
|
||||||
|
|
||||||
|
.columns-area__panels {
|
||||||
|
|
||||||
|
background: url('../images/elephant_ui_plane.svg') no-repeat left bottom fixed, url('../images/logo_cipherbliss.png') no-repeat right bottom fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__content {
|
||||||
|
min-height: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__wrapper {
|
||||||
|
border-left: solid 3px transparent;
|
||||||
|
transition: 0.5s all ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transition: 0.2s all ease;
|
||||||
|
border-left: solid 3px #528dc8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__wrapper {
|
||||||
|
border-left: solid 3px #528dc8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links-started__footer {
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
&:hover {
|
||||||
|
color: $gold-star;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: .5em;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
margin-right: 1ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:visited {
|
||||||
|
color: #528dc8;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $gold-star;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.staff-actions {
|
||||||
|
.fa {
|
||||||
|
|
||||||
|
color: $gold-star !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle_links {
|
||||||
|
&[data-active=true] {
|
||||||
|
background: $classic-primary-color;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.compose-form {
|
||||||
|
.reply-indicator {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.autosuggest-textarea__textarea{
|
||||||
|
color: #528dc8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-authorize--more-data {
|
||||||
|
padding: 1em;
|
||||||
|
color: white;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
a {
|
||||||
|
margin-right: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__relationship {
|
||||||
|
button {
|
||||||
|
width: 10em;
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account--panel {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account--panel__button {
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.status__content,
|
||||||
|
.status_info,
|
||||||
|
.status__content__read-more-button,
|
||||||
|
.display-name{
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__wrapper, .detailed-status__wrapper{
|
||||||
|
.status__action-bar{
|
||||||
|
opacity: 0;
|
||||||
|
transition: all ease 0.5s;
|
||||||
|
}
|
||||||
|
&:hover{
|
||||||
|
.status__action-bar{
|
||||||
|
|
||||||
|
opacity: 1;
|
||||||
|
transition: all ease 0.2s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.status__content__read-more-button {
|
||||||
|
.fa{
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
.see-more {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity ease 0.2s;
|
||||||
|
float:left;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
&:hover .see-more{
|
||||||
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu__item{
|
||||||
|
.fa{
|
||||||
|
margin-right:1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (max-width: 600px) {
|
||||||
|
.columns-area__panels {
|
||||||
|
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
app/javascript/styles/bliss/_mixins.scss
Normal file
56
app/javascript/styles/bliss/_mixins.scss
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
@mixin avatar-radius {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: transparent no-repeat;
|
||||||
|
background-position: 50%;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin avatar-size($size: 48px) {
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
background-size: $size $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin search-input {
|
||||||
|
outline: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
font-family: inherit;
|
||||||
|
background: $ui-base-color;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin search-popout {
|
||||||
|
background: $simple-background-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
padding-bottom: 14px;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: $light-text-color;
|
||||||
|
box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: $light-text-color;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-weight: 500;
|
||||||
|
color: $inverted-text-color;
|
||||||
|
}
|
||||||
|
}
|
885
app/javascript/styles/bliss/about.scss
Normal file
885
app/javascript/styles/bliss/about.scss
Normal file
@ -0,0 +1,885 @@
|
|||||||
|
$maximum-width: 1235px;
|
||||||
|
$fluid-breakpoint: $maximum-width + 20px;
|
||||||
|
$column-breakpoint: 700px;
|
||||||
|
$small-breakpoint: 960px;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: $maximum-width;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@media screen and (max-width: $fluid-breakpoint) {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rich-formatting {
|
||||||
|
font-family: $font-sans-serif, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.7;
|
||||||
|
word-wrap: break-word;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
li {
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: .85em;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-style: italic;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 0.85em;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.2em 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
margin-top: 1.275em;
|
||||||
|
margin-bottom: .85em;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
padding-left: 2em;
|
||||||
|
margin-bottom: 0.85em;
|
||||||
|
|
||||||
|
&[type='a'] {
|
||||||
|
list-style-type: lower-alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[type='i'] {
|
||||||
|
list-style-type: lower-roman;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
margin: 1.7em 0;
|
||||||
|
|
||||||
|
&.spacer {
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
break-inside: auto;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
|
||||||
|
thead tr,
|
||||||
|
tbody tr {
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
font-size: 1em;
|
||||||
|
line-height: 1.625;
|
||||||
|
font-weight: 400;
|
||||||
|
text-align: left;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead tr {
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 8px;
|
||||||
|
align-self: start;
|
||||||
|
align-items: start;
|
||||||
|
word-break: break-all;
|
||||||
|
|
||||||
|
&.nowrap {
|
||||||
|
width: 25%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: absolute;
|
||||||
|
left: 8px;
|
||||||
|
right: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.information-board {
|
||||||
|
background: darken($ui-base-color, 4%);
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
.container-alt {
|
||||||
|
position: relative;
|
||||||
|
padding-right: 280px + 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__sections {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__section {
|
||||||
|
flex: 1 0 0;
|
||||||
|
font-family: $font-sans-serif, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 28px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-align: right;
|
||||||
|
padding: 10px 15px;
|
||||||
|
|
||||||
|
span,
|
||||||
|
strong {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
&:last-child {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $column-breakpoint) {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
position: absolute;
|
||||||
|
width: 280px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
padding: 20px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: -40px;
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $darker-text-color;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
a,
|
||||||
|
span {
|
||||||
|
font-weight: 400;
|
||||||
|
color: darken($darker-text-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.owner {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.display_name {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page {
|
||||||
|
p,
|
||||||
|
li {
|
||||||
|
font-family: $font-sans-serif, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 700;
|
||||||
|
background: transparent;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
color: lighten($darker-text-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 26px;
|
||||||
|
line-height: 30px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-family: $font-sans-serif, sans-serif;
|
||||||
|
display: block;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: lighten($darker-text-color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 26px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-left: 20px;
|
||||||
|
|
||||||
|
&[type='a'] {
|
||||||
|
list-style-type: lower-alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[type='i'] {
|
||||||
|
list-style-type: lower-roman;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > ol,
|
||||||
|
li > ul {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
&.spacer {
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__information,
|
||||||
|
&__forms {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__call-to-action {
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 25px 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.row {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row__information-board {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
.information-board__section {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row__mascot {
|
||||||
|
flex: 1;
|
||||||
|
margin: 10px -50px 0 0;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__logo {
|
||||||
|
margin-right: 20px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 50px;
|
||||||
|
width: auto;
|
||||||
|
mix-blend-mode: lighten;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__information {
|
||||||
|
padding: 45px 40px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 500;
|
||||||
|
color: lighten($darker-text-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
border-bottom: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&__display-name {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.account__display-name {
|
||||||
|
&:hover {
|
||||||
|
.display-name strong {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__avatar {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__avatar-wrapper {
|
||||||
|
margin-left: 0;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-name {
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
&__account {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $small-breakpoint) {
|
||||||
|
.contact {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $column-breakpoint) {
|
||||||
|
padding: 25px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__information,
|
||||||
|
&__forms,
|
||||||
|
#mastodon-timeline {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 0 6px rgba($black, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__mascot {
|
||||||
|
height: 104px;
|
||||||
|
position: relative;
|
||||||
|
left: -40px;
|
||||||
|
bottom: 25px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 190px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__short-description {
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $column-breakpoint) {
|
||||||
|
.row {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p a {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 500;
|
||||||
|
color: $primary-text-color;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__hero {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 840px) {
|
||||||
|
.information-board {
|
||||||
|
.container-alt {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
position: static;
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 675px) {
|
||||||
|
.header-wrapper {
|
||||||
|
padding-top: 0;
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.compact .hero .heading {
|
||||||
|
text-align: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .container-alt,
|
||||||
|
.features .container-alt {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing {
|
||||||
|
margin-bottom: 100px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 738px) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__brand {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 50px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: $primary-text-color;
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory {
|
||||||
|
margin-top: 30px;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-widget {
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
padding: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
border-radius: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
background: $ui-base-color;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&__column {
|
||||||
|
flex: 1 1 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
.account__display-name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__counters__wrapper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__counter {
|
||||||
|
padding: 10px;
|
||||||
|
width: 50%;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .user_agreement .label_input > label {
|
||||||
|
font-weight: 400;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form p.lead {
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__grid {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 50%) minmax(0, 50%);
|
||||||
|
grid-gap: 30px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 738px) {
|
||||||
|
grid-template-columns: minmax(0, 100%);
|
||||||
|
grid-gap: 10px;
|
||||||
|
|
||||||
|
&__column-login {
|
||||||
|
grid-row: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.box-widget {
|
||||||
|
order: 2;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-widget {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
order: 1;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__column-registration {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
grid-gap: 0;
|
||||||
|
|
||||||
|
.hero-widget {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&__img,
|
||||||
|
&__img img,
|
||||||
|
&__footer {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-widget,
|
||||||
|
.box-widget,
|
||||||
|
.directory__tag {
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory {
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
|
&__tag {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
& > a,
|
||||||
|
& > div {
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand__tagline {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -10px;
|
||||||
|
left: 50px;
|
||||||
|
width: 300px;
|
||||||
|
color: $ui-primary-color;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
position: static;
|
||||||
|
width: auto;
|
||||||
|
margin-top: 20px;
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
13
app/javascript/styles/bliss/accessibility.scss
Normal file
13
app/javascript/styles/bliss/accessibility.scss
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange' 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on' 'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default;
|
||||||
|
|
||||||
|
%emoji-color-inversion {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emojione {
|
||||||
|
@each $emoji in $emojis-requiring-inversion {
|
||||||
|
&[title=':#{$emoji}:'] {
|
||||||
|
@extend %emoji-color-inversion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
328
app/javascript/styles/bliss/accounts.scss
Normal file
328
app/javascript/styles/bliss/accounts.scss
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
@import 'variables';
|
||||||
|
.card {
|
||||||
|
& > a {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
.card__bar {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
height: 130px;
|
||||||
|
position: relative;
|
||||||
|
background: darken($ui-base-color, 12%);
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bar {
|
||||||
|
position: relative;
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
padding-top: 2px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-name {
|
||||||
|
margin-left: 15px;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
i[data-hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-size: 15px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 400;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
padding: 30px 0;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
a,
|
||||||
|
.current,
|
||||||
|
.newer,
|
||||||
|
.older,
|
||||||
|
.page,
|
||||||
|
.gap {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current {
|
||||||
|
background: $simple-background-color;
|
||||||
|
border-radius: 100px;
|
||||||
|
color: $inverted-text-color;
|
||||||
|
cursor: default;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gap {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.older,
|
||||||
|
.newer {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.older {
|
||||||
|
float: left;
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.newer {
|
||||||
|
float: right;
|
||||||
|
padding-right: 0;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
cursor: default;
|
||||||
|
color: lighten($inverted-text-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px) {
|
||||||
|
padding: 30px 20px;
|
||||||
|
|
||||||
|
.page {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newer,
|
||||||
|
.older {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nothing-here {
|
||||||
|
background: $ui-base-color;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
color: $light-text-color;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: default;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 30vh;
|
||||||
|
|
||||||
|
&--under-tabs {
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--flexible {
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-role,
|
||||||
|
.simple_form .recommended {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 6px;
|
||||||
|
cursor: default;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $ui-secondary-color;
|
||||||
|
background-color: rgba($ui-secondary-color, 0.1);
|
||||||
|
border: 1px solid rgba($ui-secondary-color, 0.5);
|
||||||
|
|
||||||
|
&.moderator {
|
||||||
|
color: $success-green;
|
||||||
|
background-color: rgba($success-green, 0.1);
|
||||||
|
border-color: rgba($success-green, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.admin {
|
||||||
|
color: lighten($error-red, 12%);
|
||||||
|
background-color: rgba(lighten($error-red, 12%), 0.1);
|
||||||
|
border-color: rgba(lighten($error-red, 12%), 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__fields {
|
||||||
|
max-width: 100vw;
|
||||||
|
padding: 0;
|
||||||
|
margin: 15px -15px -15px;
|
||||||
|
border: 0 none;
|
||||||
|
border-top: 1px solid lighten($ui-base-color, 12%);
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 12%);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
|
||||||
|
dl {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
dt,
|
||||||
|
dd {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 14px;
|
||||||
|
text-align: center;
|
||||||
|
max-height: 48px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: 500;
|
||||||
|
width: 120px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
background: rgba(darken($ui-base-color, 8%), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.verified {
|
||||||
|
border: 1px solid rgba($valid-value-color, 0.5);
|
||||||
|
background: rgba($valid-value-color, 0.25);
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $valid-value-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__mark {
|
||||||
|
color: $valid-value-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dl:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__tag .trends__item__current {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pending-account {
|
||||||
|
&__header {
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $ui-secondary-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
918
app/javascript/styles/bliss/admin.scss
Normal file
918
app/javascript/styles/bliss/admin.scss
Normal file
@ -0,0 +1,918 @@
|
|||||||
|
$no-columns-breakpoint: 600px;
|
||||||
|
$sidebar-width: 240px;
|
||||||
|
$content-width: 840px;
|
||||||
|
|
||||||
|
.admin-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
background: $ui-base-color;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: $sidebar-width;
|
||||||
|
padding: 0;
|
||||||
|
pointer-events: auto;
|
||||||
|
|
||||||
|
&__toggle {
|
||||||
|
display: none;
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
height: 48px;
|
||||||
|
|
||||||
|
&__logo {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: $primary-text-color;
|
||||||
|
height: 20px;
|
||||||
|
position: relative;
|
||||||
|
bottom: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
display: block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
background: lighten($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: block;
|
||||||
|
margin: 40px auto;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
& > a:first-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
padding: 15px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
transition-property: color, background-color;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
i.fa {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $primary-text-color;
|
||||||
|
background-color: darken($ui-base-color, 5%);
|
||||||
|
transition: all 100ms linear;
|
||||||
|
transition-property: color, background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background: darken($ui-base-color, 2%);
|
||||||
|
border-radius: 4px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
background: darken($ui-base-color, 4%);
|
||||||
|
border-radius: 0 0 0 4px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border: 0;
|
||||||
|
padding: 15px 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple-navigation-active-leaf a {
|
||||||
|
color: $primary-text-color;
|
||||||
|
background-color: $ui-highlight-color;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($ui-highlight-color, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > ul > .simple-navigation-active-leaf a {
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
max-width: $content-width;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $content-width + $sidebar-width) {
|
||||||
|
.sidebar-wrapper--empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
width: $sidebar-width;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
.sidebar-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 55px 15px 20px 25px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
max-width: none;
|
||||||
|
padding: 15px;
|
||||||
|
padding-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-heading {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
padding-bottom: 36px;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
|
||||||
|
margin: -15px -15px 40px 0;
|
||||||
|
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-actions {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
& > :not(:first-child) {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
border-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 36px;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 28px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $darker-text-color;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
line-height: 28px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-group h6 {
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__tag > a,
|
||||||
|
.directory__tag > div {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__tag .table-action-link .fa {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__tag h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-transform: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > p {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 21px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
&.spacer {
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
&__toggle {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > ul {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul a,
|
||||||
|
ul ul a {
|
||||||
|
border-radius: 0;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
transition: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul ul {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul .simple-navigation-active-leaf a {
|
||||||
|
border-bottom-color: $ui-highlight-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr.spacer {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
margin: 20px 0;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
.admin-wrapper .content {
|
||||||
|
.muted-hint {
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.positive-hint {
|
||||||
|
color: $valid-value-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.negative-hint {
|
||||||
|
color: $error-value-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neutral-hint {
|
||||||
|
color: $dark-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-hint {
|
||||||
|
color: $gold-star;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.filter-subset {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin: 0 40px 20px 0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin-top: 5px;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--with-select strong {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 2px solid $ui-base-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $primary-text-color;
|
||||||
|
border-bottom: 2px solid lighten($ui-base-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
border-bottom: 2px solid $ui-highlight-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-accounts {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-accounts__item {
|
||||||
|
display: flex;
|
||||||
|
flex: 250px;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0 5px;
|
||||||
|
|
||||||
|
& > strong {
|
||||||
|
display: block;
|
||||||
|
margin: 0 0 10px -5px;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-card {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-status,
|
||||||
|
.account-status {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.activity-stream {
|
||||||
|
flex: 2 0 0;
|
||||||
|
margin-right: 20px;
|
||||||
|
max-width: calc(100% - 60px);
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-status__actions,
|
||||||
|
.account-status__actions {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
font-size: 24px;
|
||||||
|
width: 24px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form.new_report_note,
|
||||||
|
.simple_form.new_account_moderation_note {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form {
|
||||||
|
.actions {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-form-box {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
#form_status_batch_action {
|
||||||
|
margin: 0 5px 5px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.button {
|
||||||
|
margin: 0 5px 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-spoiler-toggle-buttons {
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
overflow: visible;
|
||||||
|
margin: 0 0 5px 5px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.special-action-button,
|
||||||
|
.back-link {
|
||||||
|
text-align: right;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry {
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 15px 0;
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__avatar {
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
max-width: calc(100% - 90px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__timestamp {
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
.username,
|
||||||
|
.target {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.name-tag,
|
||||||
|
.name-tag,
|
||||||
|
a.inline-name-tag,
|
||||||
|
.inline-name-tag {
|
||||||
|
text-decoration: none;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.suspended {
|
||||||
|
.username {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: lighten($error-red, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.name-tag,
|
||||||
|
.name-tag {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.suspended {
|
||||||
|
.avatar {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.speech-bubble {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-left: 4px solid $ui-highlight-color;
|
||||||
|
|
||||||
|
&.positive {
|
||||||
|
border-left-color: $success-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.negative {
|
||||||
|
border-left-color: lighten($error-red, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
border-left-color: $gold-star;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bubble {
|
||||||
|
padding: 16px;
|
||||||
|
padding-left: 14px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
border-radius: 4px 4px 4px 0;
|
||||||
|
position: relative;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__owner {
|
||||||
|
padding: 8px;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
time {
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-card {
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&__profile {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
.account {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
&__avatar-wrapper {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__stats {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
color: lighten($darker-text-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: $error-value-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__summary {
|
||||||
|
&__item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border-top: 1px solid darken($ui-base-color, 4%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: lighten($ui-base-color, 2%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__reported-by,
|
||||||
|
&__assigned {
|
||||||
|
padding: 15px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 150px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
&,
|
||||||
|
.username {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
max-width: calc(100% - 300px);
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
color: $dark-text-color;
|
||||||
|
margin-right: 4px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content a {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.one-line {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ellipsized-ip {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 120px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-account-bio {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0 -5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
flex: 1 0 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__fields,
|
||||||
|
.account__header__content {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__fields {
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: lighten($ui-highlight-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
dl:first-child .verified {
|
||||||
|
border-radius: 0 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verified a {
|
||||||
|
color: $valid-value-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-text {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.announcements-list {
|
||||||
|
border: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
padding: 15px 0;
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
padding: 0 15px;
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__meta {
|
||||||
|
padding: 0 15px;
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__action-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-badges {
|
||||||
|
margin: -2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard__counters.admin-account-counters {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
272
app/javascript/styles/bliss/basics.scss
Normal file
272
app/javascript/styles/bliss/basics.scss
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
@function hex-color($color) {
|
||||||
|
@if type-of($color) == 'color' {
|
||||||
|
$color: str-slice(ie-hex-str($color), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@return '%23' + unquote($color);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: $font-sans-serif, sans-serif;
|
||||||
|
background: darken($ui-base-color, 7%);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-rendering: optimizelegibility;
|
||||||
|
font-feature-settings: "kern";
|
||||||
|
text-size-adjust: none;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
|
||||||
|
&.system-font {
|
||||||
|
// system-ui => standard property (Chrome/Android WebView 56+, Opera 43+, Safari 11+)
|
||||||
|
// -apple-system => Safari <11 specific
|
||||||
|
// BlinkMacSystemFont => Chrome <56 on macOS specific
|
||||||
|
// Segoe UI => Windows 7/8/10
|
||||||
|
// Oxygen => KDE
|
||||||
|
// Ubuntu => Unity/Ubuntu
|
||||||
|
// Cantarell => GNOME
|
||||||
|
// Fira Sans => Firefox OS
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.app-body {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&.layout-single-column {
|
||||||
|
height: auto;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.layout-multiple-columns {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.with-modals--active {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.lighter {
|
||||||
|
background: $ui-base-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.with-modals {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.player {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-player video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-gallery {
|
||||||
|
margin-top: 0;
|
||||||
|
height: 100% !important;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-gallery__item {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.embed {
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
margin: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.admin {
|
||||||
|
background: darken($ui-base-color, 4%);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
color: $darker-text-color;
|
||||||
|
background: $ui-base-color;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 20px;
|
||||||
|
|
||||||
|
&__illustration {
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
max-width: 470px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
margin-top: -120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 28px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-family: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-holder {
|
||||||
|
&,
|
||||||
|
& > div,
|
||||||
|
& > noscript {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > noscript {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-single-column .app-holder {
|
||||||
|
&,
|
||||||
|
& > div {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-multiple-columns .app-holder {
|
||||||
|
&,
|
||||||
|
& > div {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-boundary,
|
||||||
|
.app-holder noscript {
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.7;
|
||||||
|
color: lighten($error-red, 4%);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: .85em;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
color: $dark-text-color;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: inline;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: $dark-text-color;
|
||||||
|
font: inherit;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
line-height: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: 0;
|
||||||
|
transition: color 300ms linear;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.copied {
|
||||||
|
color: $valid-value-color;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-resources {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoScript adds a __ns__pop2top class to the full ancestry of blocked elements,
|
||||||
|
// to set the z-index to a high value, which messes with modals and dropdowns.
|
||||||
|
// Blocked elements can in theory only be media and frames/embeds, so they
|
||||||
|
// should only appear in statuses, under divs and articles.
|
||||||
|
body,
|
||||||
|
div,
|
||||||
|
article {
|
||||||
|
.__ns__pop2top {
|
||||||
|
z-index: unset !important;
|
||||||
|
}
|
||||||
|
}
|
22
app/javascript/styles/bliss/boost.scss
Normal file
22
app/javascript/styles/bliss/boost.scss
Normal file
File diff suppressed because one or more lines are too long
34
app/javascript/styles/bliss/compact_header.scss
Normal file
34
app/javascript/styles/bliss/compact_header.scss
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.compact-header {
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 28px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 0 10px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
@media screen and (max-width: 740px) {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-weight: 400;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: -5px;
|
||||||
|
margin-right: 15px;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7058
app/javascript/styles/bliss/components.scss
Normal file
7058
app/javascript/styles/bliss/components.scss
Normal file
File diff suppressed because it is too large
Load Diff
899
app/javascript/styles/bliss/containers.scss
Normal file
899
app/javascript/styles/bliss/containers.scss
Normal file
@ -0,0 +1,899 @@
|
|||||||
|
.container-alt {
|
||||||
|
width: 700px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 40px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 740px) {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container {
|
||||||
|
margin: 100px auto 50px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 500px) {
|
||||||
|
margin: 40px auto 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
fill: $primary-text-color;
|
||||||
|
height: 42px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: 0;
|
||||||
|
padding: 12px 16px;
|
||||||
|
line-height: 32px;
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.compose-standalone {
|
||||||
|
.compose-form {
|
||||||
|
width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px 0;
|
||||||
|
margin-top: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
@media screen and (max-width: 400px) {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-header {
|
||||||
|
width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin-bottom: -30px;
|
||||||
|
margin-top: 40px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 440px) {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-right: 8px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
width: calc(100% - 88px);
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-link {
|
||||||
|
display: block;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 40px;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-3 {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: 3fr 1fr;
|
||||||
|
grid-auto-columns: 25%;
|
||||||
|
grid-auto-rows: max-content;
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-column: 1 / 3;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3 {
|
||||||
|
grid-column: 1 / 3;
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
grid-gap: 0;
|
||||||
|
grid-template-columns: minmax(0, 100%);
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-4 {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
grid-auto-columns: 25%;
|
||||||
|
grid-auto-rows: max-content;
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-column: 1 / 5;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 4;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3 {
|
||||||
|
grid-column: 2 / 5;
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-4 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page__call-to-action {
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flash-message {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 738px) {
|
||||||
|
grid-template-columns: minmax(0, 50%) minmax(0, 50%);
|
||||||
|
|
||||||
|
.landing-page__call-to-action {
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row__information-board {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row__mascot {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
grid-gap: 0;
|
||||||
|
grid-template-columns: minmax(0, 100%);
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-4 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-layout {
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
padding-top: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 960px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 48px;
|
||||||
|
margin: 10px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
z-index: 110;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
flex: 1 1 33.3%;
|
||||||
|
min-height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-end;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
display: block;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
height: 18px;
|
||||||
|
width: auto;
|
||||||
|
position: relative;
|
||||||
|
bottom: -2px;
|
||||||
|
fill: $primary-text-color;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
background: lighten($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 1rem;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $darker-text-color;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 550px) {
|
||||||
|
&.optional {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-button {
|
||||||
|
background: lighten($ui-base-color, 16%);
|
||||||
|
margin: 8px;
|
||||||
|
margin-left: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
background: lighten($ui-base-color, 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$no-columns-breakpoint: 600px;
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: minmax(300px, 3fr) minmax(298px, 1fr);
|
||||||
|
grid-auto-columns: 25%;
|
||||||
|
grid-auto-rows: max-content;
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
grid-gap: 0;
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__card {
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-account-header {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
|
||||||
|
&.inactive {
|
||||||
|
opacity: 0.5;
|
||||||
|
|
||||||
|
.public-account-header__image,
|
||||||
|
.avatar {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-button {
|
||||||
|
background-color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 300px;
|
||||||
|
position: relative;
|
||||||
|
background: darken($ui-base-color, 12%);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-shadow: inset 0 -1px 1px 1px rgba($base-shadow-color, 0.15);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--no-bar {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
.public-account-header__image,
|
||||||
|
.public-account-header__image img {
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&__image::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image,
|
||||||
|
&__image img {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bar {
|
||||||
|
position: relative;
|
||||||
|
margin-top: -80px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
display: block;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
padding-left: 20px - 4px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid lighten($ui-base-color, 4%);
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
margin-top: 0;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
padding: 7px 0;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 360px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__tabs {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
margin-left: 20px;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 18px * 1.5;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-shadow: 1px 1px 1px $base-shadow-color;
|
||||||
|
|
||||||
|
small {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 400;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
margin-left: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
text-shadow: none;
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__tabs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
height: 58px;
|
||||||
|
|
||||||
|
.details-counters {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
.details-counters {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter {
|
||||||
|
min-width: 33.3%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: $darker-text-color;
|
||||||
|
padding: 10px;
|
||||||
|
border-right: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
cursor: default;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 4px solid $ui-primary-color;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: all 400ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
&::after {
|
||||||
|
border-bottom: 4px solid $highlight-text-color;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.inactive::after {
|
||||||
|
border-bottom-color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&::after {
|
||||||
|
opacity: 1;
|
||||||
|
transition-duration: 100ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-label {
|
||||||
|
font-size: 12px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-number {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__buttons {
|
||||||
|
padding: 7px 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__extra {
|
||||||
|
display: none;
|
||||||
|
margin-top: 4px;
|
||||||
|
|
||||||
|
.public-account-bio {
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
background: transparent;
|
||||||
|
margin: 0 -5px;
|
||||||
|
|
||||||
|
.account__header__fields {
|
||||||
|
border-top: 1px solid lighten($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roles {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__links {
|
||||||
|
margin-top: -15px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
display: block;
|
||||||
|
flex: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__section-headline {
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__meta {
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-account-bio {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
box-shadow: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__fields {
|
||||||
|
margin: 0;
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: lighten($ui-highlight-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
dl:first-child .verified {
|
||||||
|
border-radius: 0 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verified a {
|
||||||
|
color: $valid-value-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__content {
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__extra,
|
||||||
|
.roles {
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roles {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__list {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: minmax(0, 50%) minmax(0, 50%);
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__card {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
min-width: 100%;
|
||||||
|
margin: 0 -5px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1 0 auto;
|
||||||
|
width: 300px;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
max-width: 33.333%;
|
||||||
|
|
||||||
|
@media screen and (max-width: 900px) {
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin: 0;
|
||||||
|
border-top: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__bar {
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
app/javascript/styles/bliss/dashboard.scss
Normal file
101
app/javascript/styles/bliss/dashboard.scss
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
@import 'variables';
|
||||||
|
.dashboard__counters {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0 -5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 0 0 33.333%;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
& > div,
|
||||||
|
& > a {
|
||||||
|
padding: 20px;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__num,
|
||||||
|
&__text {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 21px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-family: $font-display, sans-serif;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard__widgets {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0 -5px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
flex: 0 0 33.333%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not(.name-tag) {
|
||||||
|
color: $ui-secondary-color;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// custom bliss
|
||||||
|
.navigation-panel{
|
||||||
|
.column-link{
|
||||||
|
span{
|
||||||
|
opacity: 0 ;
|
||||||
|
|
||||||
|
}
|
||||||
|
&:hover span{
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity ease 0.1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.timelines{
|
||||||
|
a{
|
||||||
|
display: inline-block;
|
||||||
|
width : 20%;
|
||||||
|
}
|
||||||
|
span{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
204
app/javascript/styles/bliss/emoji_picker.scss
Normal file
204
app/javascript/styles/bliss/emoji_picker.scss
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
.emoji-mart {
|
||||||
|
font-size: 13px;
|
||||||
|
display: inline-block;
|
||||||
|
color: $inverted-text-color;
|
||||||
|
|
||||||
|
&,
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-emoji {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-bar {
|
||||||
|
border: 0 solid darken($ui-secondary-color, 8%);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
background: $ui-secondary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 6px;
|
||||||
|
color: $lighter-text-color;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 12px 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: color .1s ease-out;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: darken($lighter-text-color, 4%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-selected {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: darken($highlight-text-color, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-bar {
|
||||||
|
bottom: -1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -5px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 4px;
|
||||||
|
background-color: $highlight-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors {
|
||||||
|
i {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: currentColor;
|
||||||
|
max-height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 270px;
|
||||||
|
max-height: 35vh;
|
||||||
|
padding: 0 6px 6px;
|
||||||
|
background: $simple-background-color;
|
||||||
|
will-change: transform;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track:hover,
|
||||||
|
&::-webkit-scrollbar-track:active {
|
||||||
|
background-color: rgba($base-overlay-background, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-search {
|
||||||
|
padding: 10px;
|
||||||
|
padding-right: 45px;
|
||||||
|
background: $simple-background-color;
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 7px 9px;
|
||||||
|
font-family: inherit;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
background: rgba($ui-secondary-color, 0.3);
|
||||||
|
color: $inverted-text-color;
|
||||||
|
border: 1px solid $ui-secondary-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-focus-inner,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category .emoji-mart-emoji {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
span {
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::before {
|
||||||
|
z-index: 0;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba($ui-secondary-color, 0.7);
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category-label {
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 5px 6px;
|
||||||
|
background: $simple-background-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-emoji {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-no-results {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 70px;
|
||||||
|
color: $light-text-color;
|
||||||
|
|
||||||
|
.emoji-mart-category-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-no-results-label {
|
||||||
|
margin-top: .2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-emoji:hover::before {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview {
|
||||||
|
display: none;
|
||||||
|
}
|
137
app/javascript/styles/bliss/footer.scss
Normal file
137
app/javascript/styles/bliss/footer.scss
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
.public-layout {
|
||||||
|
.footer {
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: 1fr 1fr 2fr 1fr 1fr;
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 3;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h4 a {
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3 {
|
||||||
|
grid-column: 4;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-4 {
|
||||||
|
grid-column: 5;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 690px) {
|
||||||
|
grid-template-columns: 1fr 2fr 1fr;
|
||||||
|
|
||||||
|
.column-0,
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3,
|
||||||
|
.column-4 {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-4 {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.column-1 {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
.column-0,
|
||||||
|
.column-1,
|
||||||
|
.column-3,
|
||||||
|
.column-4 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
height: 36px;
|
||||||
|
width: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
fill: lighten($ui-base-color, 34%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
svg {
|
||||||
|
fill: lighten($ui-base-color, 38%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
980
app/javascript/styles/bliss/forms.scss
Normal file
980
app/javascript/styles/bliss/forms.scss
Normal file
@ -0,0 +1,980 @@
|
|||||||
|
$no-columns-breakpoint: 600px;
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: $font-monospace, monospace;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
max-width: 400px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form {
|
||||||
|
.input {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.radio_buttons {
|
||||||
|
.radio {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio > label {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 28px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
top: -2px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.boolean {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
.label_input > label {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-top: 5px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label_input,
|
||||||
|
.hint {
|
||||||
|
padding-left: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label_input__wrapper {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.checkbox {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommended {
|
||||||
|
position: absolute;
|
||||||
|
margin: 0 4px;
|
||||||
|
margin-top: -2px;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
margin: 0 -5px;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 50%;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
background: darken($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style: disc;
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.hint {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.hint {
|
||||||
|
display: block;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.hint {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
&.subtle-hint {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-hint {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.with_floating_label {
|
||||||
|
.label_input {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
& > label {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
min-width: 150px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
select {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.select .hint {
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-left: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.with_label {
|
||||||
|
.label_input > label {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
flex: 390px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.with_block_label {
|
||||||
|
max-width: none;
|
||||||
|
|
||||||
|
& > label {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 16px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
columns: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.datetime .label_input select {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.required abbr {
|
||||||
|
text-decoration: none;
|
||||||
|
color: lighten($error-value-color, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-group {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
|
||||||
|
.input:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-row {
|
||||||
|
display: flex;
|
||||||
|
margin: 0 -10px;
|
||||||
|
padding-top: 5px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__column {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 10px;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 1px;
|
||||||
|
|
||||||
|
&-6 {
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
margin-top: 27px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-group:last-child,
|
||||||
|
.fields-row__column.fields-group {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
&__column {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-group:last-child,
|
||||||
|
.fields-row__column.fields-group,
|
||||||
|
.fields-row__column {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-group.invited-by {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.radio_buttons .radio label {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check_boxes {
|
||||||
|
.checkbox {
|
||||||
|
label {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
position: relative;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-left: 25px;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 5px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.static .label_input__wrapper {
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid $dark-text-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text],
|
||||||
|
input[type=number],
|
||||||
|
input[type=email],
|
||||||
|
input[type=password],
|
||||||
|
textarea {
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 16px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
outline: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
resize: vertical;
|
||||||
|
background: darken($ui-base-color, 10%);
|
||||||
|
border: 1px solid darken($ui-base-color, 14%);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: lighten($darker-text-color, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:invalid {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus:invalid:not(:placeholder-shown) {
|
||||||
|
border-color: lighten($error-red, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:required:valid {
|
||||||
|
border-color: $valid-value-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: darken($ui-base-color, 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
border-color: $highlight-text-color;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.field_with_errors {
|
||||||
|
label {
|
||||||
|
color: lighten($error-red, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text],
|
||||||
|
input[type=number],
|
||||||
|
input[type=email],
|
||||||
|
input[type=password],
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
border-color: lighten($error-red, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
color: lighten($error-red, 12%);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input.disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
margin-top: 30px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&.actions--top {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
.button,
|
||||||
|
.block-button {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: $ui-highlight-color;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: inherit;
|
||||||
|
height: auto;
|
||||||
|
padding: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
outline: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($ui-highlight-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: darken($ui-highlight-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled:hover {
|
||||||
|
background-color: $ui-primary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.negative {
|
||||||
|
background: $error-value-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($error-value-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: darken($error-value-color, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
appearance: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 16px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
outline: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
resize: vertical;
|
||||||
|
background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(lighten($ui-base-color, 12%))}'/></svg>") no-repeat right 8px center / auto 16px;
|
||||||
|
border: 1px solid darken($ui-base-color, 14%);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 30px;
|
||||||
|
height: 41px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-bottom: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label_input {
|
||||||
|
&__wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__append {
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
top: 1px;
|
||||||
|
padding: 10px;
|
||||||
|
padding-bottom: 9px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: $dark-text-color;
|
||||||
|
font-family: inherit;
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: default;
|
||||||
|
max-width: 140px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 1px;
|
||||||
|
width: 5px;
|
||||||
|
background-image: linear-gradient(to right, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__overlay-area {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__blurred form {
|
||||||
|
filter: blur(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba($ui-base-color, 0.65);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-left: -4px;
|
||||||
|
margin-top: -4px;
|
||||||
|
padding: 4px;
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.rich-formatting {
|
||||||
|
&,
|
||||||
|
p {
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-icon {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flash-message {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
color: $darker-text-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 15px 10px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.notice {
|
||||||
|
border: 1px solid rgba($valid-value-color, 0.5);
|
||||||
|
background: rgba($valid-value-color, 0.25);
|
||||||
|
color: $valid-value-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.alert {
|
||||||
|
border: 1px solid rgba($error-value-color, 0.5);
|
||||||
|
background: rgba($error-value-color, 0.1);
|
||||||
|
color: $error-value-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-code {
|
||||||
|
outline: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
padding: 10px;
|
||||||
|
font-family: $font-monospace, monospace;
|
||||||
|
background: $ui-base-color;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-focus-inner,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 740px) and (min-width: 441px) {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.translation-prompt {
|
||||||
|
text-align: unset;
|
||||||
|
color: unset;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-footer {
|
||||||
|
margin-top: 30px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-nav {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
color: lighten($highlight-text-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-prompt,
|
||||||
|
.follow-prompt {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 740px) and (min-width: 441px) {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.qr-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qr-code {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
background: $simple-background-color;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 0 10px 20px 0;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.qr-alternative {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
flex: 150px;
|
||||||
|
|
||||||
|
samp {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-form {
|
||||||
|
p {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form,
|
||||||
|
.table-form {
|
||||||
|
.warning {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: rgba($error-value-color, 0.5);
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-shadow: 1px 1px 0 rgba($base-shadow-color, 0.3);
|
||||||
|
box-shadow: 0 2px 6px rgba($base-shadow-color, 0.4);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 600;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-pagination {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.actions,
|
||||||
|
.pagination {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
padding: 30px 0;
|
||||||
|
padding-right: 20px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-follow-actions {
|
||||||
|
text-align: center;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
div {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alternative-login {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scope-danger {
|
||||||
|
color: $warning-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form_admin_settings_site_short_description,
|
||||||
|
.form_admin_settings_site_description,
|
||||||
|
.form_admin_settings_site_extended_description,
|
||||||
|
.form_admin_settings_site_terms,
|
||||||
|
.form_admin_settings_custom_css,
|
||||||
|
.form_admin_settings_closed_registrations_message {
|
||||||
|
textarea {
|
||||||
|
font-family: $font-monospace, monospace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-copy {
|
||||||
|
background: darken($ui-base-color, 10%);
|
||||||
|
border: 1px solid darken($ui-base-color, 14%);
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-right: 4px;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
transition: border-color 300ms linear;
|
||||||
|
|
||||||
|
&__wrapper {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: $font-monospace, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin: 4px;
|
||||||
|
text-transform: none;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 7px 18px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
width: auto;
|
||||||
|
transition: background 300ms linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.copied {
|
||||||
|
border-color: $valid-value-color;
|
||||||
|
transition: none;
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: $valid-value-color;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-prompt {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
|
||||||
|
.fa-link {
|
||||||
|
background-color: darken($ui-base-color, 4%);
|
||||||
|
border-radius: 100%;
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__column {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-shrink: 1;
|
||||||
|
max-width: 50%;
|
||||||
|
|
||||||
|
&-sep {
|
||||||
|
align-self: center;
|
||||||
|
flex-grow: 0;
|
||||||
|
overflow: visible;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__avatar {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__connection {
|
||||||
|
background-color: lighten($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 25px 10px;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background-color: darken($ui-base-color, 4%);
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
align-items: flex-start;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
}
|
154
app/javascript/styles/bliss/introduction.scss
Normal file
154
app/javascript/styles/bliss/introduction.scss
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
.introduction {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
@media screen and (max-width: 920px) {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__pager {
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__pager,
|
||||||
|
&__frame {
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 50vw;
|
||||||
|
min-width: 920px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 920px) {
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__frame-wrapper {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 500ms linear;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 50ms linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__frame {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__illustration {
|
||||||
|
height: 50vh;
|
||||||
|
|
||||||
|
@media screen and (max-width: 630px) {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
border-top: 2px solid $ui-highlight-color;
|
||||||
|
|
||||||
|
&--columnized {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
flex: 1 1 33.33%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 25px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 630px) {
|
||||||
|
display: block;
|
||||||
|
padding: 15px 0;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
padding: 10px 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
code {
|
||||||
|
display: inline-block;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 1px 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--centered {
|
||||||
|
padding: 25px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dots {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 25px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 630px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dot {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid $ui-highlight-color;
|
||||||
|
background: transparent;
|
||||||
|
margin: 0 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
cursor: default;
|
||||||
|
background: $ui-highlight-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__action {
|
||||||
|
padding: 25px;
|
||||||
|
padding-top: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
19
app/javascript/styles/bliss/lists.scss
Normal file
19
app/javascript/styles/bliss/lists.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.no-list {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.recovery-codes {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-size: 125%;
|
||||||
|
line-height: 1.5;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
}
|
0
app/javascript/styles/bliss/messaging.scss
Normal file
0
app/javascript/styles/bliss/messaging.scss
Normal file
26
app/javascript/styles/bliss/modal.scss
Normal file
26
app/javascript/styles/bliss/modal.scss
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.modal-layout {
|
||||||
|
background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-lighter-color)}"/></svg>') repeat-x bottom fixed;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-layout__mastodon {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
flex: 1;
|
||||||
|
max-height: 235px;
|
||||||
|
background: url('../images/elephant_ui_plane.svg') no-repeat left bottom / contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.account-header {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
274
app/javascript/styles/bliss/polls.scss
Normal file
274
app/javascript/styles/bliss/polls.scss
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
.poll {
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__chart {
|
||||||
|
border-radius: 4px;
|
||||||
|
display: block;
|
||||||
|
background: darken($ui-primary-color, 5%);
|
||||||
|
height: 5px;
|
||||||
|
min-width: 1%;
|
||||||
|
|
||||||
|
&.leading {
|
||||||
|
background: $ui-highlight-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
border: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&::-webkit-progress-bar {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Those rules need to be entirely separate or they won't work, hence the
|
||||||
|
// duplication
|
||||||
|
&::-moz-progress-bar {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: darken($ui-primary-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-fill {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: darken($ui-primary-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-progress-value {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: darken($ui-primary-color, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__option {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 0;
|
||||||
|
line-height: 18px;
|
||||||
|
cursor: default;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
display: inline-block;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
max-width: calc(100% - 45px - 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=radio],
|
||||||
|
input[type=checkbox] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autossugest-input {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $inverted-text-color;
|
||||||
|
outline: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
background: $simple-background-color;
|
||||||
|
border: 1px solid darken($simple-background-color, 14%);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: $highlight-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selectable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.editable {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid $ui-primary-color;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-right: 10px;
|
||||||
|
top: -1px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: auto;
|
||||||
|
flex: 0 0 18px;
|
||||||
|
|
||||||
|
&.checkbox {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: $valid-value-color;
|
||||||
|
background: $valid-value-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
border-color: lighten($valid-value-color, 15%);
|
||||||
|
border-width: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-focus-inner {
|
||||||
|
outline: 0 !important;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__number {
|
||||||
|
display: inline-block;
|
||||||
|
width: 45px;
|
||||||
|
font-weight: 700;
|
||||||
|
flex: 0 0 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__voted {
|
||||||
|
padding: 0 5px;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&__mark {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
color: $dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
display: inline;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
color: $dark-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-size: inherit;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: rgba($dark-text-color, .1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 16px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.compose-form__poll-wrapper {
|
||||||
|
border-top: 1px solid darken($simple-background-color, 8%);
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.poll__footer {
|
||||||
|
border-top: 1px solid darken($simple-background-color, 8%);
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
flex: 1 1 50%;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: $highlight-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.button-secondary {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 6px 10px;
|
||||||
|
height: auto;
|
||||||
|
line-height: inherit;
|
||||||
|
color: $action-button-color;
|
||||||
|
border-color: $action-button-color;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.poll__option {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: calc(100% - (23px + 6px));
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
appearance: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $inverted-text-color;
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
outline: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
background: $simple-background-color url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(darken($simple-background-color, 14%))}'/></svg>") no-repeat right 8px center / auto 16px;
|
||||||
|
border: 1px solid darken($simple-background-color, 14%);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button.disabled {
|
||||||
|
color: darken($simple-background-color, 14%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted .poll {
|
||||||
|
color: $dark-text-color;
|
||||||
|
|
||||||
|
&__chart {
|
||||||
|
background: rgba(darken($ui-primary-color, 14%), 0.2);
|
||||||
|
|
||||||
|
&.leading {
|
||||||
|
background: rgba($ui-highlight-color, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
95
app/javascript/styles/bliss/reset.scss
Normal file
95
app/javascript/styles/bliss/reset.scss
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
v2.0 | 20110126
|
||||||
|
License: none (public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||||
|
article, aside, canvas, details, embed,
|
||||||
|
figure, figcaption, footer, header, hgroup,
|
||||||
|
menu, nav, output, ruby, section, summary,
|
||||||
|
time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article, aside, details, figcaption, figure,
|
||||||
|
footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scrollbar-color: lighten($ui-base-color, 4%) rgba($base-overlay-background, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
border: 0px none $base-border-color;
|
||||||
|
border-radius: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: lighten($ui-base-color, 6%);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:active {
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
border: 0px none $base-border-color;
|
||||||
|
border-radius: 0;
|
||||||
|
background: rgba($base-overlay-background, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track:hover {
|
||||||
|
background: $ui-base-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track:active {
|
||||||
|
background: $ui-base-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
|
background: transparent;
|
||||||
|
}
|
419
app/javascript/styles/bliss/rtl.scss
Normal file
419
app/javascript/styles/bliss/rtl.scss
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
body.rtl {
|
||||||
|
direction: rtl;
|
||||||
|
|
||||||
|
.column-header > button {
|
||||||
|
text-align: right;
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-button__input {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__card__bar .display-name {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-name {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification__message {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 68px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer__inner__mastodon > img {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification__favourite-icon-wrapper {
|
||||||
|
left: auto;
|
||||||
|
right: -26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page__logo {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .features-list .features-list__row .visual {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-link__icon,
|
||||||
|
.column-header__icon {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compose-form .compose-form__buttons-wrapper .character-counter__wrapper {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-bar__profile {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search__input {
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search__icon .fa {
|
||||||
|
right: auto;
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-area {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-header__buttons {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: -15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-inline-form .icon-button {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-header__links .text-btn {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__avatar-wrapper {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-header__back-button {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-header__setting-arrows {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-toggle__label {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__avatar {
|
||||||
|
left: auto;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status,
|
||||||
|
.activity-stream .status.light {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 68px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__info .status__display-name,
|
||||||
|
.activity-stream .status.light .status__display-name {
|
||||||
|
padding-left: 25px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-stream .pre-header {
|
||||||
|
padding-right: 68px;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__prepend {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 68px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__prepend-icon-wrapper {
|
||||||
|
left: auto;
|
||||||
|
right: -26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-stream .pre-header .pre-header__icon {
|
||||||
|
left: auto;
|
||||||
|
right: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__avatar-overlay-overlay {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-back-button--slim-button {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__relative-time,
|
||||||
|
.status__visibility-icon,
|
||||||
|
.activity-stream .status.light .status__header .status__meta {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__action-bar {
|
||||||
|
&__counter {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 11px;
|
||||||
|
|
||||||
|
.status__action-bar-button {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__action-bar-button {
|
||||||
|
float: right;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__action-bar-dropdown {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-dropdown__dropdown {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-dropdown__option__icon {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__display-name .display-name {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__display-avatar {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 10px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__favorites,
|
||||||
|
.detailed-status__reblogs {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-ul {
|
||||||
|
margin-left: 2.14285714em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-li {
|
||||||
|
left: auto;
|
||||||
|
right: -2.14285714em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-wrapper {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-wrapper .sidebar ul a i.fa,
|
||||||
|
a.table-action-link i.fa {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .check_boxes .checkbox label {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input.with_label.boolean label.checkbox {
|
||||||
|
padding-left: 25px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .check_boxes .checkbox input[type="checkbox"],
|
||||||
|
.simple_form .input.boolean input[type="checkbox"] {
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input.radio_buttons .radio {
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input.radio_buttons .radio > label {
|
||||||
|
padding-right: 28px;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input-with-append .input input {
|
||||||
|
padding-left: 142px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input.boolean label.checkbox {
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input.boolean .label_input,
|
||||||
|
.simple_form .input.boolean .hint {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .label_input__append {
|
||||||
|
right: auto;
|
||||||
|
left: 3px;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
background-image: linear-gradient(to left, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form select {
|
||||||
|
background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(lighten($ui-base-color, 12%))}'/></svg>") no-repeat left 8px center / auto 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table th,
|
||||||
|
.table td {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters .filter-subset {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .header-wrapper .mascot {
|
||||||
|
right: 60px;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page__call-to-action .row__information-board {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .header .hero .floats .float-1 {
|
||||||
|
left: -120px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .header .hero .floats .float-2 {
|
||||||
|
left: 210px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .header .hero .floats .float-3 {
|
||||||
|
left: 110px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .header .links .brand img {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .fa-external-link {
|
||||||
|
padding-right: 5px;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .features #mastodon-timeline {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 631px) {
|
||||||
|
.column,
|
||||||
|
.drawer {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-area > div {
|
||||||
|
.column,
|
||||||
|
.drawer {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-area--mobile .column,
|
||||||
|
.columns-area--mobile .drawer {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-layout {
|
||||||
|
.header {
|
||||||
|
.nav-button {
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-account-header__tabs {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page__information {
|
||||||
|
.account__display-name {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__avatar-wrapper {
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__bar .display-name {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 15px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-chevron-left::before {
|
||||||
|
content: "\F054";
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-chevron-right::before {
|
||||||
|
content: "\F053";
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-back-button__icon {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-header__setting-arrows .column-header__setting-btn:last-child {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple_form .input.radio_buttons .radio > label input {
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
190
app/javascript/styles/bliss/statuses.scss
Normal file
190
app/javascript/styles/bliss/statuses.scss
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
.activity-stream {
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&--under-tabs {
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--headless {
|
||||||
|
border-radius: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
.detailed-status,
|
||||||
|
.status {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div[data-component] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
.detailed-status,
|
||||||
|
.status,
|
||||||
|
.load-more {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
.detailed-status,
|
||||||
|
.status,
|
||||||
|
.load-more {
|
||||||
|
border-bottom: 0;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
.detailed-status,
|
||||||
|
.status,
|
||||||
|
.load-more {
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
.detailed-status,
|
||||||
|
.status,
|
||||||
|
.load-more {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 740px) {
|
||||||
|
.detailed-status,
|
||||||
|
.status,
|
||||||
|
.load-more {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--highlighted .entry {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.logo-button {
|
||||||
|
flex: 0 auto;
|
||||||
|
font-size: 14px;
|
||||||
|
background: $ui-highlight-color;
|
||||||
|
color: $primary-text-color;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 36px;
|
||||||
|
height: auto;
|
||||||
|
padding: 3px 15px;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 20px;
|
||||||
|
height: auto;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 5px;
|
||||||
|
fill: $primary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
background: lighten($ui-highlight-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled,
|
||||||
|
&.disabled {
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
background: $ui-primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.button--destructive {
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
background: $error-red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
svg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.embed,
|
||||||
|
.public-layout {
|
||||||
|
.status__content[data-spoiler=folded] {
|
||||||
|
.e-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:first-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status {
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
.detailed-status__display-avatar .account__avatar {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
padding: 15px 15px 15px (48px + 15px * 2);
|
||||||
|
min-height: 48px + 2px;
|
||||||
|
|
||||||
|
&__avatar {
|
||||||
|
left: 15px;
|
||||||
|
top: 17px;
|
||||||
|
|
||||||
|
.account__avatar {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__prepend {
|
||||||
|
margin-left: 48px + 15px * 2;
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__prepend-icon-wrapper {
|
||||||
|
left: -32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-gallery,
|
||||||
|
&__action-bar,
|
||||||
|
.video-player {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__action-bar-button {
|
||||||
|
font-size: 18px;
|
||||||
|
width: 23.1429px;
|
||||||
|
height: 23.1429px;
|
||||||
|
line-height: 23.15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
293
app/javascript/styles/bliss/tables.scss
Normal file
293
app/javascript/styles/bliss/tables.scss
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
.table {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 8px;
|
||||||
|
line-height: 18px;
|
||||||
|
vertical-align: top;
|
||||||
|
border-top: 1px solid $ui-base-color;
|
||||||
|
text-align: left;
|
||||||
|
background: darken($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > thead > tr > th {
|
||||||
|
vertical-align: bottom;
|
||||||
|
border-bottom: 2px solid $ui-base-color;
|
||||||
|
border-top: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > tbody > tr > th {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > tbody > tr:nth-child(odd) > td,
|
||||||
|
& > tbody > tr:nth-child(odd) > th {
|
||||||
|
background: $ui-base-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.inline-table {
|
||||||
|
& > tbody > tr:nth-child(odd) {
|
||||||
|
& > td,
|
||||||
|
& > th {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > tbody > tr:first-child {
|
||||||
|
& > td,
|
||||||
|
& > th {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.batch-table {
|
||||||
|
& > thead > tr > th {
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-top: 1px solid darken($ui-base-color, 8%);
|
||||||
|
border-bottom: 1px solid darken($ui-base-color, 8%);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-radius: 4px 0 0;
|
||||||
|
border-left: 1px solid darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-radius: 0 4px 0 0;
|
||||||
|
border-right: 1px solid darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--invites tbody td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
overflow: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
samp {
|
||||||
|
font-family: $font-monospace, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.table-action-link {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.table-action-link,
|
||||||
|
a.table-action-link {
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
padding: 0 10px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.fa {
|
||||||
|
font-weight: 400;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-table {
|
||||||
|
&__toolbar,
|
||||||
|
&__row {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&__select {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--aligned {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__actions,
|
||||||
|
&__content {
|
||||||
|
padding: 8px 0;
|
||||||
|
padding-right: 16px;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__toolbar {
|
||||||
|
border: 1px solid darken($ui-base-color, 8%);
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px 0 0;
|
||||||
|
height: 47px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__actions {
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 16px - 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form {
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid darken($ui-base-color, 8%);
|
||||||
|
border-top: 0;
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
.fields-row {
|
||||||
|
padding-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
border: 1px solid darken($ui-base-color, 8%);
|
||||||
|
border-top: 0;
|
||||||
|
background: darken($ui-base-color, 4%);
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
.optional &:first-child {
|
||||||
|
border-top: 1px solid darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($ui-base-color, 2%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: lighten($ui-base-color, 2%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
|
||||||
|
&--unpadded {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--with-image {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.emojione {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__extra {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
text-align: right;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory__tag {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
a {
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.optional .batch-table__toolbar,
|
||||||
|
&.optional .batch-table__row__select {
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__content {
|
||||||
|
padding-top: 0;
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nothing-here {
|
||||||
|
border: 1px solid darken($ui-base-color, 8%);
|
||||||
|
border-top: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-top: 1px solid darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 870px) {
|
||||||
|
.accounts-table tbody td.optional {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
app/javascript/styles/bliss/variables.scss
Normal file
32
app/javascript/styles/bliss/variables.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
@import '../mastodon/variables';
|
||||||
|
|
||||||
|
// Commonly used web colors
|
||||||
|
$black: #000; // Black
|
||||||
|
$white: #fff; // White
|
||||||
|
$success-green: #6bbd77 !default; // Padua
|
||||||
|
$error-red: #d4839b !default; // Cerise
|
||||||
|
$warning-red: #528dc8 !default; // Sunset Orange
|
||||||
|
$gold-star: #98c6ff !default; // Dark Goldenrod
|
||||||
|
|
||||||
|
/************************
|
||||||
|
BEGIN bliss specific variables
|
||||||
|
************************/
|
||||||
|
|
||||||
|
// Variables for components
|
||||||
|
$media-modal-media-max-width: 100%;
|
||||||
|
// put margins on top and bottom of image to avoid the screen covered by image.
|
||||||
|
$media-modal-media-max-height: 80%;
|
||||||
|
// fix
|
||||||
|
|
||||||
|
|
||||||
|
// Variables for components
|
||||||
|
$media-modal-media-max-width: 100%;
|
||||||
|
// put margins on top and bottom of image to avoid the screen covered by image.
|
||||||
|
$media-modal-media-max-height: 80%;
|
||||||
|
|
||||||
|
$no-gap-breakpoint: 600px;
|
||||||
|
$main-col-size-max: 800px;
|
||||||
|
/************************
|
||||||
|
END bliss specific variables
|
||||||
|
************************/
|
||||||
|
|
595
app/javascript/styles/bliss/widgets.scss
Normal file
595
app/javascript/styles/bliss/widgets.scss
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
.hero-widget {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
background: $base-shadow-color;
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
background: $ui-base-color;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
line-height: 20px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
.emojione {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: -3px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 700;
|
||||||
|
background: transparent;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
color: lighten($darker-text-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.endorsements-widget {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
padding: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
padding: 10px 0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__display-name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trends__item {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trends-widget {
|
||||||
|
h4 {
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-widget {
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: $ui-base-color;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-widget {
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 2px dashed $dark-text-color;
|
||||||
|
text-align: center;
|
||||||
|
color: $darker-text-color;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-widget {
|
||||||
|
min-height: 100%;
|
||||||
|
font-size: 15px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
line-height: 20px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
padding: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
border-bottom: 0;
|
||||||
|
padding: 10px 0;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px;
|
||||||
|
padding-top: 0;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.moved-account-widget {
|
||||||
|
padding: 15px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: $ui-base-color;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
strong,
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&.mention {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__message {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
margin-right: 5px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__card {
|
||||||
|
.detailed-status__display-avatar {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__display-name {
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.memoriam-widget {
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: $base-shadow-color;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 60px 15px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-size: 36px;
|
||||||
|
line-height: 1.1;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 15px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-top: 0;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory {
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
|
||||||
|
&__tag {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
& > a,
|
||||||
|
& > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active > a {
|
||||||
|
background: $ui-highlight-color;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled > div {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $primary-text-color;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
display: block;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 15px;
|
||||||
|
margin-top: 8px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active h4 {
|
||||||
|
&,
|
||||||
|
.fa,
|
||||||
|
small,
|
||||||
|
.trends__item__current {
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-stack {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: (36px + 4px) * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active .avatar-stack .account__avatar {
|
||||||
|
border-color: $ui-highlight-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trends__item__current {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-stack {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
.account__avatar {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
margin-left: -10px;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
border: 2px solid $ui-base-color;
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.accounts-table {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.account {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td {
|
||||||
|
padding: 15px 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:last-child td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__count {
|
||||||
|
width: 120px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $primary-text-color;
|
||||||
|
|
||||||
|
small {
|
||||||
|
display: block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__comment {
|
||||||
|
width: 50%;
|
||||||
|
vertical-align: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
tbody td.optional {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.moved-account-widget,
|
||||||
|
.memoriam-widget,
|
||||||
|
.box-widget,
|
||||||
|
.contact-widget,
|
||||||
|
.landing-page__information.contact-widget,
|
||||||
|
.directory,
|
||||||
|
.page-header {
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$maximum-width: 1235px;
|
||||||
|
$fluid-breakpoint: $maximum-width + 20px;
|
||||||
|
|
||||||
|
.statuses-grid {
|
||||||
|
min-height: 600px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 640px) {
|
||||||
|
width: 100% !important; // Masonry layout is unnecessary at this width
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
width: (960px - 20px) / 3;
|
||||||
|
|
||||||
|
@media screen and (max-width: $fluid-breakpoint) {
|
||||||
|
width: (940px - 20px) / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 640px) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
width: 100vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status {
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-top: 1px solid lighten($ui-base-color, 16%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
.detailed-status__meta {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__content {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
|
||||||
|
.emojione {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: -3px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__content__spoiler-link {
|
||||||
|
line-height: 20px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-gallery,
|
||||||
|
.status-card,
|
||||||
|
.video-player {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-widget {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-widget,
|
||||||
|
.placeholder-widget {
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $ui-highlight-color;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-of-contents {
|
||||||
|
background: darken($ui-base-color, 4%);
|
||||||
|
min-height: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
li a {
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $primary-text-color;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li:last-child a {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li ul {
|
||||||
|
padding-left: 20px;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
}
|
0
app/javascript/styles/custom.scss
Normal file
0
app/javascript/styles/custom.scss
Normal file
0
app/javascript/styles/custom/diff.scss
Normal file
0
app/javascript/styles/custom/diff.scss
Normal file
0
app/javascript/styles/custom/variables.scss
Normal file
0
app/javascript/styles/custom/variables.scss
Normal file
0
app/javascript/styles/default/diff.scss
Normal file
0
app/javascript/styles/default/diff.scss
Normal file
0
app/javascript/styles/default/variables.scss
Normal file
0
app/javascript/styles/default/variables.scss
Normal file
0
app/javascript/styles/large_center.scss
Normal file
0
app/javascript/styles/large_center.scss
Normal file
@ -1,3 +1,3 @@
|
|||||||
@import 'mastodon-light/variables';
|
@import 'mastodon-light/variables';
|
||||||
@import 'application';
|
@import 'bliss';
|
||||||
@import 'mastodon-light/diff';
|
@import 'mastodon-light/diff';
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Dependent colors
|
// Dependent colors
|
||||||
$black: #000000;
|
$black: #000000;
|
||||||
$white: #ffffff;
|
$white: #eeeeff;
|
||||||
|
|
||||||
$classic-base-color: #282c37;
|
$classic-base-color: #282c37;
|
||||||
$classic-primary-color: #9baec8;
|
$classic-primary-color: #9baec8;
|
||||||
$classic-secondary-color: #d9e1e8;
|
$classic-secondary-color: #d9e1f8;
|
||||||
$classic-highlight-color: #2b90d9;
|
$classic-highlight-color: #2b90d9;
|
||||||
|
|
||||||
// Differences
|
// Differences
|
||||||
@ -13,10 +13,10 @@ $success-green: lighten(#3c754d, 8%);
|
|||||||
$base-overlay-background: $white !default;
|
$base-overlay-background: $white !default;
|
||||||
$valid-value-color: $success-green !default;
|
$valid-value-color: $success-green !default;
|
||||||
|
|
||||||
$ui-base-color: $classic-secondary-color !default;
|
$ui-base-color: $base-overlay-background !default;
|
||||||
$ui-base-lighter-color: #b0c0cf;
|
$ui-base-lighter-color: #dedeff;
|
||||||
$ui-primary-color: #9bcbed;
|
$ui-primary-color: #9bcbed;
|
||||||
$ui-secondary-color: $classic-base-color !default;
|
$ui-secondary-color: $classic-secondary-color !default;
|
||||||
$ui-highlight-color: #2b90d9;
|
$ui-highlight-color: #2b90d9;
|
||||||
|
|
||||||
$primary-text-color: $black !default;
|
$primary-text-color: $black !default;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
svg {
|
> svg {
|
||||||
fill: $primary-text-color;
|
fill: $primary-text-color;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
@ -88,6 +88,7 @@ code {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
|
color: $white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
// Commonly used web colors
|
// Commonly used web colors
|
||||||
$black: #000000; // Black
|
$black: #000000; // Black
|
||||||
$white: #ffffff; // White
|
$white: #ffffff; // White
|
||||||
$success-green: #79bd9a !default; // Padua
|
$success-green: #79bd9a !default; // Padua
|
||||||
$error-red: #df405a !default; // Cerise
|
$error-red: #df405a !default; // Cerise
|
||||||
$warning-red: #ff5050 !default; // Sunset Orange
|
$warning-red: #ff5050 !default; // Sunset Orange
|
||||||
$gold-star: #ca8f04 !default; // Dark Goldenrod
|
$gold-star: #ca8f04 !default; // Dark Goldenrod
|
||||||
|
|
||||||
$red-bookmark: $warning-red;
|
$red-bookmark: $warning-red;
|
||||||
|
|
||||||
// Values from the classic Mastodon UI
|
// Values from the classic Mastodon UI
|
||||||
$classic-base-color: #282c37; // Midnight Express
|
$classic-base-color: #282c37; // Midnight Express
|
||||||
$classic-primary-color: #9baec8; // Echo Blue
|
$classic-primary-color: #9baec8; // Echo Blue
|
||||||
$classic-secondary-color: #d9e1e8; // Pattens Blue
|
$classic-secondary-color: #d9e1e8; // Pattens Blue
|
||||||
$classic-highlight-color: #2b90d9; // Summer Sky
|
$classic-highlight-color: #2b90d9; // Summer Sky
|
||||||
|
|
||||||
// Variables for defaults in UI
|
// Variables for defaults in UI
|
||||||
$base-shadow-color: $black !default;
|
$base-shadow-color: $black !default;
|
||||||
@ -23,10 +23,10 @@ $valid-value-color: $success-green !default;
|
|||||||
$error-value-color: $error-red !default;
|
$error-value-color: $error-red !default;
|
||||||
|
|
||||||
// Tell UI to use selected colors
|
// Tell UI to use selected colors
|
||||||
$ui-base-color: $classic-base-color !default; // Darkest
|
$ui-base-color: $classic-base-color !default; // Darkest
|
||||||
$ui-base-lighter-color: lighten($ui-base-color, 26%) !default; // Lighter darkest
|
$ui-base-lighter-color: lighten($ui-base-color, 26%) !default; // Lighter darkest
|
||||||
$ui-primary-color: $classic-primary-color !default; // Lighter
|
$ui-primary-color: $classic-primary-color !default; // Lighter
|
||||||
$ui-secondary-color: $classic-secondary-color !default; // Lightest
|
$ui-secondary-color: $classic-secondary-color !default; // Lightest
|
||||||
$ui-highlight-color: $classic-highlight-color !default;
|
$ui-highlight-color: $classic-highlight-color !default;
|
||||||
|
|
||||||
// Variables for texts
|
// Variables for texts
|
||||||
@ -43,6 +43,20 @@ $inverted-text-color: $ui-base-color !default;
|
|||||||
$lighter-text-color: $ui-base-lighter-color !default;
|
$lighter-text-color: $ui-base-lighter-color !default;
|
||||||
$light-text-color: $ui-primary-color !default;
|
$light-text-color: $ui-primary-color !default;
|
||||||
|
|
||||||
|
|
||||||
|
// User Interface Colors
|
||||||
|
$ui-base-color: #313644; // Midnight Express
|
||||||
|
$ui-base-lighter-color: #bdd2d6;
|
||||||
|
$ui-primary-color: #a1ccff; // Echo Blue
|
||||||
|
$ui-secondary-color: #7fc0ff; // Pattens Blue
|
||||||
|
$ui-highlight-color: #00a7d1; // Summer Sky
|
||||||
|
|
||||||
|
// Variables for components
|
||||||
|
$media-modal-media-max-width: 100%;
|
||||||
|
// put margins on top and bottom of image to avoid the screen covered by image.
|
||||||
|
$media-modal-media-max-height: 80%;
|
||||||
|
// fix
|
||||||
|
|
||||||
// Language codes that uses CJK fonts
|
// Language codes that uses CJK fonts
|
||||||
$cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
|
$cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
|
||||||
|
|
||||||
|
12
app/models/article.rb
Normal file
12
app/models/article.rb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: articles
|
||||||
|
#
|
||||||
|
# id :bigint(8) not null, primary key
|
||||||
|
# title :string
|
||||||
|
# text :text
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
class Article < ApplicationRecord
|
||||||
|
end
|
@ -23,7 +23,7 @@
|
|||||||
# file_storage_schema_version :integer
|
# file_storage_schema_version :integer
|
||||||
# thumbnail_file_name :string
|
# thumbnail_file_name :string
|
||||||
# thumbnail_content_type :string
|
# thumbnail_content_type :string
|
||||||
# thumbnail_file_size :integer
|
# thumbnail_file_size :bigint(8)
|
||||||
# thumbnail_updated_at :datetime
|
# thumbnail_updated_at :datetime
|
||||||
# thumbnail_remote_url :string
|
# thumbnail_remote_url :string
|
||||||
#
|
#
|
||||||
|
16
app/models/user_group.rb
Normal file
16
app/models/user_group.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: user_groups
|
||||||
|
#
|
||||||
|
# id :bigint(8) not null, primary key
|
||||||
|
# name :string not null
|
||||||
|
# createdAt :datetime
|
||||||
|
# visibility :string
|
||||||
|
# account_id :integer
|
||||||
|
# creator_id :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
|
class UserGroup < ApplicationRecord
|
||||||
|
end
|
3
app/serializers/user_group_serializer.rb
Normal file
3
app/serializers/user_group_serializer.rb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class UserGroupSerializer < ActiveModel::Serializer
|
||||||
|
attributes :id, :name, :createAt, :visibility, :members
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user