From 524a438a9b6a7609b5f1357f122fe62c25bb43b1 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 2 Aug 2019 18:29:48 -0400 Subject: [PATCH 01/38] Make mention links internal, fixes #74 --- app/javascript/gabsocial/components/status_content.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/gabsocial/components/status_content.js b/app/javascript/gabsocial/components/status_content.js index ca47143f..0b274e72 100644 --- a/app/javascript/gabsocial/components/status_content.js +++ b/app/javascript/gabsocial/components/status_content.js @@ -45,7 +45,7 @@ export default class StatusContent extends React.PureComponent { } link.classList.add('status-link'); - let mention = this.props.status.get('mentions').find(item => link.href === `/${item.get('acct')}`); + let mention = this.props.status.get('mentions').find(item => link.href === `${item.get('url')}`); if (mention) { link.addEventListener('click', this.onMentionClick.bind(this, mention), false); @@ -139,7 +139,7 @@ export default class StatusContent extends React.PureComponent { const { status, reblogContent } = this.props; const properContent = status.get('contentHtml'); - + return reblogContent ? `${reblogContent}
${properContent}
` : properContent; From f6ee98a2f0123b7af1c982aa4f8f22885f391fdb Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 5 Aug 2019 18:48:45 -0400 Subject: [PATCH 02/38] Add PRO conditional to dashboard, fixes #78 --- app/views/admin/accounts/show.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 4e709352..41228e39 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -133,7 +133,10 @@ %td - if @account.is_pro? =fa_icon 'check' - %time.formatted{ datetime: @account.pro_expires_at.iso8601, title: l(@account.pro_expires_at) }= l @account.pro_expires_at + - if @account.pro_expires_at? + %time.formatted{ datetime: @account.pro_expires_at.iso8601, title: l(@account.pro_expires_at) }= l @account.pro_expires_at + - else + ∞ %td - if @account.local? = table_link_to '', t('admin.accounts.edit_pro'), edit_pro_admin_account_path(@account.id), class: 'button' if can?(:verify, @account) From cc39821efa8a8f5c3f2a9fae5ef8181a1980ac0e Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 5 Aug 2019 20:02:23 -0400 Subject: [PATCH 03/38] Make "muted words" button work, fixes #77 --- .../gabsocial/features/compose/components/action_bar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/gabsocial/features/compose/components/action_bar.js b/app/javascript/gabsocial/features/compose/components/action_bar.js index 06c12e4b..2a710287 100644 --- a/app/javascript/gabsocial/features/compose/components/action_bar.js +++ b/app/javascript/gabsocial/features/compose/components/action_bar.js @@ -48,7 +48,7 @@ class ActionBar extends React.PureComponent { menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' }); menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' }); menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' }); - menu.push({ text: intl.formatMessage(messages.filters), to: '/filters' }); + menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' }); menu.push(null); menu.push({ text: intl.formatMessage(messages.keyboard_shortcuts), action: this.handleHotkeyClick }); menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' }); From d694d4a1a7fafad720f9a9afbbfca0314542c0ec Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 7 Aug 2019 15:49:16 -0400 Subject: [PATCH 04/38] Fix "delete & redraft" to pop up modal, fixes #71 --- app/javascript/gabsocial/actions/statuses.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/javascript/gabsocial/actions/statuses.js b/app/javascript/gabsocial/actions/statuses.js index 1b2744c4..69261f41 100644 --- a/app/javascript/gabsocial/actions/statuses.js +++ b/app/javascript/gabsocial/actions/statuses.js @@ -4,6 +4,7 @@ import { evictStatus } from '../storage/modifier'; import { deleteFromTimelines } from './timelines'; import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer'; import { ensureComposeIsVisible } from './compose'; +import { openModal, closeModal } from './modal'; import { me } from 'gabsocial/initial_state'; export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST'; @@ -159,7 +160,7 @@ export function deleteStatus(id, routerHistory, withRedraft = false) { if (withRedraft) { dispatch(redraft(status, response.data.text)); - ensureComposeIsVisible(getState, routerHistory); + dispatch(openModal('COMPOSE')); } }).catch(error => { dispatch(deleteStatusFail(id, error)); @@ -272,7 +273,7 @@ export function muteStatusFail(id, error) { export function unmuteStatus(id) { return (dispatch, getState) => { if (!me) return; - + dispatch(unmuteStatusRequest(id)); api(getState).post(`/api/v1/statuses/${id}/unmute`).then(() => { From a2bb97d4127674bfffb6751fea5e5ab3c9d6aff3 Mon Sep 17 00:00:00 2001 From: mgabdev <> Date: Wed, 14 Aug 2019 23:02:48 -0400 Subject: [PATCH 05/38] Updated tabs bar updated responsiveness of tabs bar --- .../features/ui/components/tabs_bar.js | 120 ++++++++- .../styles/gabsocial/components/tabs-bar.scss | 251 +++++++++++++----- 2 files changed, 295 insertions(+), 76 deletions(-) diff --git a/app/javascript/gabsocial/features/ui/components/tabs_bar.js b/app/javascript/gabsocial/features/ui/components/tabs_bar.js index 1164aba2..ee4bce0b 100644 --- a/app/javascript/gabsocial/features/ui/components/tabs_bar.js +++ b/app/javascript/gabsocial/features/ui/components/tabs_bar.js @@ -2,11 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { NavLink, withRouter } from 'react-router-dom'; import { FormattedMessage, injectIntl } from 'react-intl'; -import { debounce } from 'lodash'; +import { throttle } from 'lodash'; import { connect } from 'react-redux'; -import { isUserTouching } from '../../../is_mobile'; import { me } from '../../../initial_state'; -import { Link } from 'react-router-dom'; +import classNames from 'classnames'; import NotificationsCounterIcon from './notifications_counter_icon'; import SearchContainer from 'gabsocial/features/compose/containers/search_container'; import Avatar from '../../../components/avatar'; @@ -14,35 +13,42 @@ import ActionBar from 'gabsocial/features/compose/components/action_bar'; import { openModal } from '../../../actions/modal'; export const privateLinks = [ - + , - + + , - + + , - + + , - + + , - + + , ]; export const publicLinks = [ - + , - + + , - + + , ]; @@ -56,16 +62,101 @@ class TabsBar extends React.PureComponent { onOpenCompose: PropTypes.func, } + state = { + collapsed: false, + } + + static contextTypes = { + router: PropTypes.object, + } + + lastScrollTop = 0; + + componentDidMount () { + this.window = window; + this.documentElement = document.scrollingElement || document.documentElement; + + this.attachScrollListener(); + // Handle initial scroll posiiton + this.handleScroll(); + } + + componentWillUnmount () { + this.detachScrollListener(); + } + setRef = ref => { this.node = ref; } + attachScrollListener () { + this.window.addEventListener('scroll', this.handleScroll); + } + + detachScrollListener () { + this.window.removeEventListener('scroll', this.handleScroll); + } + + handleScroll = throttle(() => { + if (this.window) { + const { pageYOffset, innerWidth } = this.window; + if (innerWidth > 895) return; + const { scrollTop } = this.documentElement; + + let st = pageYOffset || scrollTop; + if (st > this.lastScrollTop){ + let offset = st - this.lastScrollTop; + if (offset > 50) this.setState({collapsed: true}); + } else { + let offset = this.lastScrollTop - st; + if (offset > 50) this.setState({collapsed: false}); + } + + this.lastScrollTop = st <= 0 ? 0 : st; + } + }, 150, { + trailing: true, + }); + render () { - const { intl: { formatMessage }, account, onOpenCompose } = this.props; + const { intl: { formatMessage }, account, onOpenCompose, onOpenSidebar } = this.props; + const { collapsed } = this.state; const links = account ? privateLinks : publicLinks; + const pathname = this.context.router.route.location.pathname || ''; + let pathTitle = ''; + if (pathname.includes('/home')) { + pathTitle = 'Home'; + } else if (pathname.includes('/timeline/all')) { + pathTitle = 'All'; + } else if (pathname.includes('/group')) { + pathTitle = 'Groups'; + } else if (pathname.includes('/tags')) { + pathTitle = 'Tags'; + } else if (pathname.includes('/list')) { + pathTitle = 'Lists'; + } else if (pathname.includes('/notifications')) { + pathTitle = 'Notifications'; + } else if (pathname.includes('/search')) { + pathTitle = 'Search'; + } else if (pathname.includes('/follow_requests')) { + pathTitle = 'Requests'; + } else if (pathname.includes('/blocks')) { + pathTitle = 'Blocks'; + } else if (pathname.includes('/domain_blocks')) { + pathTitle = 'Domain Blocks'; + } else if (pathname.includes('/mutes')) { + pathTitle = 'Mutes'; + } else { + pathTitle = 'Profile'; + } + + const classes = classNames('tabs-bar', { + 'tabs-bar--collapsed': collapsed, + }) + return ( -