info: { id: 'navigation_bar.info', defaultMessage: 'Extended information' },
show_me_around: { id: 'getting_started.onboarding', defaultMessage: 'Show me around' },
pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
+ lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
});
const mapStateToProps = state => ({
navItems = navItems.concat([
<ColumnLink key='5' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
<ColumnLink key='6' icon='thumb-tack' text={intl.formatMessage(messages.pins)} to='/pinned' />,
+ <ColumnLink key='9' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />,
]);
if (myAccount.get('locked')) {
navItems = navItems.concat([
<ColumnLink key='8' icon='volume-off' text={intl.formatMessage(messages.mutes)} to='/mutes' />,
<ColumnLink key='9' icon='ban' text={intl.formatMessage(messages.blocks)} to='/blocks' />,
+ <ColumnLink key='10' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' hideOnMobile />,
]);
return (
ReportModal,
SettingsModal,
EmbedModal,
+ ListEditor,
} from 'flavours/glitch/util/async-components';
const MODAL_COMPONENTS = {
'SETTINGS': SettingsModal,
'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
'EMBED': EmbedModal,
+ 'LIST_EDITOR': ListEditor,
};
export default class ModalRoot extends React.PureComponent {
Blocks,
Mutes,
PinnedStatuses,
+ Lists,
} from 'flavours/glitch/util/async-components';
import { HotKeys } from 'react-hotkeys';
import { me } from 'flavours/glitch/util/initial_state';
<WrappedRoute path='/follow_requests' component={FollowRequests} content={children} />
<WrappedRoute path='/blocks' component={Blocks} content={children} />
<WrappedRoute path='/mutes' component={Mutes} content={children} />
+ <WrappedRoute path='/lists' component={Lists} content={children} />
<WrappedRoute component={GenericNotFound} content={children} />
</WrappedSwitch>
FAVOURITED_STATUSES_FETCH_SUCCESS,
FAVOURITED_STATUSES_EXPAND_SUCCESS,
} from 'flavours/glitch/actions/favourites';
+import {
+ LIST_ACCOUNTS_FETCH_SUCCESS,
+ LIST_EDITOR_SUGGESTIONS_READY,
+} from 'flavours/glitch/actions/lists';
import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
import emojify from 'flavours/glitch/util/emoji';
import { Map as ImmutableMap, fromJS } from 'immutable';
case BLOCKS_EXPAND_SUCCESS:
case MUTES_FETCH_SUCCESS:
case MUTES_EXPAND_SUCCESS:
+ case LIST_ACCOUNTS_FETCH_SUCCESS:
+ case LIST_EDITOR_SUGGESTIONS_READY:
return action.accounts ? normalizeAccounts(state, action.accounts) : state;
case NOTIFICATIONS_REFRESH_SUCCESS:
case NOTIFICATIONS_EXPAND_SUCCESS:
FAVOURITED_STATUSES_FETCH_SUCCESS,
FAVOURITED_STATUSES_EXPAND_SUCCESS,
} from 'flavours/glitch/actions/favourites';
+import {
+ LIST_ACCOUNTS_FETCH_SUCCESS,
+ LIST_EDITOR_SUGGESTIONS_READY,
+} from 'flavours/glitch/actions/lists';
import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
import { Map as ImmutableMap, fromJS } from 'immutable';
case BLOCKS_EXPAND_SUCCESS:
case MUTES_FETCH_SUCCESS:
case MUTES_EXPAND_SUCCESS:
+ case LIST_ACCOUNTS_FETCH_SUCCESS:
+ case LIST_EDITOR_SUGGESTIONS_READY:
return action.accounts ? normalizeAccounts(state, action.accounts) : state;
case NOTIFICATIONS_REFRESH_SUCCESS:
case NOTIFICATIONS_EXPAND_SUCCESS:
import height_cache from './height_cache';
import custom_emojis from './custom_emojis';
import lists from './lists';
+import listEditor from './list_editor';
const reducers = {
timelines,
height_cache,
custom_emojis,
lists,
+ listEditor,
};
export default combineReducers(reducers);
import { COLUMN_ADD, COLUMN_REMOVE, COLUMN_MOVE } from 'flavours/glitch/actions/columns';
import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
import { EMOJI_USE } from 'flavours/glitch/actions/emojis';
+import { LIST_DELETE_SUCCESS, LIST_FETCH_FAIL } from '../actions/lists';
import { Map as ImmutableMap, fromJS } from 'immutable';
import uuid from 'flavours/glitch/util/uuid';
const updateFrequentEmojis = (state, emoji) => state.update('frequentlyUsedEmojis', ImmutableMap(), map => map.update(emoji.id, 0, count => count + 1)).set('saved', false);
+const filterDeadListColumns = (state, listId) => state.update('columns', columns => columns.filterNot(column => column.get('id') === 'LIST' && column.get('params').get('id') === listId));
+
export default function settings(state = initialState, action) {
switch(action.type) {
case STORE_HYDRATE:
return updateFrequentEmojis(state, action.emoji);
case SETTING_SAVE:
return state.set('saved', true);
+ case LIST_FETCH_FAIL:
+ return action.error.response.status === 404 ? filterDeadListColumns(state, action.id) : state;
+ case LIST_DELETE_SUCCESS:
+ return filterDeadListColumns(state, action.id);
default:
return state;
}
}
}
+
+.column-inline-form {
+ padding: 7px 15px;
+ padding-right: 5px;
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ background: lighten($ui-base-color, 4%);
+
+ label {
+ flex: 1 1 auto;
+
+ input {
+ width: 100%;
+ margin-bottom: 6px;
+ }
+ }
+
+ .icon-button {
+ flex: 0 0 auto;
+ margin-left: 5px;
+ }
+}
+
+.drawer__backdrop {
+ cursor: pointer;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba($base-overlay-background, 0.5);
+}
+
+.list-editor {
+ background: $ui-base-color;
+ flex-direction: column;
+ border-radius: 8px;
+ box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
+ width: 40vh;
+ overflow: hidden;
+
+ h4 {
+ padding: 15px 0;
+ background: lighten($ui-base-color, 13%);
+ font-weight: 500;
+ font-size: 16px;
+ text-align: center;
+ border-radius: 8px 8px 0 0;
+ }
+
+ .drawer__pager {
+ height: 50vh;
+ }
+
+ .drawer__inner {
+ border-radius: 0 0 8px 8px;
+
+ &.backdrop {
+ width: calc(100% - 60px);
+ box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
+ border-radius: 0 0 0 8px;
+ }
+ }
+
+ &__accounts {
+ overflow-y: auto;
+ }
+
+ .account__display-name {
+ &:hover strong {
+ text-decoration: none;
+ }
+ }
+
+ .account__avatar {
+ cursor: default;
+ }
+
+ .search {
+ margin-bottom: 0;
+ }
+}
+
@import 'doodle';
@import 'emoji_picker';
@import 'local_settings';
return import(/* webpackChunkName: "features/list_timeline" */'flavours/glitch/features/list_timeline');
}
+export function Lists () {
+ return import(/* webpackChunkName: "features/lists" */'flavours/glitch/features/lists');
+}
+
+export function ListEditor () {
+ return import(/* webpackChunkName: "features/list_editor" */'flavours/glitch/features/list_editor');
+}
+
export function DirectTimeline() {
return import(/* webpackChunkName: "flavours/glitch/async/direct_timeline" */'flavours/glitch/features/direct_timeline');
}