diff --git a/app/javascript/gabsocial/components/footer_bar/footer_bar.scss b/app/javascript/gabsocial/components/footer_bar/footer_bar.scss
deleted file mode 100644
index ab0ce2e7..00000000
--- a/app/javascript/gabsocial/components/footer_bar/footer_bar.scss
+++ /dev/null
@@ -1,45 +0,0 @@
-.footer-bar {
- display: block;
- position: fixed;
- background: #000;
- height: 58px;
- bottom: 0;
- left: 0;
- right: 0;
- z-index: 1000;
- transition: transform 0.2s ease;
- overflow: hidden;
- padding-bottom: 0;
- padding-bottom: env(safe-area-inset-bottom);
-
- @media screen and (min-width: 895px) {
- display: none !important;
- }
-
- &__container {
- display: flex;
- flex-direction: row;
- align-items: stretch;
- }
-
- &__link {
- display: flex;
- flex: 1 1 auto;
- margin: 0;
- min-width: 36px;
- height: 58px;
- padding-top: 4px;
- justify-content: center;
- color: white;
- text-decoration: none;
- border-top: 2px solid transparent;
-
- &.active {
- border-top-color: $gab-brand-default;
- }
-
- & > span {
- display: none;
- }
- }
-}
\ No newline at end of file
diff --git a/app/javascript/gabsocial/components/footer_bar/index.js b/app/javascript/gabsocial/components/footer_bar/index.js
deleted file mode 100644
index 9d14266c..00000000
--- a/app/javascript/gabsocial/components/footer_bar/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './footer_bar'
\ No newline at end of file
diff --git a/app/javascript/gabsocial/components/icon.js b/app/javascript/gabsocial/components/icon.js
index b7a238c8..c61189ab 100644
--- a/app/javascript/gabsocial/components/icon.js
+++ b/app/javascript/gabsocial/components/icon.js
@@ -45,6 +45,8 @@ export default class Icon extends PureComponent {
return
case 'group':
return
+ case 'group-add':
+ return
case 'happy':
return
case 'home':
@@ -55,6 +57,8 @@ export default class Icon extends PureComponent {
return
case 'list':
return
+ case 'list-add':
+ return
case 'loading':
return
case 'media':
diff --git a/app/javascript/gabsocial/components/list.js b/app/javascript/gabsocial/components/list.js
index 5f6222cf..a88bcb34 100644
--- a/app/javascript/gabsocial/components/list.js
+++ b/app/javascript/gabsocial/components/list.js
@@ -1,8 +1,9 @@
+import ImmutablePureComponent from 'react-immutable-pure-component'
import Block from './block'
import ScrollableList from './scrollable_list'
import ListItem from './list_item'
-export default class List extends PureComponent {
+export default class List extends ImmutablePureComponent {
static propTypes = {
items: PropTypes.array,
@@ -21,16 +22,14 @@ export default class List extends PureComponent {
emptyMessage={emptyMessage}
>
{
- items.map((item, i) => {
- return (
-
- )
- })
+ items.map((item, i) => (
+
+ ))
}
diff --git a/app/javascript/gabsocial/components/modal/all_timeline_settings_modal.js b/app/javascript/gabsocial/components/modal/all_timeline_settings_modal.js
deleted file mode 100644
index 21498cf8..00000000
--- a/app/javascript/gabsocial/components/modal/all_timeline_settings_modal.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import { defineMessages, injectIntl } from 'react-intl'
-import ImmutablePureComponent from 'react-immutable-pure-component'
-import Button from '../button'
-import Text from '../text'
-import ModalLayout from './modal_layout'
-
-const messages = defineMessages({
- title: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
- text: { id: 'pro_upgrade_modal.text', defaultMessage: 'Gab is fully funded by people like you. Please consider supporting us on our mission to defend free expression online for all people.' },
- benefits: { id: 'pro_upgrade_modal.benefits', defaultMessage: 'Here are just some of the benefits that thousands of GabPRO members receive:' },
-})
-
-export default
-@injectIntl
-class HomeTimelineSettingsModal extends ImmutablePureComponent {
-
- static propTypes = {
- intl: PropTypes.object.isRequired,
- }
-
- render() {
- const { intl } = this.props
-
- return (
-
-
- {intl.formatMessage(messages.text)}
-
-
- {intl.formatMessage(messages.benefits)}
-
-
-
- • Schedule Posts
- • Get Verified
- • Create Groups
- • Larger Video and Image Uploads
- • Receive the PRO Badge
- • Remove in-feed promotions
-
-
-
-
-
- )
- }
-}
diff --git a/app/javascript/gabsocial/components/modal/block_account_modal.js b/app/javascript/gabsocial/components/modal/block_account_modal.js
index 25588be7..52084f57 100644
--- a/app/javascript/gabsocial/components/modal/block_account_modal.js
+++ b/app/javascript/gabsocial/components/modal/block_account_modal.js
@@ -1,6 +1,5 @@
import { injectIntl, defineMessages } from 'react-intl'
import { makeGetAccount } from '../../selectors'
-import { closeModal } from '../../actions/modal'
import { blockAccount } from '../../actions/accounts'
import ConfirmationModal from './confirmation_modal'
@@ -23,9 +22,6 @@ const mapDispatchToProps = dispatch => {
onConfirm(account) {
dispatch(blockAccount(account.get('id')))
},
- onClose() {
- dispatch(closeModal())
- },
}
}
@@ -37,7 +33,6 @@ class BlockAccountModal extends PureComponent {
static propTypes = {
account: PropTypes.object.isRequired,
onConfirm: PropTypes.func.isRequired,
- onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
@@ -45,10 +40,6 @@ class BlockAccountModal extends PureComponent {
this.props.onConfirm(this.props.account)
}
- handleClose = () => {
- this.props.onClose()
- }
-
render() {
const { account, intl } = this.props
@@ -64,7 +55,6 @@ class BlockAccountModal extends PureComponent {
title={title}
message={message}
confirm={intl.formatMessage(messages.block)}
- onClose={this.handleClose}
onConfirm={this.handleClick}
/>
)
diff --git a/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js b/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js
new file mode 100644
index 00000000..7697542f
--- /dev/null
+++ b/app/javascript/gabsocial/components/modal/community_timeline_settings_modal.js
@@ -0,0 +1,92 @@
+import { defineMessages, injectIntl } from 'react-intl'
+import ImmutablePureComponent from 'react-immutable-pure-component'
+import ImmutablePropTypes from 'react-immutable-proptypes'
+import { closeModal } from '../../actions/modal'
+import { changeSetting, saveSettings } from '../../actions/settings'
+import ModalLayout from './modal_layout'
+import Button from '../button'
+import SettingSwitch from '../setting_switch'
+import Text from '../text'
+
+const messages = defineMessages({
+ title: { id: 'community_timeline_settings', defaultMessage: 'Community Timeline 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' },
+})
+
+const mapStateToProps = state => ({
+ settings: state.getIn(['settings', 'community']),
+})
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onChange(key, checked) {
+ dispatch(changeSetting(['community', ...key], checked))
+ },
+ onSave() {
+ dispatch(saveSettings())
+ dispatch(closeModal())
+ },
+ }
+}
+
+export default
+@connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
+class CommunityTimelineSettingsModal extends ImmutablePureComponent {
+
+ static propTypes = {
+ intl: PropTypes.object.isRequired,
+ settings: ImmutablePropTypes.map.isRequired,
+ onChange: PropTypes.func.isRequired,
+ onSave: PropTypes.func.isRequired,
+ }
+
+ handleSaveAndClose = () => {
+ this.props.onSave()
+ }
+
+ render() {
+ const { intl, settings, onChange } = this.props
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+}
diff --git a/app/javascript/gabsocial/components/modal/group_adder_modal.js b/app/javascript/gabsocial/components/modal/group_adder_modal.js
deleted file mode 100644
index c878e233..00000000
--- a/app/javascript/gabsocial/components/modal/group_adder_modal.js
+++ /dev/null
@@ -1,72 +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 => {
- return {
- isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
- account: state.getIn(['mutes', 'new', 'account']),
- }
-}
-
-const mapDispatchToProps = dispatch => {
- return {
- 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/modal/group_create_modal.js b/app/javascript/gabsocial/components/modal/group_create_modal.js
new file mode 100644
index 00000000..3b972016
--- /dev/null
+++ b/app/javascript/gabsocial/components/modal/group_create_modal.js
@@ -0,0 +1,30 @@
+import { defineMessages, injectIntl } from 'react-intl'
+import ImmutablePureComponent from 'react-immutable-pure-component'
+import ModalLayout from './modal_layout'
+import GroupCreate from '../../features/group_create'
+
+const messages = defineMessages({
+ title: { id: 'create_group', defaultMessage: 'Create Group' },
+})
+
+export default
+@injectIntl
+class GroupCreateModal extends ImmutablePureComponent {
+
+ static propTypes = {
+ intl: PropTypes.object.isRequired,
+ }
+
+ render() {
+ const { intl } = this.props
+
+ return (
+
+
+
+ )
+ }
+}
diff --git a/app/javascript/gabsocial/components/modal/group_delete_modal.js b/app/javascript/gabsocial/components/modal/group_delete_modal.js
new file mode 100644
index 00000000..110bdedc
--- /dev/null
+++ b/app/javascript/gabsocial/components/modal/group_delete_modal.js
@@ -0,0 +1,55 @@
+import { injectIntl, defineMessages } from 'react-intl'
+import { makeGetAccount } from '../../selectors'
+import { blockAccount } from '../../actions/accounts'
+import ConfirmationModal from './confirmation_modal'
+
+const messages = defineMessages({
+ title: { id: 'group_delete_title', defaultMessage: 'Delete "{group}"' },
+ groupMessage: { id: 'confirmations.group_delete.message', defaultMessage: 'Are you sure you want to delete "{group}"?' },
+ delete: { id: 'delete', defaultMessage: 'Delete' },
+})
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onConfirm(account) {
+ // dispatch(blockAccount(account.get('id')))
+ },
+ }
+}
+
+export default
+@connect(null, mapDispatchToProps)
+@injectIntl
+class GroupDeleteModal extends PureComponent {
+
+ static propTypes = {
+ group: PropTypes.object.isRequired,
+ onConfirm: PropTypes.func.isRequired,
+ intl: PropTypes.object.isRequired,
+ }
+
+ handleClick = () => {
+ this.props.onConfirm(this.props.account)
+ }
+
+ render() {
+ const { group, intl } = this.props
+
+ const title = intl.formatMessage(messages.title, {
+ group: !!group ? account.get('title') : '',
+ })
+ const message = intl.formatMessage(messages.groupMessage, {
+ group: !!group ? account.get('title') : '',
+ })
+
+ return (
+
+ )
+ }
+
+}
diff --git a/app/javascript/gabsocial/components/modal/home_timeline_settings_modal.js b/app/javascript/gabsocial/components/modal/home_timeline_settings_modal.js
index 132356a2..a45fb899 100644
--- a/app/javascript/gabsocial/components/modal/home_timeline_settings_modal.js
+++ b/app/javascript/gabsocial/components/modal/home_timeline_settings_modal.js
@@ -59,7 +59,7 @@ class HomeTimelineSettingsModal extends ImmutablePureComponent {
title={intl.formatMessage(messages.title)}
>
-
+
-
diff --git a/app/javascript/gabsocial/components/modal/list_adder_modal.js b/app/javascript/gabsocial/components/modal/list_adder_modal.js
deleted file mode 100644
index c878e233..00000000
--- a/app/javascript/gabsocial/components/modal/list_adder_modal.js
+++ /dev/null
@@ -1,72 +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 => {
- return {
- isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
- account: state.getIn(['mutes', 'new', 'account']),
- }
-}
-
-const mapDispatchToProps = dispatch => {
- return {
- 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/modal/list_create_modal.js b/app/javascript/gabsocial/components/modal/list_create_modal.js
new file mode 100644
index 00000000..86686788
--- /dev/null
+++ b/app/javascript/gabsocial/components/modal/list_create_modal.js
@@ -0,0 +1,30 @@
+import { defineMessages, injectIntl } from 'react-intl'
+import ImmutablePureComponent from 'react-immutable-pure-component'
+import ModalLayout from './modal_layout'
+import ListCreate from '../../features/list_create'
+
+const messages = defineMessages({
+ title: { id: 'create_list', defaultMessage: 'Create List' },
+})
+
+export default
+@injectIntl
+class ListCreateModal extends ImmutablePureComponent {
+
+ static propTypes = {
+ intl: PropTypes.object.isRequired,
+ }
+
+ render() {
+ const { intl } = this.props
+
+ return (
+
+
+
+ )
+ }
+}
diff --git a/app/javascript/gabsocial/components/modal/list_delete_modal.js b/app/javascript/gabsocial/components/modal/list_delete_modal.js
new file mode 100644
index 00000000..d41f99fe
--- /dev/null
+++ b/app/javascript/gabsocial/components/modal/list_delete_modal.js
@@ -0,0 +1,55 @@
+import { injectIntl, defineMessages } from 'react-intl'
+import { makeGetAccount } from '../../selectors'
+import { blockAccount } from '../../actions/accounts'
+import ConfirmationModal from './confirmation_modal'
+
+const messages = defineMessages({
+ title: { id: 'list_delete_title', defaultMessage: 'Delete "{list}"' },
+ listMessage: { id: 'confirmations.list_delete.message', defaultMessage: 'Are you sure you want to delete "{list}"?' },
+ delete: { id: 'delete', defaultMessage: 'Delete' },
+})
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onConfirm(account) {
+ // dispatch(blockAccount(account.get('id')))
+ },
+ }
+}
+
+export default
+@connect(null, mapDispatchToProps)
+@injectIntl
+class ListDeleteModal extends PureComponent {
+
+ static propTypes = {
+ list: PropTypes.object.isRequired,
+ onConfirm: PropTypes.func.isRequired,
+ intl: PropTypes.object.isRequired,
+ }
+
+ handleClick = () => {
+ this.props.onConfirm(this.props.account)
+ }
+
+ render() {
+ const { list, intl } = this.props
+
+ const title = intl.formatMessage(messages.title, {
+ list: !!list ? account.get('title') : '',
+ })
+ const message = intl.formatMessage(messages.listMessage, {
+ list: !!list ? account.get('title') : '',
+ })
+
+ 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
new file mode 100644
index 00000000..2732357d
--- /dev/null
+++ b/app/javascript/gabsocial/components/modal/list_timeline_settings_modal.js
@@ -0,0 +1,119 @@
+import { defineMessages, injectIntl } from 'react-intl'
+import ImmutablePureComponent from 'react-immutable-pure-component'
+import ImmutablePropTypes from 'react-immutable-proptypes'
+import { closeModal } from '../../actions/modal'
+import { changeSetting, saveSettings } from '../../actions/settings'
+import ModalLayout from './modal_layout'
+import Button from '../button'
+import SettingSwitch from '../setting_switch'
+import Text from '../text'
+
+const messages = defineMessages({
+ title: { id: 'list_timeline_settings', defaultMessage: 'List Timeline Settings' },
+ saveAndClose: { id: 'saveClose', defaultMessage: 'Save & Close' },
+ showVideos: { id: 'home.column_settings.show_videos', defaultMessage: 'Show videos' },
+ showPhotos: { id: 'home.column_settings.show_photos', defaultMessage: 'Show photos' },
+ showPolls: { id: 'home.column_settings.show_polls', defaultMessage: 'Show polls' },
+ showReposts: { id: 'home.column_settings.show_reposts', defaultMessage: 'Show comments' },
+ showReplies: { id: 'home.column_settings.show_replies', defaultMessage: 'Show replies' },
+})
+
+const mapStateToProps = state => ({
+ settings: state.getIn(['settings', 'list']),
+})
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onChange(key, checked) {
+ dispatch(changeSetting(['list', ...key], checked))
+ },
+ onSave() {
+ dispatch(saveSettings())
+ dispatch(closeModal())
+ },
+ }
+}
+
+export default
+@connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
+class ListTimelineSettingsModal extends ImmutablePureComponent {
+
+ static propTypes = {
+ intl: PropTypes.object.isRequired,
+ settings: ImmutablePropTypes.map.isRequired,
+ onChange: PropTypes.func.isRequired,
+ onSave: PropTypes.func.isRequired,
+ }
+
+ handleSaveAndClose = () => {
+ this.props.onSave()
+ }
+
+ render() {
+ const { intl, settings, onChange } = this.props
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+}
diff --git a/app/javascript/gabsocial/components/modal/modal_layout.js b/app/javascript/gabsocial/components/modal/modal_layout.js
index 29a9ccb0..db7e8420 100644
--- a/app/javascript/gabsocial/components/modal/modal_layout.js
+++ b/app/javascript/gabsocial/components/modal/modal_layout.js
@@ -1,5 +1,6 @@
import { defineMessages, injectIntl } from 'react-intl'
import classNames from 'classnames/bind'
+import { closeModal } from '../../actions/modal'
import Button from '../button'
import Block from '../block'
import Heading from '../heading'
@@ -10,13 +11,23 @@ const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
})
+const mapDispatchToProps = dispatch => {
+ return {
+ handleCloseModal() {
+ dispatch(closeModal())
+ },
+ }
+}
+
export default
+@connect(null, mapDispatchToProps)
@injectIntl
class ModalLayout extends PureComponent {
static propTypes = {
title: PropTypes.string,
children: PropTypes.node,
onClose: PropTypes.func.isRequired,
+ handleCloseModal: PropTypes.func.isRequired,
width: PropTypes.number,
hideClose: PropTypes.bool,
noPadding: PropTypes.bool,
@@ -26,12 +37,19 @@ class ModalLayout extends PureComponent {
width: 600,
}
+ onHandleCloseModal = () => {
+ if (this.props.onClose) {
+ this.props.onClose();
+ } else {
+ this.props.handleCloseModal()
+ }
+ }
+
render() {
const {
title,
children,
intl,
- onClose,
width,
hideClose,
noPadding
@@ -39,6 +57,8 @@ class ModalLayout extends PureComponent {
const childrenContainerClasses = cx({
default: 1,
+ heightMax80VH: 1,
+ overflowScroll: 1,
px15: !noPadding,
py10: !noPadding,
})
@@ -56,7 +76,7 @@ class ModalLayout extends PureComponent {
backgroundColor='none'
title={intl.formatMessage(messages.close)}
className={_s.marginLeftAuto}
- onClick={onClose}
+ onClick={this.onHandleCloseModal}
icon='close'
iconWidth='10px'
iconWidth='10px'
diff --git a/app/javascript/gabsocial/components/modal/modal_root.js b/app/javascript/gabsocial/components/modal/modal_root.js
index 3a73a800..fa1cd530 100644
--- a/app/javascript/gabsocial/components/modal/modal_root.js
+++ b/app/javascript/gabsocial/components/modal/modal_root.js
@@ -8,7 +8,7 @@ import {
// ListEditor,
// ListAdder,
StatusRevisionModal,
-} from '../../features/ui/util/async-components'
+} from '../../features/ui/util/async_components'
import ModalBase from './modal_base'
import BundleModalError from '../bundle_modal_error'
@@ -17,14 +17,18 @@ import ActionsModal from './actions_modal'
import BlockAccountModal from './block_account_modal'
import BlockDomainModal from './block_domain_modal'
import BoostModal from './boost_modal'
+import CommunityTimelineSettingsModal from './community_timeline_settings_modal'
import ComposeModal from './compose_modal'
import ConfirmationModal from './confirmation_modal'
-import GroupAdderModal from './group_adder_modal'
+import GroupCreateModal from './group_create_modal'
+import GroupDeleteModal from './group_delete_modal'
import GroupEditorModal from './group_editor_modal'
import HomeTimelineSettingsModal from './home_timeline_settings_modal'
import HotkeysModal from './hotkeys_modal'
-import ListAdderModal from './list_adder_modal'
+import ListCreateModal from './list_create_modal'
+import ListDeleteModal from './list_delete_modal'
import ListEditorModal from './list_editor_modal'
+import ListTimelineSettingsModal from './list_timeline_settings_modal'
import MediaModal from './media_modal'
import ModalLoading from './modal_loading'
import ProUpgradeModal from './pro_upgrade_modal'
@@ -37,15 +41,19 @@ const MODAL_COMPONENTS = {
BLOCK_ACCOUNT: () => Promise.resolve({ default: BlockAccountModal }),
BLOCK_DOMAIN: () => Promise.resolve({ default: BlockDomainModal }),
BOOST: () => Promise.resolve({ default: BoostModal }),
+ COMMUNITY_TIMELINE_SETTINGS: () => Promise.resolve({ default: CommunityTimelineSettingsModal }),
COMPOSE: () => Promise.resolve({ default: ComposeModal }),
CONFIRM: () => Promise.resolve({ default: ConfirmationModal }),
EMBED: () => Promise.resolve({ default: EmbedModal }),
+ GROUP_CREATE: () => Promise.resolve({ default: GroupCreateModal }),
+ GROUP_DELETE: () => Promise.resolve({ default: GroupDeleteModal }),
GROUP_EDITOR: () => Promise.resolve({ default: GroupEditorModal }),
- GROUP_ADDER: () => Promise.resolve({ default: GroupAdderModal }),
HOME_TIMELINE_SETTINGS: () => Promise.resolve({ default: HomeTimelineSettingsModal }),
HOTKEYS: () => Promise.resolve({ default: HotkeysModal }),
+ LIST_CREATE: () => Promise.resolve({ default: ListCreateModal }),
+ LIST_DELETE: () => Promise.resolve({ default: ListDeleteModal }),
LIST_EDITOR: () => Promise.resolve({ default: ListEditorModal }),
- LIST_ADDER: () => Promise.resolve({ default: ListAdderModal }),
+ LIST_TIMELINE_SETTINGS: () => Promise.resolve({ default: ListTimelineSettingsModal }),
MEDIA: () => Promise.resolve({ default: MediaModal }),
'MUTE': MuteModal,
PRO_UPGRADE: () => Promise.resolve({ default: ProUpgradeModal }),
diff --git a/app/javascript/gabsocial/components/modal/mute_modal.js b/app/javascript/gabsocial/components/modal/mute_modal.js
index 417ffdbc..ffd29ca7 100644
--- a/app/javascript/gabsocial/components/modal/mute_modal.js
+++ b/app/javascript/gabsocial/components/modal/mute_modal.js
@@ -1,6 +1,5 @@
import { injectIntl, defineMessages } from 'react-intl'
import { makeGetAccount } from '../../selectors'
-import { closeModal } from '../../actions/modal'
import { muteAccount } from '../../actions/accounts'
import ConfirmationModal from './confirmation_modal'
@@ -21,12 +20,8 @@ const mapStateToProps = (state, { accountId }) => {
const mapDispatchToProps = dispatch => {
return {
onConfirm(account, notifications) {
- dispatch(closeModal())
dispatch(muteAccount(account.get('id'), notifications))
},
- onClose() {
- dispatch(closeModal())
- },
}
}
@@ -38,7 +33,6 @@ class MuteModal extends PureComponent {
static propTypes = {
account: PropTypes.object.isRequired,
onConfirm: PropTypes.func.isRequired,
- onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
@@ -46,10 +40,6 @@ class MuteModal extends PureComponent {
this.props.onConfirm(this.props.account)
}
- handleClose = () => {
- this.props.onClose()
- }
-
render() {
const { account, intl } = this.props
@@ -65,7 +55,6 @@ class MuteModal extends PureComponent {
title={title}
message={message}
confirm={intl.formatMessage(messages.mute)}
- onClose={this.handleClose}
onConfirm={this.handleClick}
/>
)
diff --git a/app/javascript/gabsocial/components/modal/pro_upgrade_modal.js b/app/javascript/gabsocial/components/modal/pro_upgrade_modal.js
index e6b43def..09e617eb 100644
--- a/app/javascript/gabsocial/components/modal/pro_upgrade_modal.js
+++ b/app/javascript/gabsocial/components/modal/pro_upgrade_modal.js
@@ -22,7 +22,7 @@ class ProUpgradeModal extends ImmutablePureComponent {
const { intl } = this.props
return (
-
+
{intl.formatMessage(messages.text)}
diff --git a/app/javascript/gabsocial/components/panel/list_details_panel.js b/app/javascript/gabsocial/components/panel/list_details_panel.js
index 2a644a27..4e43fedc 100644
--- a/app/javascript/gabsocial/components/panel/list_details_panel.js
+++ b/app/javascript/gabsocial/components/panel/list_details_panel.js
@@ -1,24 +1,31 @@
-import { defineMessages, injectIntl } from 'react-intl';
-import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import PanelLayout from './panel_layout';
+import { defineMessages, injectIntl } from 'react-intl'
+import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions'
+import ImmutablePureComponent from 'react-immutable-pure-component'
+import ImmutablePropTypes from 'react-immutable-proptypes'
+import PanelLayout from './panel_layout'
+import Avatar from '../avatar'
+import Divider from '../divider'
+import Icon from '../icon'
+import Heading from '../heading'
+import Text from '../text'
const messages = defineMessages({
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
- title: { id: 'lists.panel_title', defaultMessage: 'On This List ({count})' },
- show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
-});
+ memberCount: { id: 'lists.panel_members', defaultMessage: 'Members: {count}' },
+ createdAt: { id: 'lists.panel_created', defaultMessage: 'Created: {date}' },
+ title: { id: 'lists_information', defaultMessage: 'List Information' },
+ edit: { id: 'edit', defaultMessage: 'Edit' },
+})
const mapStateToProps = state => ({
// accountIds: state.getIn(['listEditor', 'accounts', 'items']),
-});
+})
const mapDispatchToProps = dispatch => {
return {
}
-};
+}
export default
@connect(mapStateToProps, mapDispatchToProps)
@@ -27,27 +34,77 @@ class ListDetailsPanel extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
- };
+ }
handleShowAllLists() {
}
render() {
- const { intl } = this.props;
-
- const count = 10
+ const { intl } = this.props
return (
+
+
+ Some List Title
+
+
+
+
+
+
+
+
+ {
+ intl.formatMessage(messages.createdAt, {
+ date: '12-25-2019'
+ })
+ }
+
+
+
+
+
+
+
+
+
+ {
+ intl.formatMessage(messages.memberCount, {
+ count: 10
+ })
+ }
+
+
+
+
+ {
+ [1, 2, 3, 4, 5, 6, 7, 8, 9].map(item => (
+
+ ))
+ }
+
+
+
- );
- };
-};
\ No newline at end of file
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/javascript/gabsocial/components/popover/popover_base.js b/app/javascript/gabsocial/components/popover/popover_base.js
index 9373a1f8..58a1e0f4 100644
--- a/app/javascript/gabsocial/components/popover/popover_base.js
+++ b/app/javascript/gabsocial/components/popover/popover_base.js
@@ -123,6 +123,9 @@ class PopoverBase extends ImmutablePureComponent {
displayNone: !visible,
})
+ console.log("targetRef:", targetRef)
+
+
return (
Promise.resolve({ default: SearchPopover }),
SIDEBAR_MORE: () => Promise.resolve({ default: SidebarMorePopover }),
STATUS_OPTIONS: () => Promise.resolve({ default: StatusOptionsPopover }),
+ STATUS_SHARE: () => Promise.resolve({ default: StatusSharePopover }),
STATUS_VISIBILITY: () => Promise.resolve({ default: StatusVisibilityPopover }),
USER_INFO: () => Promise.resolve({ default: UserInfoPopover }),
}
diff --git a/app/javascript/gabsocial/components/popover/profile_options_popover.js b/app/javascript/gabsocial/components/popover/profile_options_popover.js
index 1d0424e8..e802ded2 100644
--- a/app/javascript/gabsocial/components/popover/profile_options_popover.js
+++ b/app/javascript/gabsocial/components/popover/profile_options_popover.js
@@ -1,4 +1,4 @@
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
+import { defineMessages, injectIntl } from 'react-intl'
import {
followAccount,
unfollowAccount,
diff --git a/app/javascript/gabsocial/components/popover/status_options_popover.js b/app/javascript/gabsocial/components/popover/status_options_popover.js
index 59b66e34..e407f169 100644
--- a/app/javascript/gabsocial/components/popover/status_options_popover.js
+++ b/app/javascript/gabsocial/components/popover/status_options_popover.js
@@ -1,43 +1,84 @@
+import PopoverLayout from './popover_layout'
+import List from '../list'
+
export default class StatusOptionsPopover extends PureComponent {
- render() {
+ _makeMenu = (publicStatus) => {
+ // const { status, intl: { formatMessage }, withDismiss, withGroupAdmin } = this.props
+ // const mutingConversation = status.get('muted')
+
+ let menu = [];
+
+ // menu.push({ text: formatMessage(messages.open), action: this.handleOpen });
// if (publicStatus) {
- // menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
- // menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
+ // menu.push({ text: formatMessage(messages.copy), action: this.handleCopy });
+ // menu.push({ text: formatMessage(messages.embed), action: this.handleEmbed });
+ // }
+
+ // if (!me) return menu
+
+ // menu.push(null);
+
+ // if (status.getIn(['account', 'id']) === me || withDismiss) {
+ // menu.push({ text: formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
// menu.push(null);
// }
- // if (me === status.getIn(['account', 'id'])) {
+ // if (status.getIn(['account', 'id']) === me) {
// if (publicStatus) {
- // menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
+ // menu.push({ text: formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
// } else {
// if (status.get('visibility') === 'private') {
- // menu.push({ text: intl.formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private), action: this.handleRepostClick });
+ // menu.push({ text: formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private), action: this.handleRepostClick });
// }
// }
-
- // menu.push(null);
- // menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
- // menu.push(null);
- // menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
- // menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
+ // menu.push({ text: formatMessage(messages.delete), action: this.handleDeleteClick });
+ // menu.push({ text: formatMessage(messages.edit), action: this.handleEditClick });
// } else {
- // menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
+ // menu.push({ text: formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
// menu.push(null);
- // menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
- // menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
- // menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
+ // menu.push({ text: formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
+ // menu.push({ text: formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
+ // menu.push({ text: formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
+
// if (isStaff) {
// menu.push(null);
- // menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
- // menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+ // menu.push({ text: formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
+ // menu.push({ text: formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+ // }
+
+ // if (withGroupAdmin) {
+ // menu.push(null);
+ // menu.push({ text: formatMessage(messages.group_remove_account), action: this.handleGroupRemoveAccount });
+ // menu.push({ text: formatMessage(messages.group_remove_post), action: this.handleGroupRemovePost });
// }
// }
+ return menu;
+ }
+
+ render() {
return (
-
- { /* */ }
-
+
+
+
)
}
}
\ No newline at end of file
diff --git a/app/javascript/gabsocial/components/popover/status_share_popover.js b/app/javascript/gabsocial/components/popover/status_share_popover.js
new file mode 100644
index 00000000..4f61a98a
--- /dev/null
+++ b/app/javascript/gabsocial/components/popover/status_share_popover.js
@@ -0,0 +1,91 @@
+import ImmutablePropTypes from 'react-immutable-proptypes'
+import ImmutablePureComponent from 'react-immutable-pure-component'
+import { defineMessages, injectIntl } from 'react-intl'
+import PopoverLayout from './popover_layout'
+import List from '../list'
+
+const messages = defineMessages({
+ embed: { id: 'status.embed', defaultMessage: 'Embed gab' },
+ email: { id: 'status.email', defaultMessage: 'Email gab' },
+ copy: { id: 'status.copy', defaultMessage: 'Copy link to gab' },
+});
+
+// const makeMapStateToProps = () => {
+// const getAccount = makeGetAccount();
+
+// const mapStateToProps = (state, { account }) => ({
+
+// });
+
+// return mapStateToProps;
+// };
+
+// const mapDispatchToProps = (dispatch, { intl }) => ({
+
+// });
+
+export default
+@injectIntl
+// @connect(makeMapStateToProps, mapDispatchToProps)
+class StatusSharePopover extends ImmutablePureComponent {
+ static propTypes = {
+ status: ImmutablePropTypes.map,
+ intl: PropTypes.object.isRequired,
+ }
+
+ handleEmbed = () => {
+ // this.props.onEmbed(this.props.status);
+ }
+
+ handleCopy = () => {
+ // const url = this.props.status.get('url');
+ // const textarea = document.createElement('textarea');
+
+ // textarea.textContent = url;
+ // textarea.style.position = 'fixed';
+
+ // document.body.appendChild(textarea);
+
+ // try {
+ // textarea.select();
+ // document.execCommand('copy');
+ // } catch (e) {
+ // //
+ // } finally {
+ // document.body.removeChild(textarea);
+ // }
+ }
+
+ render() {
+ const { intl } = this.props
+
+ return (
+
+
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/javascript/gabsocial/components/sidebar.js b/app/javascript/gabsocial/components/sidebar.js
index 098c16c9..8ef3d6e4 100644
--- a/app/javascript/gabsocial/components/sidebar.js
+++ b/app/javascript/gabsocial/components/sidebar.js
@@ -40,6 +40,7 @@ const mapStateToProps = state => {
sidebarOpen: state.get('sidebar').sidebarOpen,
notificationCount: state.getIn(['notifications', 'unread']),
homeItemsQueueCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
+ showCommunityTimeline: state.getIn(['settings', 'community', 'shows', 'inSidebar']),
}
}
@@ -64,6 +65,7 @@ class Sidebar extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
sidebarOpen: PropTypes.bool,
+ showCommunityTimeline: PropTypes.bool,
onClose: PropTypes.func.isRequired,
onOpenComposeModal: PropTypes.func.isRequired,
openSidebarMorePopover: PropTypes.func.isRequired,
@@ -115,7 +117,14 @@ class Sidebar extends ImmutablePureComponent {
}
render() {
- const { sidebarOpen, intl, account, notificationCount, homeItemsQueueCount } = this.props
+ const {
+ sidebarOpen,
+ intl,
+ account,
+ notificationCount,
+ homeItemsQueueCount,
+ showCommunityTimeline
+ } = this.props
const { moreOpen } = this.state
// : todo :
@@ -127,6 +136,8 @@ class Sidebar extends ImmutablePureComponent {
const moreIcon = moreOpen ? 'minus' : 'plus'
const moreContainerStyle = { display: moreOpen ? 'block' : 'none' }
+ console.log("showCommunityTimeline:", showCommunityTimeline)
+
const menuItems = [
{
title: 'Home',
@@ -134,18 +145,24 @@ class Sidebar extends ImmutablePureComponent {
to: '/',
count: homeItemsQueueCount,
},
+ {
+ title: 'Community',
+ icon: 'community',
+ to: '/timeline/all',
+ hidden: !showCommunityTimeline,
+ },
{
title: 'Notifications',
icon: 'notifications',
to: '/notifications',
count: notificationCount,
},
- // : todo : show only when search on top is not visible
- // {
- // title: 'Search',
- // icon: 'search-alt',
- // to: '/search',
- // },
+ {
+ title: 'Search',
+ icon: 'search-alt',
+ to: '/search',
+ hidden: true, // : todo : show only when search on top is not visible
+ },
{
title: 'Groups',
icon: 'group',
@@ -169,11 +186,6 @@ class Sidebar extends ImmutablePureComponent {
},
]
- // more modal:
- // settings/preferences
- // help
- // logout
-
const shortcutItems = [
{
title: 'Meme Group',
@@ -223,9 +235,13 @@ class Sidebar extends ImmutablePureComponent {