diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb index c8a20bae..2ab1b1a5 100644 --- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb @@ -4,52 +4,80 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController include Authorization before_action -> { authorize_if_got_token! :read, :'read:accounts' } - - respond_to :json + before_action :set_status + before_action :verify_own_status + after_action :insert_pagination_headers def index - render json: {}, status: :ok + @accounts = load_accounts + render json: @accounts, each_serializer: REST::AccountSerializer end private def load_accounts - # + scope = default_accounts + scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? + scope.merge(paginated_favourites).to_a end def default_accounts - # + Account + .includes(:favourites, :account_stat) + .references(:favourites) + .where(favourites: { status_id: @status.id }) end def paginated_favourites - # + Favourite.paginate_by_max_id( + limit_param(DEFAULT_ACCOUNTS_LIMIT), + params[:max_id], + params[:since_id] + ) + end + + def insert_pagination_headers + set_pagination_headers(next_path, prev_path) end def next_path - # + if records_continue? + api_v1_status_favourited_by_index_url pagination_params(max_id: pagination_max_id) + end end def prev_path - # + unless @accounts.empty? + api_v1_status_favourited_by_index_url pagination_params(since_id: pagination_since_id) + end end def pagination_max_id - # + @accounts.last.favourites.last.id end def pagination_since_id - # + @accounts.first.favourites.first.id end def records_continue? - # + @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end def set_status - # + @status = Status.find(params[:status_id]) + authorize @status, :show? + rescue Mastodon::NotPermittedError + not_found end def pagination_params(core_params) - # + params.slice(:limit).permit(:limit).merge(core_params) end -end + + def verify_own_status + unless @status.account.id == current_account.id + render json: {}, status: 404 + end + end +end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3641c3e1..e338b3c7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -99,7 +99,7 @@ class ApplicationController < ActionController::Base end def current_theme - 'light' + 'default' # : todo : # current_user.setting_theme end diff --git a/app/javascript/gabsocial/actions/lists.js b/app/javascript/gabsocial/actions/lists.js index e0400268..fe9e41bf 100644 --- a/app/javascript/gabsocial/actions/lists.js +++ b/app/javascript/gabsocial/actions/lists.js @@ -258,8 +258,7 @@ export const fetchListSuggestions = (q) => (dispatch, getState) => { const params = { q, resolve: false, - limit: 4, - following: true, + limit: 25, }; api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => { diff --git a/app/javascript/gabsocial/actions/tenor.js b/app/javascript/gabsocial/actions/tenor.js index cab02a2c..075fee9d 100644 --- a/app/javascript/gabsocial/actions/tenor.js +++ b/app/javascript/gabsocial/actions/tenor.js @@ -4,6 +4,7 @@ import { me } from '../initial_state' export const GIFS_CLEAR_RESULTS = 'GIFS_CLEAR_RESULTS' export const GIF_SET_SELECTED = 'GIF_SET_SELECTED' export const GIF_CHANGE_SEARCH_TEXT = 'GIF_CHANGE_SEARCH_TEXT' +export const GIF_CLEAR_SELECTED = 'GIF_CLEAR_SELECTED' export const GIF_RESULTS_FETCH_REQUEST = 'GIF_RESULTS_FETCH_REQUEST' export const GIF_RESULTS_FETCH_SUCCESS = 'GIF_RESULTS_FETCH_SUCCESS' diff --git a/app/javascript/gabsocial/components/account.js b/app/javascript/gabsocial/components/account.js index b0bec958..25c103f5 100644 --- a/app/javascript/gabsocial/components/account.js +++ b/app/javascript/gabsocial/components/account.js @@ -135,6 +135,8 @@ class Account extends ImmutablePureComponent { isOutline={true} color='brand' backgroundColor='none' + icon={actionIcon} + iconSize='10px' > {actionTitle} diff --git a/app/javascript/gabsocial/components/autosuggest_textbox.js b/app/javascript/gabsocial/components/autosuggest_textbox.js index 9d237596..1911f487 100644 --- a/app/javascript/gabsocial/components/autosuggest_textbox.js +++ b/app/javascript/gabsocial/components/autosuggest_textbox.js @@ -265,7 +265,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { className={textareaClasses} disabled={disabled} placeholder={placeholder} - autoFocus={false} + dautoFocus={false} value={value} onChange={this.onChange} // onKeyDown={this.onKeyDown} diff --git a/app/javascript/gabsocial/components/button.js b/app/javascript/gabsocial/components/button.js index 0a87cf79..eea0b06f 100644 --- a/app/javascript/gabsocial/components/button.js +++ b/app/javascript/gabsocial/components/button.js @@ -138,6 +138,7 @@ export default class Button extends PureComponent { cursorPointer: 1, textAlignCenter: 1, outlineNone: 1, + // outlineOnFocus: !isText, flexRow: !!children && !!icon, cursorNotAllowed: isDisabled, opacity05: isDisabled, @@ -221,6 +222,9 @@ export default class Button extends PureComponent { ) } + const isLogout = href === '/auth/sign_out' + const dataMethod = isLogout ? 'delete' : undefined + const options = { rel, target, @@ -230,6 +234,7 @@ export default class Button extends PureComponent { className: classes, href: href || undefined, ref: this.setRef, + 'data-method': dataMethod, ...handlers, } diff --git a/app/javascript/gabsocial/components/divider.js b/app/javascript/gabsocial/components/divider.js index 7af4fce2..c50a998d 100644 --- a/app/javascript/gabsocial/components/divider.js +++ b/app/javascript/gabsocial/components/divider.js @@ -1,7 +1,4 @@ -import classnames from 'classnames/bind' - -// Bind CSS Modules global variable `_s` to classNames module -const cx = classnames.bind(_s) +import { CX } from '../constants' /** * Renders a divider component @@ -18,7 +15,7 @@ export default class Divider extends PureComponent { render() { const { isSmall, isInvisible } = this.props - const classes = cx({ + const classes = CX({ default: 1, borderBottom1PX: !isInvisible, borderColorSecondary: !isInvisible, diff --git a/app/javascript/gabsocial/components/heading.js b/app/javascript/gabsocial/components/heading.js index 98d27734..8033c4b5 100644 --- a/app/javascript/gabsocial/components/heading.js +++ b/app/javascript/gabsocial/components/heading.js @@ -31,13 +31,13 @@ export default class Heading extends PureComponent { } render() { - const { children, size, center } = this.props + const { children, size, isCentered } = this.props // Each size has it's own custom style const classes = cx({ default: 1, text: 1, - textAlignCenter: center, + textAlignCenter: isCentered, colorPrimary: [SIZES.h1, SIZES.h2].indexOf(size) > -1, colorSecondary: [SIZES.h3, SIZES.h4, SIZES.h5].indexOf(size) > -1, diff --git a/app/javascript/gabsocial/components/link_footer.js b/app/javascript/gabsocial/components/link_footer.js index 0975bfa6..64c81295 100644 --- a/app/javascript/gabsocial/components/link_footer.js +++ b/app/javascript/gabsocial/components/link_footer.js @@ -54,11 +54,12 @@ class LinkFooter extends PureComponent { text: intl.formatMessage(messages.help), requiresUser: true, }, - { - onClick: onOpenHotkeys, - text: intl.formatMessage(messages.hotkeys), - requiresUser: true, - }, + // : todo : + // { + // onClick: onOpenHotkeys, + // text: intl.formatMessage(messages.hotkeys), + // requiresUser: true, + // }, { to: '/auth/edit', text: intl.formatMessage(messages.security), diff --git a/app/javascript/gabsocial/components/list_item.js b/app/javascript/gabsocial/components/list_item.js index 50fa1eec..4faa8433 100644 --- a/app/javascript/gabsocial/components/list_item.js +++ b/app/javascript/gabsocial/components/list_item.js @@ -56,6 +56,8 @@ export default class ListItem extends PureComponent { flexRow: 1, alignItemsCenter: 1, width100PC: 1, + outlineNone: 1, + bgTransparent: 1, bgSubtle_onHover: 1, borderColorSecondary: !isLast, borderBottom1PX: !isLast, diff --git a/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js b/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js index aa260e2a..e6e13097 100644 --- a/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js +++ b/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js @@ -8,7 +8,7 @@ import SettingSwitch from '../setting_switch' import Text from '../text' const messages = defineMessages({ - title: { id: 'community_timeline_settings', defaultMessage: 'Community Timeline Settings' }, + title: { id: 'community_timeline_settings', defaultMessage: 'Community Feed Settings' }, saveAndClose: { id: 'saveClose', defaultMessage: 'Save & Close' }, onlyMedia: { id: 'community.column_settings.media_only', defaultMessage: 'Media Only' }, showInSidebar: { id: 'show_in_sidebar', defaultMessage: 'Show in Sidebar' }, @@ -18,17 +18,15 @@ const mapStateToProps = (state) => ({ settings: state.getIn(['settings', 'community']), }) -const mapDispatchToProps = (dispatch, { onClose }) => { - return { - onChange(key, checked) { - dispatch(changeSetting(['community', ...key], checked)) - }, - onSave() { - dispatch(saveSettings()) - onClose() - }, - } -} +const mapDispatchToProps = (dispatch, { onClose }) => ({ + onChange(key, checked) { + dispatch(changeSetting(['community', ...key], checked)) + }, + onSave() { + dispatch(saveSettings()) + onClose() + }, +}) export default @connect(mapStateToProps, mapDispatchToProps) @@ -39,6 +37,7 @@ class CommunityTimelineSettingsModal extends ImmutablePureComponent { intl: PropTypes.object.isRequired, settings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, onSave: PropTypes.func.isRequired, } @@ -47,10 +46,16 @@ class CommunityTimelineSettingsModal extends ImmutablePureComponent { } render() { - const { intl, settings, onChange, onClose } = this.props + const { + intl, + settings, + onChange, + onClose, + } = this.props return ( diff --git a/app/javascript/gabsocial/components/modal/confirmation_modal.js b/app/javascript/gabsocial/components/modal/confirmation_modal.js index 0267d088..22557956 100644 --- a/app/javascript/gabsocial/components/modal/confirmation_modal.js +++ b/app/javascript/gabsocial/components/modal/confirmation_modal.js @@ -14,8 +14,6 @@ class ConfirmationModal extends PureComponent { confirm: PropTypes.any.isRequired, onClose: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired, - secondary: PropTypes.string, - onSecondary: PropTypes.func, intl: PropTypes.object.isRequired, onCancel: PropTypes.func, } @@ -29,11 +27,6 @@ class ConfirmationModal extends PureComponent { this.props.onConfirm() } - handleSecondary = () => { - this.props.onClose() - this.props.onSecondary() - } - handleCancel = () => { const { onClose, onCancel } = this.props onClose() @@ -49,7 +42,6 @@ class ConfirmationModal extends PureComponent { title, message, confirm, - secondary } = this.props return ( @@ -74,19 +66,11 @@ class ConfirmationModal extends PureComponent { onClick={this.handleCancel} className={[_s.mr10, _s.flexGrow1].join(' ')} > - + - - { /** - : todo : - */ - secondary !== undefined && ( - diff --git a/app/javascript/gabsocial/components/modal/display_options_modal.js b/app/javascript/gabsocial/components/modal/display_options_modal.js index 40244a91..e44f9d8e 100644 --- a/app/javascript/gabsocial/components/modal/display_options_modal.js +++ b/app/javascript/gabsocial/components/modal/display_options_modal.js @@ -1,6 +1,12 @@ import { injectIntl, defineMessages } from 'react-intl' -import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePropTypes from 'react-immutable-proptypes' +import ImmutablePureComponent from 'react-immutable-pure-component' +import { changeSetting, saveSettings } from '../../actions/settings' +import { + DEFAULT_THEME, + DEFAULT_FONT_SIZE, + FONT_SIZES, +} from '../../constants' import ModalLayout from './modal_layout' import Button from '../button' import Text from '../text' @@ -12,12 +18,15 @@ const messages = defineMessages({ }) const mapStateToProps = (state) => ({ - settings: state.getIn(['notifications', 'filter']), + displayOptionsSettings: state.getIn(['settings', 'displayOptions']), + fontSize: state.getIn(['settings', 'displayOptions', 'fontSize'], DEFAULT_FONT_SIZE), + theme: state.getIn(['settings', 'displayOptions', 'theme'], DEFAULT_THEME), }) const mapDispatchToProps = (dispatch) => ({ - onChange(path, value) { - dispatch(setFilter(path, value)) + onChange(key, value) { + dispatch(changeSetting(['displayOptions', key], value)) + dispatch(saveSettings()) }, }) @@ -27,34 +36,47 @@ export default class DisplayOptionsModal extends ImmutablePureComponent { static propTypes = { - isSubmitting: PropTypes.bool.isRequired, - account: PropTypes.object.isRequired, - onConfirm: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, + fontSize: PropTypes.string, intl: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + displayOptionsSettings: ImmutablePropTypes.map, + theme: PropTypes.string, onChange: PropTypes.func.isRequired, - settings: ImmutablePropTypes.map.isRequired, + onClose: PropTypes.func.isRequired, } - handleClick = () => { - this.props.onClose() - this.props.onConfirm(this.props.account, this.props.notifications) + updateOnProps = [ + 'fontSize', + 'displayOptionsSettings', + 'theme', + ] + + handleOnFontSizeChange = (e) => { + const fontSizeNames = Object.keys(FONT_SIZES) + const index = fontSizeNames[e.target.value] + + this.props.onChange('fontSize', index) + } + + handleOnThemeSelected = (e) => { + this.props.onChange('theme', e.target.value) + } + + handleOnRadiusKeyDisabled = (key, checked) => { + this.props.onChange(key, checked) } - // document.documentElement.style.setProperty("--color-surface", "black"); - render() { const { - account, + fontSize, + displayOptionsSettings, intl, - settings, - onChange, + theme, onClose, } = this.props - // theme - light, muted, dark - // text size - extra small, small, normal, medium, large, extra large - // rounded borders + const fontSizeNames = Object.keys(FONT_SIZES) + const currentFontSizeIndex = fontSizeNames.indexOf(fontSize) return (
- + {intl.formatMessage(messages.message)}
-
- +
+ Font Size
- test +
+ + Aa + + + + Aa + +
-
- +
+ Rounded
- + Theme -
+
-
-
- - Light - -
-
+ -
-
- - Muted - -
-
+ -
-
- - Black - -
-
+
- -
-
- + ) } } + +class ThemeBlock extends PureComponent { + + static propTypes = { + checked: PropTypes.bool, + onChange: PropTypes.func.isRequired, + title: PropTypes.string, + value: PropTypes.string, + style: PropTypes.object, + } + + render() { + const { + checked, + onChange, + title, + value, + style, + } = this.props + + const id = `theme-${value}` + + return ( + + ) + } + +} \ No newline at end of file diff --git a/app/javascript/gabsocial/components/modal/list_delete_modal.js b/app/javascript/gabsocial/components/modal/list_delete_modal.js index dbb3826a..c6a8692b 100644 --- a/app/javascript/gabsocial/components/modal/list_delete_modal.js +++ b/app/javascript/gabsocial/components/modal/list_delete_modal.js @@ -1,3 +1,5 @@ +import ImmutablePropTypes from 'react-immutable-proptypes' +import ImmutablePureComponent from 'react-immutable-pure-component' import { injectIntl, defineMessages } from 'react-intl' import { deleteList } from '../../actions/lists' import ConfirmationModal from './confirmation_modal' @@ -9,24 +11,24 @@ const messages = defineMessages({ }) const mapDispatchToProps = (dispatch) => ({ - onConfirm(listId) { - dispatch(deleteList(listId)) - }, + onConfirm: (listId) => dispatch(deleteList(listId)), }) export default @injectIntl @connect(null, mapDispatchToProps) -class ListDeleteModal extends PureComponent { +class ListDeleteModal extends ImmutablePureComponent { static propTypes = { - list: PropTypes.object.isRequired, - onConfirm: PropTypes.func.isRequired, + list: ImmutablePropTypes.map.isRequired, intl: PropTypes.object.isRequired, + onConfirm: PropTypes.func.isRequired, } handleClick = () => { this.props.onConfirm(this.props.list.get('id')) + // : todo : + // redirect back to /lists } render() { diff --git a/app/javascript/gabsocial/components/modal/list_editor_modal.js b/app/javascript/gabsocial/components/modal/list_editor_modal.js index 2378e4f8..c4e589da 100644 --- a/app/javascript/gabsocial/components/modal/list_editor_modal.js +++ b/app/javascript/gabsocial/components/modal/list_editor_modal.js @@ -14,19 +14,20 @@ class ListEditorModal extends ImmutablePureComponent { static propTypes = { intl: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, - listId: PropTypes.string.isRequired, + id: PropTypes.string.isRequired, } render() { - const { intl, onClose, listId } = this.props + const { intl, onClose, id } = this.props return ( - + ) } diff --git a/app/javascript/gabsocial/components/modal/list_timeline_settings_modal.js b/app/javascript/gabsocial/components/modal/list_timeline_settings_modal.js index a68a9b24..ddccf381 100644 --- a/app/javascript/gabsocial/components/modal/list_timeline_settings_modal.js +++ b/app/javascript/gabsocial/components/modal/list_timeline_settings_modal.js @@ -21,17 +21,15 @@ const mapStateToProps = (state) => ({ settings: state.getIn(['settings', 'list']), }) -const mapDispatchToProps = (dispatch, { onClose }) => { - return { - onChange(key, checked) { - dispatch(changeSetting(['list', ...key], checked)) - }, - onSave() { - dispatch(saveSettings()) - onClose() - }, - } -} +const mapDispatchToProps = (dispatch, { onClose }) => ({ + onChange(key, checked) { + dispatch(changeSetting(['list', ...key], checked)) + }, + onSave() { + dispatch(saveSettings()) + onClose() + }, +}) export default @connect(mapStateToProps, mapDispatchToProps) diff --git a/app/javascript/gabsocial/components/modal/modal_root.js b/app/javascript/gabsocial/components/modal/modal_root.js index 0ed07fe3..163f5b86 100644 --- a/app/javascript/gabsocial/components/modal/modal_root.js +++ b/app/javascript/gabsocial/components/modal/modal_root.js @@ -29,6 +29,8 @@ import { MODAL_MUTE, MODAL_PRO_UPGRADE, MODAL_REPORT, + MODAL_STATUS_LIKES, + MODAL_STATUS_REPOSTS, MODAL_STATUS_REVISIONS, MODAL_UNAUTHORIZED, MODAL_UNFOLLOW, @@ -60,6 +62,8 @@ import { MuteModal, ProUpgradeModal, ReportModal, + StatusLikesModal, + StatusRepostsModal, StatusRevisionsModal, UnauthorizedModal, UnfollowModal, @@ -92,6 +96,8 @@ MODAL_COMPONENTS[MODAL_MEDIA] = MediaModal MODAL_COMPONENTS[MODAL_MUTE] = MuteModal MODAL_COMPONENTS[MODAL_PRO_UPGRADE] = ProUpgradeModal MODAL_COMPONENTS[MODAL_REPORT] = ReportModal +MODAL_COMPONENTS[MODAL_STATUS_LIKES] = StatusLikesModal +MODAL_COMPONENTS[MODAL_STATUS_REPOSTS] = StatusRepostsModal MODAL_COMPONENTS[MODAL_STATUS_REVISIONS] = StatusRevisionsModal MODAL_COMPONENTS[MODAL_UNAUTHORIZED] = UnauthorizedModal MODAL_COMPONENTS[MODAL_UNFOLLOW] = UnfollowModal diff --git a/app/javascript/gabsocial/components/modal/status_likes_modal.js b/app/javascript/gabsocial/components/modal/status_likes_modal.js new file mode 100644 index 00000000..384f9cd6 --- /dev/null +++ b/app/javascript/gabsocial/components/modal/status_likes_modal.js @@ -0,0 +1,44 @@ +import { defineMessages, injectIntl } from 'react-intl' +import ImmutablePureComponent from 'react-immutable-pure-component' +import ImmutablePropTypes from 'react-immutable-proptypes' +import StatusLikes from '../../features/status_likes' +import ModalLayout from './modal_layout' + +const messages = defineMessages({ + title: { id: 'likes', defaultMessage: 'Likes' }, +}) + +export default +@injectIntl +class StatusLikesModal extends ImmutablePureComponent { + + static propTypes = { + intl: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + status: ImmutablePropTypes.map.isRequired, + } + + render() { + const { + intl, + onClose, + status, + } = this.props + + const params = { + statusId: status.get('id'), + } + + return ( + + + + ) + } + +} diff --git a/app/javascript/gabsocial/components/modal/status_reposts_modal.js b/app/javascript/gabsocial/components/modal/status_reposts_modal.js new file mode 100644 index 00000000..146f2305 --- /dev/null +++ b/app/javascript/gabsocial/components/modal/status_reposts_modal.js @@ -0,0 +1,44 @@ +import { defineMessages, injectIntl } from 'react-intl' +import ImmutablePureComponent from 'react-immutable-pure-component' +import ImmutablePropTypes from 'react-immutable-proptypes' +import StatusReposts from '../../features/status_reposts' +import ModalLayout from './modal_layout' + +const messages = defineMessages({ + title: { id: 'reposts', defaultMessage: 'Reposts' }, +}) + +export default +@injectIntl +class StatusRepostsModal extends ImmutablePureComponent { + + static propTypes = { + intl: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + status: ImmutablePropTypes.map.isRequired, + } + + render() { + const { + intl, + onClose, + status, + } = this.props + + const params = { + statusId: status.get('id'), + } + + return ( + + + + ) + } + +} diff --git a/app/javascript/gabsocial/components/modal/status_stats_modal.js b/app/javascript/gabsocial/components/modal/status_stats_modal.js deleted file mode 100644 index 723ad7e0..00000000 --- a/app/javascript/gabsocial/components/modal/status_stats_modal.js +++ /dev/null @@ -1,68 +0,0 @@ -import { injectIntl, defineMessages } from 'react-intl' -import { muteAccount } from '../../actions/accounts' - -const messages = defineMessages({ - muteMessage: { id: 'confirmations.mute.message', defaultMessage: 'Are you sure you want to mute {name}?' }, - cancel: { id: 'confirmation_modal.cancel', defaultMessage: 'Cancel' }, - confirm: { id: 'confirmations.mute.confirm', defaultMessage: 'Mute' }, -}) - -const mapStateToProps = (state) => ({ - isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']), - account: state.getIn(['mutes', 'new', 'account']), -}) - -const mapDispatchToProps = (dispatch) => ({ - onConfirm(account, notifications) { - dispatch(muteAccount(account.get('id'), notifications)) - }, -}) - -export default -@connect(mapStateToProps, mapDispatchToProps) -@injectIntl -class UnfollowModal extends PureComponent { - - static propTypes = { - isSubmitting: PropTypes.bool.isRequired, - account: PropTypes.object.isRequired, - onConfirm: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - } - - componentDidMount() { - this.button.focus() - } - - handleClick = () => { - this.props.onClose() - this.props.onConfirm(this.props.account, this.props.notifications) - } - - handleCancel = () => { - this.props.onClose() - } - - render() { - const { account, intl } = this.props - - // , { - // message: @{account.get('acct')} }} />, - // confirm: intl.formatMessage(messages.unfollowConfirm), - // onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - // })); - - return ( - } - confirm={} - onConfirm={() => { - // dispatch(blockDomain(domain)) - // dispatch(blockDomain(domain)) - }} - /> - ) - } - -} diff --git a/app/javascript/gabsocial/components/panel/list_details_panel.js b/app/javascript/gabsocial/components/panel/list_details_panel.js index f9f38f75..4a5028ce 100644 --- a/app/javascript/gabsocial/components/panel/list_details_panel.js +++ b/app/javascript/gabsocial/components/panel/list_details_panel.js @@ -1,10 +1,11 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl' import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePropTypes from 'react-immutable-proptypes' +import moment from 'moment-mini' import PanelLayout from './panel_layout' +import ColumnIndicator from '../column_indicator' import Divider from '../divider' import Icon from '../icon' -import RelativeTimestamp from '../relative_timestamp' import Text from '../text' const messages = defineMessages({ @@ -18,16 +19,20 @@ class ListDetailsPanel extends ImmutablePureComponent { static propTypes = { intl: PropTypes.object.isRequired, - onEdit: PropTypes.func.isRequired, list: ImmutablePropTypes.map, + onEdit: PropTypes.func.isRequired, } - handleOnEdit = () => { - this.props.onEdit() - } + updateOnProps = [ + 'list', + ] render() { - const { intl, list } = this.props + const { + intl, + list, + onEdit, + } = this.props const title = !!list ? list.get('title') : '' const createdAt = !!list ? list.get('created_at') : '' @@ -36,34 +41,41 @@ class ListDetailsPanel extends ImmutablePureComponent { -
+ { + (!title || !createdAt) && + + } + { + title && createdAt && +
+ +
+ + {title} + +
+ + + +
+ + + { + + } + +
-
- - {title} -
- - - -
- - - { - , - }} /> - } - -
- -
+ } ) } diff --git a/app/javascript/gabsocial/components/popover/sidebar_more_popover.js b/app/javascript/gabsocial/components/popover/sidebar_more_popover.js index f806f3bc..fda972d6 100644 --- a/app/javascript/gabsocial/components/popover/sidebar_more_popover.js +++ b/app/javascript/gabsocial/components/popover/sidebar_more_popover.js @@ -1,6 +1,7 @@ import { defineMessages, injectIntl } from 'react-intl' import { MODAL_DISPLAY_OPTIONS } from '../../constants' import { openModal } from '../../actions/modal' +import { closePopover } from '../../actions/popover' import PopoverLayout from './popover_layout' import List from '../list' @@ -13,6 +14,7 @@ const messages = defineMessages({ const mapDispatchToProps = (dispatch) => ({ onOpenDisplayModal: () => { + dispatch(closePopover()) dispatch(openModal(MODAL_DISPLAY_OPTIONS)) }, }) @@ -54,7 +56,7 @@ class SidebarMorePopover extends PureComponent { }, { title: intl.formatMessage(messages.logout), - href: '/auth/log_out', + href: '/auth/sign_out', }, ]} /> diff --git a/app/javascript/gabsocial/components/scrollable_list.js b/app/javascript/gabsocial/components/scrollable_list.js index ae6d35c5..28b54d82 100644 --- a/app/javascript/gabsocial/components/scrollable_list.js +++ b/app/javascript/gabsocial/components/scrollable_list.js @@ -2,6 +2,7 @@ import throttle from 'lodash.throttle' import { List as ImmutableList } from 'immutable' import IntersectionObserverArticle from './intersection_observer_article' import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper' +import Block from './block' import ColumnIndicator from './column_indicator' import LoadMore from './load_more' @@ -250,7 +251,11 @@ export default class ScrollableList extends PureComponent { ); } - return + return ( + + + + ) } } diff --git a/app/javascript/gabsocial/components/search.js b/app/javascript/gabsocial/components/search.js index 4d121acc..96f30a94 100644 --- a/app/javascript/gabsocial/components/search.js +++ b/app/javascript/gabsocial/components/search.js @@ -147,6 +147,7 @@ class Search extends PureComponent { onChange={this.handleOnChange} onFocus={this.handleOnFocus} onBlur={this.handleOnBlur} + autoComplete='off' />
+ }
} { diff --git a/app/javascript/gabsocial/components/status.js b/app/javascript/gabsocial/components/status.js index 44eb0208..b48f29e2 100644 --- a/app/javascript/gabsocial/components/status.js +++ b/app/javascript/gabsocial/components/status.js @@ -89,6 +89,8 @@ class Status extends ImmutablePureComponent { cachedMediaWidth: PropTypes.number, contextType: PropTypes.string, commentsLimited: PropTypes.bool, + onOpenLikes: PropTypes.func.isRequired, + onOpenReposts: PropTypes.func.isRequired, } // Avoid checking props that are functions (and whose equality will always @@ -472,6 +474,8 @@ class Status extends ImmutablePureComponent { onReply={this.props.onReply} onRepost={this.props.onRepost} onShare={this.props.onShare} + onOpenLikes={this.props.onOpenLikes} + onOpenReposts={this.props.onOpenReposts} /> } diff --git a/app/javascript/gabsocial/components/status_action_bar.js b/app/javascript/gabsocial/components/status_action_bar.js index ec4d887e..126e8806 100644 --- a/app/javascript/gabsocial/components/status_action_bar.js +++ b/app/javascript/gabsocial/components/status_action_bar.js @@ -37,6 +37,8 @@ class StatusActionBar extends ImmutablePureComponent { onReply: PropTypes.func.isRequired, onRepost: PropTypes.func.isRequired, status: ImmutablePropTypes.map.isRequired, + onOpenLikes: PropTypes.func.isRequired, + onOpenReposts: PropTypes.func.isRequired, } updateOnProps = ['status'] @@ -58,15 +60,11 @@ class StatusActionBar extends ImmutablePureComponent { } openLikesList = () => { - // : todo : - } - - toggleCommentsVisible = () => { - // : todo : + this.props.onOpenLikes(this.props.status) } openRepostsList = () => { - // : todo : + this.props.onOpenReposts(this.props.status) } setRepostButton = (n) => { diff --git a/app/javascript/gabsocial/components/switch.js b/app/javascript/gabsocial/components/switch.js index bc6a7106..ff5c60ec 100644 --- a/app/javascript/gabsocial/components/switch.js +++ b/app/javascript/gabsocial/components/switch.js @@ -35,6 +35,7 @@ export default class Switch extends PureComponent { circle: 1, border1PX: 1, mlAuto: 1, + bgPrimary: 1, borderColorSecondary: 1, bgBrand: checked, }) diff --git a/app/javascript/gabsocial/constants.js b/app/javascript/gabsocial/constants.js index a1518738..589bfbe3 100644 --- a/app/javascript/gabsocial/constants.js +++ b/app/javascript/gabsocial/constants.js @@ -56,6 +56,8 @@ export const MODAL_MEDIA = 'MEDIA' export const MODAL_MUTE = 'MUTE' export const MODAL_PRO_UPGRADE = 'PRO_UPGRADE' export const MODAL_REPORT = 'REPORT' +export const MODAL_STATUS_LIKES = 'STATUS_LIKES' +export const MODAL_STATUS_REPOSTS = 'STATUS_REPOSTS' export const MODAL_STATUS_REVISIONS = 'STATUS_REVISIONS' export const MODAL_UNAUTHORIZED = 'UNAUTHORIZED' export const MODAL_UNFOLLOW = 'UNFOLLOW' @@ -69,13 +71,14 @@ export const FONT_SIZES_LARGE = '16px' export const FONT_SIZES_EXTRA_LARGE = '17px' export const FONT_SIZES = { - 'extra-small': FONT_SIZES_EXTRA_SMALL, - small: FONT_SIZES_SMALL, - normal: FONT_SIZES_NORMAL, - medium: FONT_SIZES_MEDIUM, - large: FONT_SIZES_LARGE, - 'extra-large': FONT_SIZES_EXTRA_LARGE, + 'extra-small': '12px', + small: '13px', + normal: '14px', + medium: '15px', + large: '16px', + 'extra-large': '17px', } + export const THEMES = [ 'light', 'muted', diff --git a/app/javascript/gabsocial/containers/display.js b/app/javascript/gabsocial/containers/display.js index 16035b20..ecab2cbd 100644 --- a/app/javascript/gabsocial/containers/display.js +++ b/app/javascript/gabsocial/containers/display.js @@ -5,39 +5,55 @@ import { DEFAULT_FONT_SIZE, } from '../constants' -export default class Display extends PureComponent { +const mapStateToProps = (state) => ({ + fontSize: state.getIn(['settings', 'displayOptions', 'fontSize']), + radiusSmallDisabled: state.getIn(['settings', 'displayOptions', 'radiusSmallDisabled']), + radiusCircleDisabled: state.getIn(['settings', 'displayOptions', 'radiusCircleDisabled']), + theme: state.getIn(['settings', 'displayOptions', 'theme']), +}) + +export default +@connect(mapStateToProps) +class Display extends PureComponent { static propTypes = { - theme: PropTypes.string.isRequired, - rounded: PropTypes.bool.isRequired, fontSize: PropTypes.string.isRequired, + radiusSmallDisabled: PropTypes.bool.isRequired, + radiusCircleDisabled: PropTypes.bool.isRequired, + theme: PropTypes.string.isRequired, } state = { theme: this.props.theme, - rounded: this.props.rounded, + radiusSmallDisabled: this.props.radiusSmallDisabled, + radiusCircleDisabled: this.props.radiusCircleDisabled, fontSize: this.props.fontSize, } static defaultProps = { - theme: 'BLACK', - rounded: false, + theme: 'light', + radiusSmallDisabled: true, + radiusCircleDisabled: true, fontSize: 'normal', } componentDidMount() { this.updateTheme(this.state.theme) - this.updateRounded(this.state.rounded) + this.updateRadiusSmallDisabled(this.state.radiusSmallDisabled) + this.updateRadiusCircleDisabled(this.state.radiusCircleDisabled) this.updateFontSizes(this.state.fontSize) } static getDerivedStateFromProps(nextProps, prevState) { + console.log("nextProps:", nextProps) if (nextProps.theme !== prevState.theme || - nextProps.rounded !== prevState.rounded || + nextProps.radiusSmallDisabled !== prevState.radiusSmallDisabled || + nextProps.radiusCircleDisabled !== prevState.radiusCircleDisabled || nextProps.fontSize !== prevState.fontSize) { return { theme: nextProps.theme, - rounded: nextProps.rounded, + radiusSmallDisabled: nextProps.radiusSmallDisabled, + radiusCircleDisabled: nextProps.radiusCircleDisabled, fontSize: nextProps.fontSize, } } @@ -50,8 +66,12 @@ export default class Display extends PureComponent { this.updateTheme(this.state.theme) } - if (prevState.rounded !== this.state.rounded) { - this.updateRounded(this.state.rounded) + if (prevState.radiusSmallDisabled !== this.state.radiusSmallDisabled) { + this.updateRadiusSmallDisabled(this.state.radiusSmallDisabled) + } + + if (prevState.radiusCircleDisabled !== this.state.radiusCircleDisabled) { + this.updateRadiusCircleDisabled(this.state.radiusCircleDisabled) } if (prevState.fontSize !== this.state.fontSize) { @@ -59,16 +79,24 @@ export default class Display extends PureComponent { } } - updateRounded(rounded) { - if (rounded) { - document.documentElement.removeAttribute('rounded') + updateRadiusSmallDisabled(disabled) { + if (disabled) { + document.documentElement.setAttribute('no-radius', ''); } else { - document.documentElement.setAttribute('rounded', '') + document.documentElement.removeAttribute('no-radius') + } + } + + updateRadiusCircleDisabled(disabled) { + if (disabled) { + document.documentElement.setAttribute('no-circle', ''); + } else { + document.documentElement.removeAttribute('no-circle') } } updateFontSizes(fontSize) { - let correctedFontSize = fontSize.toUpperCase() + let correctedFontSize = fontSize.toLowerCase() if (!FONT_SIZES.hasOwnProperty(correctedFontSize)) { correctedFontSize = DEFAULT_FONT_SIZE } @@ -78,7 +106,7 @@ export default class Display extends PureComponent { updateTheme(theme) { let correctedTheme = theme.toLowerCase() - if (!THEMES.hasOwnProperty(correctedTheme)) { + if (THEMES.indexOf(correctedTheme) < 0) { correctedTheme = DEFAULT_THEME } diff --git a/app/javascript/gabsocial/containers/status_container.js b/app/javascript/gabsocial/containers/status_container.js index 71abac2c..26641206 100644 --- a/app/javascript/gabsocial/containers/status_container.js +++ b/app/javascript/gabsocial/containers/status_container.js @@ -56,7 +56,7 @@ const makeMapStateToProps = () => { const ids = [status.get('id')] const r = state.getIn(['contexts', 'replies', ids[0]]) - console.log("r:", r) + // console.log("r:", r) while (ids.length > 0) { let id = ids.shift() @@ -253,6 +253,15 @@ const mapDispatchToProps = (dispatch) => ({ onFetchComments(statusId) { dispatch(fetchComments(statusId)) }, + + onOpenLikes(status) { + dispatch(openModal('STATUS_LIKES', { status })) + }, + + onOpenReposts(status) { + dispatch(openModal('STATUS_REPOSTS', { status })) + }, + }); export default connect(makeMapStateToProps, mapDispatchToProps)(Status); diff --git a/app/javascript/gabsocial/features/compose/compose.js b/app/javascript/gabsocial/features/compose/compose.js index c445b4d4..daaa7677 100644 --- a/app/javascript/gabsocial/features/compose/compose.js +++ b/app/javascript/gabsocial/features/compose/compose.js @@ -17,7 +17,7 @@ const messages = defineMessages({ home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' }, notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' }, public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' }, - community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Community timeline' }, + community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Community feed' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new gab' }, diff --git a/app/javascript/gabsocial/features/follow_requests/components/account_authorize/account_authorize.js b/app/javascript/gabsocial/features/follow_requests/components/account_authorize/account_authorize.js index e1b17d88..f06422af 100644 --- a/app/javascript/gabsocial/features/follow_requests/components/account_authorize/account_authorize.js +++ b/app/javascript/gabsocial/features/follow_requests/components/account_authorize/account_authorize.js @@ -12,15 +12,9 @@ const messages = defineMessages({ reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }, }); -const makeMapStateToProps = () => { - const getAccount = makeGetAccount(); - - const mapStateToProps = (state, props) => ({ - account: getAccount(state, props.id), - }); - - return mapStateToProps; -}; +const makeMapStateToProps = () => ({ + account: makeGetAccount()(state, props.id), +}) const mapDispatchToProps = (dispatch, { id }) => ({ onAuthorize() { diff --git a/app/javascript/gabsocial/features/list_create-old/components/list/index.js b/app/javascript/gabsocial/features/list_create-old/components/list/index.js deleted file mode 100644 index 9001c3df..00000000 --- a/app/javascript/gabsocial/features/list_create-old/components/list/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './list' \ No newline at end of file diff --git a/app/javascript/gabsocial/features/list_create-old/components/list/list.js b/app/javascript/gabsocial/features/list_create-old/components/list/list.js deleted file mode 100644 index aedee0e3..00000000 --- a/app/javascript/gabsocial/features/list_create-old/components/list/list.js +++ /dev/null @@ -1,66 +0,0 @@ -import { defineMessages, injectIntl } from 'react-intl'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { removeFromListAdder, addToListAdder } from '../../../../actions/lists'; -import Button from '../../../../components/button'; -import Icon from '../../../../components/icon'; - -const messages = defineMessages({ - remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' }, - add: { id: 'lists.account.add', defaultMessage: 'Add to list' }, -}); - -const MapStateToProps = (state, { listId, added }) => ({ - list: state.get('lists').get(listId), - added: typeof added === 'undefined' ? state.getIn(['listAdder', 'lists', 'items']).includes(listId) : added, -}); - -const mapDispatchToProps = (dispatch, { listId }) => ({ - onRemove: () => dispatch(removeFromListAdder(listId)), - onAdd: () => dispatch(addToListAdder(listId)), -}); - -// : todo : - -export default -@connect(MapStateToProps, mapDispatchToProps) -@injectIntl -class List extends ImmutablePureComponent { - - static propTypes = { - list: ImmutablePropTypes.map.isRequired, - intl: PropTypes.object.isRequired, - onRemove: PropTypes.func.isRequired, - onAdd: PropTypes.func.isRequired, - added: PropTypes.bool, - }; - - static defaultProps = { - added: false, - }; - - render () { - const { list, intl, onRemove, onAdd, added } = this.props; - - return ( -
-
-
- - {list.get('title')} -
- -
- { - added ? -
-
-
- ); - } - -} diff --git a/app/javascript/gabsocial/features/list_create-old/components/list/list.scss b/app/javascript/gabsocial/features/list_create-old/components/list/list.scss deleted file mode 100644 index b78d3b89..00000000 --- a/app/javascript/gabsocial/features/list_create-old/components/list/list.scss +++ /dev/null @@ -1,31 +0,0 @@ -.list { - padding: 4px; - border-bottom: 1px solid lighten($ui-base-color, 8%); - - &__wrapper { - display: flex; - - .account__relationship { - padding: 8px 5px 0 5px; - } - } - - &__name { - flex: 1 1 auto; - overflow: hidden; - text-decoration: none; - font-size: 16px; - padding: 10px; - } - - &__name-icon { - display: inline-block; - margin-right: 5px; - } - - &__btn-block { - height: auto; - position: relative; - padding: 0 0 0 5px; - } -} \ No newline at end of file diff --git a/app/javascript/gabsocial/features/list_create-old/index.js b/app/javascript/gabsocial/features/list_create-old/index.js deleted file mode 100644 index 37516fe2..00000000 --- a/app/javascript/gabsocial/features/list_create-old/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './list_adder' \ No newline at end of file diff --git a/app/javascript/gabsocial/features/list_create-old/list_adder.js b/app/javascript/gabsocial/features/list_create-old/list_adder.js deleted file mode 100644 index e8861e34..00000000 --- a/app/javascript/gabsocial/features/list_create-old/list_adder.js +++ /dev/null @@ -1,90 +0,0 @@ -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl } from 'react-intl'; -import { getOrderedLists } from '../../selectors' -import { setupListAdder, resetListAdder } from '../../actions/lists'; -import List from './components/list'; -import Account from '../../components/account'; -import Button from '../../components/button'; -// import NewListForm from '../lists_directory/components/new_list_form'; - -const mapStateToProps = (state, { accountId }) => ({ - listIds: getOrderedLists(state).map(list => list.get('id')), - account: state.getIn(['accounts', accountId]), -}); - -const mapDispatchToProps = (dispatch) => ({ - onInitialize: accountId => dispatch(setupListAdder(accountId)), - onReset: () => dispatch(resetListAdder()), -}); - -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, - subheading: { id: 'lists.subheading', defaultMessage: 'Your lists' }, - add: { id: 'lists.new.create', defaultMessage: 'Add List' }, - headerTitle: { id: 'list_adder.header_title', defaultMessage: 'Add or Remove from Lists' }, -}); - -export default -@connect(mapStateToProps, mapDispatchToProps) -@injectIntl -class ListAdder extends ImmutablePureComponent { - - static propTypes = { - accountId: PropTypes.string.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - onInitialize: PropTypes.func.isRequired, - onReset: PropTypes.func.isRequired, - listIds: ImmutablePropTypes.list.isRequired, - account: ImmutablePropTypes.map.isRequired, - }; - - componentDidMount() { - const { onInitialize, accountId } = this.props; - onInitialize(accountId); - } - - componentWillUnmount() { - this.props.onReset(); - } - - onClickClose = () => { - this.props.onClose('LIST_ADDER'); - }; - - render() { - const { listIds, intl, account } = this.props; - - return ( -
-
-

- {intl.formatMessage(messages.headerTitle)} -

-
-
-
-
- -
- -
- - { /* */ } - -
- -
- { - listIds.map(ListId => ) - } -
-
-
-
- ); - } - -} diff --git a/app/javascript/gabsocial/features/list_edit.js b/app/javascript/gabsocial/features/list_edit.js new file mode 100644 index 00000000..83dabde2 --- /dev/null +++ b/app/javascript/gabsocial/features/list_edit.js @@ -0,0 +1,316 @@ +import ImmutablePropTypes from 'react-immutable-proptypes' +import ImmutablePureComponent from 'react-immutable-pure-component' +import { injectIntl, defineMessages } from 'react-intl' +import isObject from 'lodash.isobject' +import { + setupListEditor, + resetListEditor, + removeFromListEditor, + addToListEditor, + fetchListSuggestions, + clearListSuggestions, + changeListSuggestions, +} from '../actions/lists' +import { openModal } from '../actions/modal' +import { + MODAL_LIST_EDITOR, + MODAL_LIST_DELETE, +} from '../constants' +import Account from '../components/account' +import Button from '../components/button' +import Divider from '../components/divider' +import Input from '../components/input' +import TabBar from '../components/tab_bar' +import Text from '../components/text' + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, + save: { id: 'lists.new.save_title', defaultMessage: 'Save Title' }, + changeTitle: { id: 'lists.edit.submit', defaultMessage: 'Change title' }, + addToList: { id: 'lists.account.add', defaultMessage: 'Add to list' }, + removeFromList: { id: 'lists.account.remove', defaultMessage: 'Remove from list' }, + editList: { id: 'lists.edit', defaultMessage: 'Edit list' }, + editListTitle: { id: 'lists.new.edit_title_placeholder', defaultMessage: 'Edit list title' }, + remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' }, + add: { id: 'lists.account.add', defaultMessage: 'Add to list' }, + search: { id: 'lists.search', defaultMessage: 'Search people...' }, + searchMembers: { id: 'lists.search_members', defaultMessage: 'Search members...' }, + searchTitle: { id: 'tabs_bar.search', defaultMessage: 'Search' }, +}) + +const mapStateToProps = (state, { params, id }) => { + const listId = isObject(params) ? params['id'] : id + + return { + listId, + list: state.getIn(['lists', listId]), + title: state.getIn(['listEditor', 'title']), + disabled: !state.getIn(['listEditor', 'isChanged']), + accountIds: state.getIn(['listEditor', 'accounts', 'items']), + searchAccountIds: state.getIn(['listEditor', 'suggestions', 'items']), + searchSuggestionsValue: state.getIn(['listEditor', 'suggestions', 'value']), + } +} + +const mapDispatchToProps = (dispatch) => ({ + + onDeleteList(list) { + dispatch(openModal(MODAL_LIST_DELETE, { list })) + }, + + onChangeTitle(value) { + dispatch(changeListEditorTitle(value)) + }, + + onUpdateList() { + dispatch(submitListEditor(false)) + }, + + onInitialize(listId) { + dispatch(setupListEditor(listId)) + }, + + onReset() { + dispatch(resetListEditor()) + }, + + onRemoveAccountFromList(accountId) { + dispatch(removeFromListEditor(accountId)) + }, + + onAddAccountToList(accountId) { + dispatch(addToListEditor(accountId)) + }, + + onSubmitSearchSuggestions(value) { + dispatch(fetchListSuggestions(value)) + }, + + onClearSearchSuggestions() { + dispatch(clearListSuggestions()) + }, + + onChangeSuggestions(value) { + dispatch(changeListSuggestions(value)) + }, + +}) + +export default +@connect(mapStateToProps, mapDispatchToProps) +@injectIntl +class ListEdit extends ImmutablePureComponent { + + static propTypes = { + list: ImmutablePropTypes.map, + title: PropTypes.string, + listId: PropTypes.string.isRequired, + onClose: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + onInitialize: PropTypes.func.isRequired, + onReset: PropTypes.func.isRequired, + searchSuggestionsValue: PropTypes.string.isRequired, + accountIds: ImmutablePropTypes.list.isRequired, + searchAccountIds: ImmutablePropTypes.list.isRequired, + onRemoveAccountFromList: PropTypes.func.isRequired, + onAddAccountToList: PropTypes.func.isRequired, + onChangeSuggestions: PropTypes.func.isRequired, + onClearSearchSuggestions: PropTypes.func.isRequired, + onSubmitSearchSuggestions: PropTypes.func.isRequired, + onDeleteList: PropTypes.func.isRequired, + tab: PropTypes.string, + } + + state = { + activeTab: this.props.tab || 'members' + } + + componentDidMount() { + const { onInitialize, listId } = this.props + if (listId) { + onInitialize(listId) + } + } + + componentDidUpdate(prevProps) { + if (this.props.listId !== prevProps.listId) { + this.props.onInitialize(this.props.listId) + } + } + + componentWillUnmount() { + this.props.onReset() + } + + handleChangeTab = (tab) => { + this.setState({ activeTab: tab }) + } + + onClickClose = () => { + this.props.onClose(MODAL_LIST_EDITOR) + } + + handleOnDeleteList = () => { + this.props.onDeleteList(this.props.list) + } + + handleAddOrRemoveFromList = (accountId) => { + if (this.props.accountIds.includes(accountId)) { + this.props.onRemoveAccountFromList(accountId) + } else { + this.props.onAddAccountToList(accountId) + } + } + + handleSearchSuggestionsChange = (value) => { + this.props.onChangeSuggestions(value) + } + + handleSearchSuggestionsKeyUp = (e) => { + if (e.keyCode === 13) { + this.props.onSubmitSearchSuggestions(this.props.searchSuggestionsValue) + } + } + + handleSearchSuggestionsSubmit = () => { + this.props.onSubmitSearchSuggestions(this.props.searchSuggestionsValue) + } + + render() { + const { + title, + accountIds, + searchAccountIds, + intl, + searchSuggestionsValue, + } = this.props + const { activeTab } = this.state + + // : todo : save new list title + + return ( +
+
+
+ this.handleChangeTab('members'), + active: activeTab === 'members', + }, + { + title: 'Add new', + onClick: () => this.handleChangeTab('add-new'), + active: activeTab === 'add-new', + }, + { + title: 'Settings', + onClick: () => this.handleChangeTab('settings'), + active: activeTab === 'settings', + }, + ]} + /> +
+ + { + activeTab === 'members' && +
+
+
+ + Total members ({accountIds.size}) + + { + accountIds && + accountIds.map((accountId) => ( + this.handleAddOrRemoveFromList(accountId)} + actionIcon={'subtract'} + /> + )) + } +
+
+
+ } + + { + activeTab === 'settings' && +
+
+ +
+ +
+ +
+ + Once you delete a list you cannot retrieve it. + +
+ } + + { + activeTab === 'add-new' && +
+
+ +
+ +
+
+ + Search results ({searchAccountIds.size}) + + { + searchAccountIds && + searchAccountIds.map((accountId) => { + if (accountIds.includes(accountId)) return null + return ( + this.handleAddOrRemoveFromList(accountId)} + actionIcon='add' + /> + ) + }) + } +
+
+
+ } + +
+
+ ) + + } + +} diff --git a/app/javascript/gabsocial/features/list_edit/components/account.js b/app/javascript/gabsocial/features/list_edit/components/account.js deleted file mode 100644 index 7bd012c6..00000000 --- a/app/javascript/gabsocial/features/list_edit/components/account.js +++ /dev/null @@ -1,78 +0,0 @@ - -import { defineMessages, injectIntl } from 'react-intl'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { removeFromListEditor, addToListEditor } from '../../../actions/lists'; -import { makeGetAccount } from '../../../selectors'; -import Avatar from '../../../components/avatar'; -import DisplayName from '../../../components/display_name'; -import Button from '../../../components/button'; - -const messages = defineMessages({ - remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' }, - add: { id: 'lists.account.add', defaultMessage: 'Add to list' }, -}); - -const makeMapStateToProps = () => { - const getAccount = makeGetAccount(); - - const mapStateToProps = (state, { accountId, added }) => ({ - account: getAccount(state, accountId), - added: typeof added === 'undefined' ? state.getIn(['listEditor', 'accounts', 'items']).includes(accountId) : added, - }); - - return mapStateToProps; -}; - -const mapDispatchToProps = (dispatch, { accountId }) => ({ - onRemove: () => dispatch(removeFromListEditor(accountId)), - onAdd: () => dispatch(addToListEditor(accountId)), -}); - -export default -@connect(makeMapStateToProps, mapDispatchToProps) -@injectIntl -class Account extends ImmutablePureComponent { - - static propTypes = { - account: ImmutablePropTypes.map.isRequired, - intl: PropTypes.object.isRequired, - onRemove: PropTypes.func.isRequired, - onAdd: PropTypes.func.isRequired, - added: PropTypes.bool, - }; - - static defaultProps = { - added: false, - }; - - render () { - const { account, intl, onRemove, onAdd, added } = this.props; - - let button; - - if (added) { - button =
-
-
- -
- - { - accountIds.size > 0 && -
-
- {accountIds.map(accountId => )} -
-
- } - -
- -
- {searchAccountIds.map(accountId => )} -
-
-
- - - ) - - } - -} diff --git a/app/javascript/gabsocial/features/list_timeline.js b/app/javascript/gabsocial/features/list_timeline.js index e9e51aaf..9653afea 100644 --- a/app/javascript/gabsocial/features/list_timeline.js +++ b/app/javascript/gabsocial/features/list_timeline.js @@ -71,7 +71,8 @@ class ListTimeline extends ImmutablePureComponent { } handleEditClick = () => { - this.props.dispatch(openModal('LIST_EDITOR', { listId: this.props.params.id })) + console.log("handleEditClick:", this.props.params.id) + this.props.dispatch(openModal('LIST_EDITOR', { id: this.props.params.id })) } render() { @@ -86,20 +87,22 @@ class ListTimeline extends ImmutablePureComponent { } const emptyMessage = ( -
+
- +
+ +
) diff --git a/app/javascript/gabsocial/features/status.js b/app/javascript/gabsocial/features/status.js index c149ccb8..3dbcadb9 100644 --- a/app/javascript/gabsocial/features/status.js +++ b/app/javascript/gabsocial/features/status.js @@ -1,7 +1,50 @@ +import ImmutablePropTypes from 'react-immutable-proptypes' +import ImmutablePureComponent from 'react-immutable-pure-component' +import { fetchStatus } from '../actions/statuses' import StatusContainer from '../containers/status_container' +import ColumnIndicator from '../components/column_indicator' + +const mapStateToProps = (state, props) => { + const statusId = props.id || props.params.statusId + + return { + status: state.getIn(['statuses', statusId]), + } +} + +const mapDispatchToProps = (dispatch) => ({ + onFetchStatus: (id) => dispatch(fetchStatus(id)), +}) + +export default +@connect(mapStateToProps, mapDispatchToProps) +class Status extends ImmutablePureComponent { + + static propTypes = { + onFetchStatus: PropTypes.func.isRequired, + params: PropTypes.object, + status: ImmutablePropTypes.map, + } + + updateOnProps = [ + 'params', + 'status', + ] + + componentDidMount() { + const statusId = this.props.id || this.props.params.statusId + this.props.onFetchStatus(statusId) + } -export default class Status extends PureComponent { render() { + const { status } = this.props + + // - if comment render as such + + if (!status) { + return + } + return ( ) diff --git a/app/javascript/gabsocial/features/status_likes.js b/app/javascript/gabsocial/features/status_likes.js index c45efb4d..21e36c37 100644 --- a/app/javascript/gabsocial/features/status_likes.js +++ b/app/javascript/gabsocial/features/status_likes.js @@ -1,72 +1,70 @@ -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl' import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePropTypes from 'react-immutable-proptypes' -import ColumnIndicator from '../components/column_indicator' +import { FormattedMessage } from 'react-intl' import { fetchLikes } from '../actions/interactions' +import { fetchStatus } from '../actions/statuses' +import { makeGetStatus } from '../selectors' import Account from '../components/account' +import ColumnIndicator from '../components/column_indicator' import ScrollableList from '../components/scrollable_list' -const messages = defineMessages({ - refresh: { id: 'refresh', defaultMessage: 'Refresh' }, -}); +const mapStateToProps = (state, props) => { + const getStatus = makeGetStatus() + const status = getStatus(state, { + id: props.params.statusId, + username: props.params.username, + }) -const mapStateToProps = (state, props) => ({ - accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]), -}); + return { + status, + accountIds: state.getIn(['user_lists', 'liked_by', props.params.statusId]), + } +} export default -@injectIntl @connect(mapStateToProps) -class StatusLikes extends ImmutablePureComponent { +class StatusReposts extends ImmutablePureComponent { static propTypes = { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, - shouldUpdateScroll: PropTypes.func, accountIds: ImmutablePropTypes.list, - multiColumn: PropTypes.bool, - intl: PropTypes.object.isRequired, - }; + status: ImmutablePropTypes.map, + } componentWillMount () { - if (!this.props.accountIds) { - this.props.dispatch(fetchLikes(this.props.params.statusId)); - } + this.props.dispatch(fetchLikes(this.props.params.statusId)) + this.props.dispatch(fetchStatus(this.props.params.statusId)) } - componentWillReceiveProps (nextProps) { + componentWillReceiveProps(nextProps) { if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { - this.props.dispatch(fetchLikes(nextProps.params.statusId)); + this.props.dispatch(fetchLikes(nextProps.params.statusId)) + this.props.dispatch(fetchStatus(nextProps.params.statusId)) } } - handleRefresh = () => { - this.props.dispatch(fetchLikes(this.props.params.statusId)); - } - render () { - const { intl, shouldUpdateScroll, accountIds, multiColumn } = this.props; + const { accountIds, status } = this.props if (!accountIds) { return + } else if (!status) { + return } - const emptyMessage = ; - return ( -
- - {accountIds.map(id => - , - )} - -
- ); + } + > + { + accountIds.map(id => + + ) + } + + ) } -} \ No newline at end of file +} diff --git a/app/javascript/gabsocial/features/ui/ui.js b/app/javascript/gabsocial/features/ui/ui.js index 7632894b..38f5bd44 100644 --- a/app/javascript/gabsocial/features/ui/ui.js +++ b/app/javascript/gabsocial/features/ui/ui.js @@ -145,7 +145,7 @@ class SwitchingArea extends PureComponent { - + diff --git a/app/javascript/gabsocial/features/ui/util/async_components.js b/app/javascript/gabsocial/features/ui/util/async_components.js index bf457efb..d5cfe770 100644 --- a/app/javascript/gabsocial/features/ui/util/async_components.js +++ b/app/javascript/gabsocial/features/ui/util/async_components.js @@ -65,6 +65,8 @@ export function SidebarMorePopover() { return import(/* webpackChunkName: "compo export function StatusLikes() { return import(/* webpackChunkName: "features/status_likes" */'../../status_likes') } export function StatusOptionsPopover() { return import(/* webpackChunkName: "components/status_options_popover" */'../../../components/popover/status_options_popover') } export function StatusReposts() { return import(/* webpackChunkName: "features/status_reposts" */'../../status_reposts') } +export function StatusLikesModal() { return import(/* webpackChunkName: "modals/status_likes_modal" */'../../../components/modal/status_likes_modal') } +export function StatusRepostsModal() { return import(/* webpackChunkName: "modals/status_reposts_modal" */'../../../components/modal/status_reposts_modal') } export function StatusRevisionsModal() { return import(/* webpackChunkName: "modals/status_revisions_modal" */'../../../components/modal/status_revisions_modal') } export function StatusSharePopover() { return import(/* webpackChunkName: "components/status_share_popover" */'../../../components/popover/status_share_popover') } export function StatusVisibilityPopover() { return import(/* webpackChunkName: "components/status_visibility_popover" */'../../../components/popover/status_visibility_popover') } diff --git a/app/javascript/gabsocial/layouts/default_layout.js b/app/javascript/gabsocial/layouts/default_layout.js index 949c7af3..72d1b962 100644 --- a/app/javascript/gabsocial/layouts/default_layout.js +++ b/app/javascript/gabsocial/layouts/default_layout.js @@ -1,32 +1,33 @@ import Layout from './layout' export default class DefaultLayout extends PureComponent { + static propTypes = { actions: PropTypes.array, - tabs: PropTypes.array, + children: PropTypes.node.isRequired, layout: PropTypes.object, showBackBtn: PropTypes.bool, + tabs: PropTypes.array, title: PropTypes.string.isRequired, - children: PropTypes.node.isRequired, } render() { const { - children, - title, - showBackBtn, - layout, actions, + children, + layout, + showBackBtn, tabs, - } = this.props + title, + } = this.props return ( {children} diff --git a/app/javascript/gabsocial/layouts/group_layout.js b/app/javascript/gabsocial/layouts/group_layout.js index d6195063..7d52e133 100644 --- a/app/javascript/gabsocial/layouts/group_layout.js +++ b/app/javascript/gabsocial/layouts/group_layout.js @@ -5,32 +5,34 @@ import Layout from './layout' import GroupHeader from '../components/group_header' export default class GroupLayout extends ImmutablePureComponent { + static propTypes = { actions: PropTypes.array, + children: PropTypes.node, group: ImmutablePropTypes.map, - relationships: ImmutablePropTypes.map, layout: PropTypes.object, + relationships: ImmutablePropTypes.map, showBackBtn: PropTypes.bool, + title: PropTypes.string, } render() { const { - group, - children, - layout, - showBackBtn, actions, + children, + group, + layout, relationships, + showBackBtn, + title, } = this.props - const title = !!group ? group.get('title') : undefined - return (
diff --git a/app/javascript/gabsocial/layouts/layout.js b/app/javascript/gabsocial/layouts/layout.js index 8ba86ed5..c5a8623b 100644 --- a/app/javascript/gabsocial/layouts/layout.js +++ b/app/javascript/gabsocial/layouts/layout.js @@ -1,52 +1,58 @@ import Sticky from 'react-stickynode' -import Search from '../components/search' -import ColumnHeader from '../components/column_header' import Sidebar from '../components/sidebar' import { BREAKPOINT_EXTRA_SMALL } from '../constants' import NavigationBar from '../components/navigation_bar' +// : todo : // import Footer from '../components/footer' import FloatingActionButton from '../components/floating_action_button' import Responsive from '../features/ui/util/responsive_component' export default class Layout extends PureComponent { + static propTypes = { actions: PropTypes.array, - tabs: PropTypes.array, + children: PropTypes.node, layout: PropTypes.object, - title: PropTypes.string, - showBackBtn: PropTypes.bool, - noSidebar: PropTypes.bool, - noRightSidebar: PropTypes.bool, noComposeButton: PropTypes.bool, + noRightSidebar: PropTypes.bool, + noSidebar: PropTypes.bool, + showBackBtn: PropTypes.bool, + tabs: PropTypes.array, + title: PropTypes.string, } render() { const { - children, - title, - showBackBtn, - layout, actions, - tabs, - noSidebar, - noRightSidebar, + children, + layout, noComposeButton, + noRightSidebar, + noSidebar, + showBackBtn, + tabs, + title, } = this.props return (
{ !noSidebar && - + } diff --git a/app/javascript/gabsocial/layouts/profile_layout.js b/app/javascript/gabsocial/layouts/profile_layout.js index d6b4e4bd..9f5c3fb7 100644 --- a/app/javascript/gabsocial/layouts/profile_layout.js +++ b/app/javascript/gabsocial/layouts/profile_layout.js @@ -1,17 +1,16 @@ import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePureComponent from 'react-immutable-pure-component' import Sticky from 'react-stickynode' -import ProfileHeader from '../components/profile_header' import NavigationBar from '../components/navigation_bar' +import ProfileHeader from '../components/profile_header' export default class ProfileLayout extends ImmutablePureComponent { static propTypes = { - children: PropTypes.node.isRequired, account: ImmutablePropTypes.map, + children: PropTypes.node.isRequired, layout: PropTypes.object, title: PropTypes.string, - showBackBtn: PropTypes.bool, } render() { @@ -20,7 +19,6 @@ export default class ProfileLayout extends ImmutablePureComponent { children, layout, title, - showBackBtn, } = this.props return ( diff --git a/app/javascript/gabsocial/locales/bg.json b/app/javascript/gabsocial/locales/bg.json index 52b28970..9d830e29 100644 --- a/app/javascript/gabsocial/locales/bg.json +++ b/app/javascript/gabsocial/locales/bg.json @@ -45,7 +45,7 @@ "bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.retry": "Try again", "column.blocks": "Blocked users", - "column.community": "Community timeline", + "column.community": "Community feed", "column.direct": "Direct messages", "column.domain_blocks": "Blocked domains", "column.favorites": "Favorites", @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Зареждане...", "media_gallery.toggle_visible": "Hide media", @@ -228,7 +228,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/locales/defaultMessages.json b/app/javascript/gabsocial/locales/defaultMessages.json index 4776766e..8a9ce6a7 100644 --- a/app/javascript/gabsocial/locales/defaultMessages.json +++ b/app/javascript/gabsocial/locales/defaultMessages.json @@ -1688,7 +1688,7 @@ { "descriptors": [ { - "defaultMessage": "Search among people you follow", + "defaultMessage": "Search people...", "id": "lists.search" } ], diff --git a/app/javascript/gabsocial/locales/en.json b/app/javascript/gabsocial/locales/en.json index e45d895f..d34bdc46 100644 --- a/app/javascript/gabsocial/locales/en.json +++ b/app/javascript/gabsocial/locales/en.json @@ -45,7 +45,7 @@ "bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.retry": "Try again", "column.blocks": "Blocked users", - "column.community": "Community timeline", + "column.community": "Community feed", "column.direct": "Direct messages", "column.domain_blocks": "Blocked domains", "column.favorites": "Favorites", @@ -221,7 +221,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Loading...", "media_gallery.toggle_visible": "Hide media", @@ -230,7 +230,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new gab", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/locales/he.json b/app/javascript/gabsocial/locales/he.json index 742a591c..e0e3eeee 100644 --- a/app/javascript/gabsocial/locales/he.json +++ b/app/javascript/gabsocial/locales/he.json @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "טוען...", "media_gallery.toggle_visible": "נראה\\בלתי נראה", diff --git a/app/javascript/gabsocial/locales/hi.json b/app/javascript/gabsocial/locales/hi.json index c4493f7a..9b85936c 100644 --- a/app/javascript/gabsocial/locales/hi.json +++ b/app/javascript/gabsocial/locales/hi.json @@ -45,7 +45,7 @@ "bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.retry": "Try again", "column.blocks": "Blocked users", - "column.community": "Community timeline", + "column.community": "Community feed", "column.direct": "Direct messages", "column.domain_blocks": "Blocked domains", "column.favorites": "Favorites", @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Loading...", "media_gallery.toggle_visible": "Hide media", @@ -228,7 +228,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/locales/hr.json b/app/javascript/gabsocial/locales/hr.json index 0ca88f55..c5846869 100644 --- a/app/javascript/gabsocial/locales/hr.json +++ b/app/javascript/gabsocial/locales/hr.json @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Učitavam...", "media_gallery.toggle_visible": "Preklopi vidljivost", diff --git a/app/javascript/gabsocial/locales/id.json b/app/javascript/gabsocial/locales/id.json index ae863e8f..6e04e910 100644 --- a/app/javascript/gabsocial/locales/id.json +++ b/app/javascript/gabsocial/locales/id.json @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Tunggu sebentar...", "media_gallery.toggle_visible": "Tampil/Sembunyikan", diff --git a/app/javascript/gabsocial/locales/io.json b/app/javascript/gabsocial/locales/io.json index 7f590c76..5e576b29 100644 --- a/app/javascript/gabsocial/locales/io.json +++ b/app/javascript/gabsocial/locales/io.json @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Kargante...", "media_gallery.toggle_visible": "Chanjar videbleso", diff --git a/app/javascript/gabsocial/locales/lv.json b/app/javascript/gabsocial/locales/lv.json index beee5e96..85df0021 100644 --- a/app/javascript/gabsocial/locales/lv.json +++ b/app/javascript/gabsocial/locales/lv.json @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Loading...", "media_gallery.toggle_visible": "Hide media", @@ -228,7 +228,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/locales/ms.json b/app/javascript/gabsocial/locales/ms.json index ed05208c..05e69d41 100644 --- a/app/javascript/gabsocial/locales/ms.json +++ b/app/javascript/gabsocial/locales/ms.json @@ -45,7 +45,7 @@ "bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.retry": "Try again", "column.blocks": "Blocked users", - "column.community": "Community timeline", + "column.community": "Community feed", "column.direct": "Direct messages", "column.domain_blocks": "Blocked domains", "column.favorites": "Favorites", @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Loading...", "media_gallery.toggle_visible": "Hide media", @@ -228,7 +228,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/locales/sl.json b/app/javascript/gabsocial/locales/sl.json index e33efb2e..13e0c5bd 100644 --- a/app/javascript/gabsocial/locales/sl.json +++ b/app/javascript/gabsocial/locales/sl.json @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Loading...", "media_gallery.toggle_visible": "Hide media", @@ -228,7 +228,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/locales/ta.json b/app/javascript/gabsocial/locales/ta.json index 7825081b..107102a5 100644 --- a/app/javascript/gabsocial/locales/ta.json +++ b/app/javascript/gabsocial/locales/ta.json @@ -45,7 +45,7 @@ "bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.retry": "Try again", "column.blocks": "Blocked users", - "column.community": "Community timeline", + "column.community": "Community feed", "column.direct": "Direct messages", "column.domain_blocks": "Blocked domains", "column.favorites": "Favorites", @@ -219,7 +219,7 @@ "lists.edit.submit": "Change title", "lists.new.create": "Add list", "lists.new.title_placeholder": "New list title", - "lists.search": "Search among people you follow", + "lists.search": "Search people...", "lists.subheading": "Your lists", "loading_indicator.label": "Loading...", "media_gallery.toggle_visible": "Hide media", @@ -228,7 +228,7 @@ "mute_modal.hide_notifications": "Hide notifications from this user?", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "Blocked users", - "navigation_bar.community_timeline": "Community timeline", + "navigation_bar.community_timeline": "Community feed", "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", diff --git a/app/javascript/gabsocial/pages/basic_page.js b/app/javascript/gabsocial/pages/basic_page.js index af647f44..bb98dff5 100644 --- a/app/javascript/gabsocial/pages/basic_page.js +++ b/app/javascript/gabsocial/pages/basic_page.js @@ -1,11 +1,12 @@ import { Fragment } from 'react' import PageTitle from '../features/ui/util/page_title' -import LinkFooter from '../components/link_footer' -import WhoToFollowPanel from '../components/panel/who_to_follow_panel' -import TrendsPanel from '../components/panel/trends_panel' import DefaultLayout from '../layouts/default_layout' +import LinkFooter from '../components/link_footer' +import TrendsPanel from '../components/panel/trends_panel' +import WhoToFollowPanel from '../components/panel/who_to_follow_panel' export default class BasicPage extends PureComponent { + static propTypes = { title: PropTypes.string.isRequired, children: PropTypes.node.isRequired, @@ -31,4 +32,5 @@ export default class BasicPage extends PureComponent { ) } + } \ No newline at end of file diff --git a/app/javascript/gabsocial/pages/community_page.js b/app/javascript/gabsocial/pages/community_page.js index 9dadd2c9..b11bfa13 100644 --- a/app/javascript/gabsocial/pages/community_page.js +++ b/app/javascript/gabsocial/pages/community_page.js @@ -12,7 +12,7 @@ import TimelineComposeBlock from '../components/timeline_compose_block' import Divider from '../components/divider' const messages = defineMessages({ - community: { 'id': 'column.community', 'defaultMessage': 'Community timeline' }, + community: { 'id': 'column.community', 'defaultMessage': 'Community feed' }, }) const mapDispatchToProps = (dispatch) => ({ diff --git a/app/javascript/gabsocial/pages/group_page.js b/app/javascript/gabsocial/pages/group_page.js index 417bd762..f5e296a7 100644 --- a/app/javascript/gabsocial/pages/group_page.js +++ b/app/javascript/gabsocial/pages/group_page.js @@ -50,36 +50,12 @@ class GroupPage extends ImmutablePureComponent { relationships, } = this.props - //
- //

- // - // {intl.formatMessage(messages.tabLatest)} - // - - //
- // - //
- //

- // {!collapsed &&
- //
- //
- // - //
- //
- //
} - //
- const groupTitle = !!group ? group.get('title') : '' return ( ({ const mapDispatchToProps = (dispatch) => ({ onOpenHomePageSettingsModal() { - dispatch(openModal('HOME_TIMELINE_SETTINGS')) + dispatch(openModal(MODAL_HOME_TIMELINE_SETTINGS)) }, }) @@ -35,10 +36,10 @@ export default class HomePage extends PureComponent { static propTypes = { - intl: PropTypes.object.isRequired, children: PropTypes.node.isRequired, - totalQueuedItemsCount: PropTypes.number.isRequired, + intl: PropTypes.object.isRequired, onOpenHomePageSettingsModal: PropTypes.func.isRequired, + totalQueuedItemsCount: PropTypes.number.isRequired, } intersectionObserverWrapper = new IntersectionObserverWrapper() @@ -59,7 +60,6 @@ class HomePage extends PureComponent { this.intersectionObserverWrapper.disconnect() } - render() { const { intl, @@ -110,13 +110,18 @@ class HomePage extends PureComponent { )} > + + + + {children} + ) } diff --git a/app/javascript/gabsocial/pages/list_page.js b/app/javascript/gabsocial/pages/list_page.js index 80ad0d27..becfd2f4 100644 --- a/app/javascript/gabsocial/pages/list_page.js +++ b/app/javascript/gabsocial/pages/list_page.js @@ -26,7 +26,7 @@ const mapDispatchToProps = (dispatch) => ({ onOpenListEditModal(list) { if (!list) return const listId = list.get('id') - dispatch(openModal(MODAL_LIST_EDITOR, { listId })) + dispatch(openModal(MODAL_LIST_EDITOR, { id: listId })) }, // : todo : // onOpenListTimelineSettingsModal() { @@ -65,7 +65,7 @@ class ListPage extends ImmutablePureComponent { return ( item.id))); + case LIKES_FETCH_SUCCESS: + return state.setIn(['liked_by', action.id], ImmutableList(action.accounts.map(item => item.id))); case FOLLOW_REQUESTS_FETCH_SUCCESS: return state.setIn(['follow_requests', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next).setIn(['follow_requests', 'isLoading'], false); case FOLLOW_REQUESTS_EXPAND_SUCCESS: diff --git a/app/javascript/styles/global.css b/app/javascript/styles/global.css index ac8d2665..da048cb5 100644 --- a/app/javascript/styles/global.css +++ b/app/javascript/styles/global.css @@ -12,6 +12,9 @@ --color_red: #de2960; --color_red-dark: #c72c5b; + --radius-small: 8px; + --radius-circle: 9999px; + --fs_xs: 0.8571428571rem; --fs_s: 0.9285714286rem; --fs_n: 1rem; @@ -19,19 +22,8 @@ --fs_l: 1.1428571429rem; --fs_xl: 1.3571428571rem; --fs_xxl: 1.7142857143rem; -} -:root { - --radius-small: 0; - --radius-circle: 0; -} - -:root[rounded] { - --radius-small: 8px; - --radius-circle: 9999px; -} - -:root[theme='light'] { + /* Default light theme */ --solid_color_primary: #fff; --solid_color_primary-opaque:rgba(255, 255, 255,.6); --solid_color_secondary: #e2e8ec; @@ -46,34 +38,42 @@ --border_color_secondary: #ececed; } +:root[no-circle] { + --radius-circle: 0 !important; +} + +:root[no-radius] { + --radius-small: 0 !important; +} + :root[theme='muted'] { - --solid_color_primary: #222; - --solid_color_primary-opaque:rgba(34, 34, 34, .6); - --solid_color_secondary: #4f5050; - --solid_color_secondary-dark: #424343; - --solid_color_tertiary: #333; - --solid_color_block: #2d2d2d; + --solid_color_primary: #222 !important; + --solid_color_primary-opaque:rgba(34, 34, 34, .6) !important; + --solid_color_secondary: #4f5050 !important; + --solid_color_secondary-dark: #424343 !important; + --solid_color_tertiary: #333 !important; + --solid_color_block: #2d2d2d !important; - --text_color_primary: #fff; - --text_color_secondary: #7b7b7b; - --text_color_tertiary: #656565; + --text_color_primary: #fff !important; + --text_color_secondary: #7b7b7b !important; + --text_color_tertiary: #656565 !important; - --border_color_secondary: #424141; + --border_color_secondary: #424141 !important; } :root[theme='black'] { - --solid_color_primary: #13171b; - --solid_color_primary-opaque:rgba(19, 23, 27, .6); - --solid_color_secondary: #4f5050; - --solid_color_secondary-dark: #424343; - --solid_color_tertiary: #000; - --solid_color_block: #202327; + --solid_color_primary: #13171b !important; + --solid_color_primary-opaque:rgba(19, 23, 27, .6) !important; + --solid_color_secondary: #4f5050 !important; + --solid_color_secondary-dark: #424343 !important; + --solid_color_tertiary: #000 !important; + --solid_color_block: #202327 !important; - --text_color_primary: #cccbcb; - --text_color_secondary: #61686E; - --text_color_tertiary: #656565; + --text_color_primary: #cccbcb !important; + --text_color_secondary: #61686E !important; + --text_color_tertiary: #656565 !important; - --border_color_secondary: #212020; + --border_color_secondary: #212020 !important; } html, @@ -199,7 +199,6 @@ body { .inherit { color: inherit; - font: inherit; white-space: inherit; } @@ -246,6 +245,9 @@ body { .whiteSpaceNoWrap { white-space: nowrap; } .outlineNone { outline: none; } +.outlineOnFocus:focus { + box-shadow: 0 0 0 5px rgba(21, 156, 228, 0.4); +} .resizeNone { resize: none; } @@ -264,6 +266,7 @@ body { .borderRight1PX { border-right-width: 1px; } .borderBottom1PX { border-bottom-width: 1px; } +.borderBottom6PX { border-bottom-width: 6px; } .borderLeft1PX { border-left-width: 1px; } .borderTop1PX { border-top-width: 1px; } @@ -393,6 +396,7 @@ body { /* */ +.posSticky { position: sticky; } .posFixed { position: fixed; } .posAbs { position: absolute; } @@ -699,7 +703,7 @@ body { } .boxShadowProfileAvatar { - box-shadow: 0 0 0 6px #F6F6F9; + box-shadow: 0 0 0 6px var(--solid_color_primary); } .listStyleNone { diff --git a/app/lib/proof_provider/keybase/config_serializer.rb b/app/lib/proof_provider/keybase/config_serializer.rb index 073b7896..9c945d2c 100644 --- a/app/lib/proof_provider/keybase/config_serializer.rb +++ b/app/lib/proof_provider/keybase/config_serializer.rb @@ -26,7 +26,7 @@ class ProofProvider::Keybase::ConfigSerializer < ActiveModel::Serializer end def brand_color - '#282c37' + '#21D07B' end def description diff --git a/app/models/list_account.rb b/app/models/list_account.rb index 1ee12cb0..f26ba277 100644 --- a/app/models/list_account.rb +++ b/app/models/list_account.rb @@ -6,7 +6,7 @@ # id :bigint(8) not null, primary key # list_id :bigint(8) not null # account_id :bigint(8) not null -# follow_id :bigint(8) not null +# follow_id :bigint(8) default(1) # class ListAccount < ApplicationRecord @@ -21,6 +21,6 @@ class ListAccount < ApplicationRecord private def set_follow - self.follow = Follow.find_by!(account_id: list.account_id, target_account_id: account.id) unless list.account_id == account.id + self.follow = Follow.find_by!(account_id: list.account_id, target_account_id: account.id) unless true end end diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb index 492ebd02..8472852d 100644 --- a/app/serializers/manifest_serializer.rb +++ b/app/serializers/manifest_serializer.rb @@ -32,7 +32,7 @@ class ManifestSerializer < ActiveModel::Serializer end def theme_color - '#282c37' + '#21D07B' end def background_color diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index baa80601..9c3a57dd 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -15,7 +15,7 @@ %link{ rel: 'mask-icon', href: '/mask-icon.svg', color: '#2B90D9' }/ %link{ rel: 'manifest', href: '/manifest.json' }/ %meta{ name: 'msapplication-config', content: '/browserconfig.xml' }/ - %meta{ name: 'theme-color', content: '#282c37' }/ + %meta{ name: 'theme-color', content: '#21D07B' }/ %meta{ name: 'apple-mobile-web-app-capable', content: 'yes' }/ - if @tag diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml index 0503dcdc..38037efa 100644 --- a/app/views/layouts/embedded.html.haml +++ b/app/views/layouts/embedded.html.haml @@ -11,7 +11,6 @@ %link{ rel: 'dns-prefetch', href: storage_host }/ = stylesheet_pack_tag 'common', media: 'all' - = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all' = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous' = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous' = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml index fa2ee556..d2083225 100644 --- a/app/views/layouts/error.html.haml +++ b/app/views/layouts/error.html.haml @@ -6,7 +6,6 @@ %title= safe_join([yield(:page_title), Setting.default_settings['site_title']], ' - ') %meta{ content: 'width=device-width,initial-scale=1', name: 'viewport' }/ = stylesheet_pack_tag 'common', media: 'all' - = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all' = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous' = javascript_pack_tag 'error', integrity: true, crossorigin: 'anonymous' %body.error diff --git a/db/schema.rb b/db/schema.rb index cf32c7db..54db4f22 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -400,7 +400,7 @@ ActiveRecord::Schema.define(version: 2020_04_30_154012) do create_table "list_accounts", force: :cascade do |t| t.bigint "list_id", null: false t.bigint "account_id", null: false - t.bigint "follow_id", null: false + t.bigint "follow_id", default: nil t.index ["account_id", "list_id"], name: "index_list_accounts_on_account_id_and_list_id", unique: true t.index ["follow_id"], name: "index_list_accounts_on_follow_id" t.index ["list_id", "account_id"], name: "index_list_accounts_on_list_id_and_account_id" diff --git a/public/browserconfig.xml b/public/browserconfig.xml index 7fdab505..a8dc61a1 100644 --- a/public/browserconfig.xml +++ b/public/browserconfig.xml @@ -3,7 +3,7 @@ - #282c37 + #21D07B