1 line
23 KiB
Plaintext
1 line
23 KiB
Plaintext
{"version":3,"sources":["webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/direct_timeline/components/conversation.js","webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js","webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js","webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/direct_timeline/containers/conversations_list_container.js","webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/direct_timeline/index.js"],"names":["messages","defineMessages","more","open","reply","markAsRead","delete","muteConversation","unmuteConversation","Conversation","injectIntl","context","router","props","lastStatus","unread","markRead","history","push","get","onMoveUp","conversationId","onMoveDown","onMute","onToggleHidden","render","this","accounts","intl","menu","text","formatMessage","action","handleClick","handleConversationMute","handleMarkAsRead","handleDelete","names","map","a","to","href","title","className","dangerouslySetInnerHTML","__html","reduce","prev","cur","handlers","handleReply","moveUp","handleHotkeyMoveUp","moveDown","handleHotkeyMoveDown","toggleHidden","handleShowMore","tabIndex","size","timestamp","id","defaultMessage","values","status","onClick","expanded","onExpandedToggle","collapsable","compact","media","icon","items","direction","ImmutablePureComponent","PropTypes","object","string","isRequired","ImmutablePropTypes","list","bool","func","replyConfirm","replyMessage","connect","getStatus","makeGetStatus","state","conversation","getIn","find","x","lastStatusId","accountId","dispatch","markConversationRead","_","getState","trim","length","openModal","message","confirm","onConfirm","replyCompose","deleteConversation","unmuteStatus","muteStatus","revealStatus","hideStatus","ConversationsList","conversations","findIndex","elementIndex","getCurrentIndex","_selectChild","c","node","last","onLoadMore","leading","index","align_top","container","element","querySelector","scrollTop","offsetTop","scrollIntoView","clientHeight","offsetHeight","focus","other","handleLoadOlder","scrollKey","ref","setRef","item","handleMoveUp","handleMoveDown","hasMore","isLoading","shouldUpdateScroll","maxId","expandConversations","DirectTimeline","columnId","removeColumn","addColumn","dir","moveColumn","column","componentDidMount","mountConversations","disconnect","connectDirectStream","componentWillUnmount","unmountConversations","hasUnread","multiColumn","pinned","bindToDocument","label","active","onPin","handlePin","onMove","handleMove","handleHeaderClick","trackScroll","timelineId","handleLoadMore","emptyMessage","React","PureComponent"],"mappings":"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","file":"features/direct_timeline.js","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport ImmutablePureComponent from 'react-immutable-pure-component';\nimport StatusContent from 'mastodon/components/status_content';\nimport AttachmentList from 'mastodon/components/attachment_list';\nimport { defineMessages, injectIntl, FormattedMessage } from 'react-intl';\nimport DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';\nimport AvatarComposite from 'mastodon/components/avatar_composite';\nimport Permalink from 'mastodon/components/permalink';\nimport IconButton from 'mastodon/components/icon_button';\nimport RelativeTimestamp from 'mastodon/components/relative_timestamp';\nimport { HotKeys } from 'react-hotkeys';\n\nconst messages = defineMessages({\n more: { id: 'status.more', defaultMessage: 'More' },\n open: { id: 'conversation.open', defaultMessage: 'View conversation' },\n reply: { id: 'status.reply', defaultMessage: 'Reply' },\n markAsRead: { id: 'conversation.mark_as_read', defaultMessage: 'Mark as read' },\n delete: { id: 'conversation.delete', defaultMessage: 'Delete conversation' },\n muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },\n unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },\n});\n\nexport default @injectIntl\nclass Conversation extends ImmutablePureComponent {\n\n static contextTypes = {\n router: PropTypes.object,\n };\n\n static propTypes = {\n conversationId: PropTypes.string.isRequired,\n accounts: ImmutablePropTypes.list.isRequired,\n lastStatus: ImmutablePropTypes.map,\n unread:PropTypes.bool.isRequired,\n onMoveUp: PropTypes.func,\n onMoveDown: PropTypes.func,\n markRead: PropTypes.func.isRequired,\n intl: PropTypes.object.isRequired,\n };\n\n handleClick = () => {\n if (!this.context.router) {\n return;\n }\n\n const { lastStatus, unread, markRead } = this.props;\n\n if (unread) {\n markRead();\n }\n\n this.context.router.history.push(`/statuses/${lastStatus.get('id')}`);\n }\n\n handleMarkAsRead = () => {\n this.props.markRead();\n }\n\n handleReply = () => {\n this.props.reply(this.props.lastStatus, this.context.router.history);\n }\n\n handleDelete = () => {\n this.props.delete();\n }\n\n handleHotkeyMoveUp = () => {\n this.props.onMoveUp(this.props.conversationId);\n }\n\n handleHotkeyMoveDown = () => {\n this.props.onMoveDown(this.props.conversationId);\n }\n\n handleConversationMute = () => {\n this.props.onMute(this.props.lastStatus);\n }\n\n handleShowMore = () => {\n this.props.onToggleHidden(this.props.lastStatus);\n }\n\n render () {\n const { accounts, lastStatus, unread, intl } = this.props;\n\n if (lastStatus === null) {\n return null;\n }\n\n const menu = [\n { text: intl.formatMessage(messages.open), action: this.handleClick },\n null,\n ];\n\n menu.push({ text: intl.formatMessage(lastStatus.get('muted') ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMute });\n\n if (unread) {\n menu.push({ text: intl.formatMessage(messages.markAsRead), action: this.handleMarkAsRead });\n menu.push(null);\n }\n\n menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete });\n\n const names = accounts.map(a => <Permalink to={`/accounts/${a.get('id')}`} href={a.get('url')} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Permalink>).reduce((prev, cur) => [prev, ', ', cur]);\n\n const handlers = {\n reply: this.handleReply,\n open: this.handleClick,\n moveUp: this.handleHotkeyMoveUp,\n moveDown: this.handleHotkeyMoveDown,\n toggleHidden: this.handleShowMore,\n };\n\n return (\n <HotKeys handlers={handlers}>\n <div className='conversation focusable muted' tabIndex='0'>\n <div className='conversation__avatar'>\n <AvatarComposite accounts={accounts} size={48} />\n </div>\n\n <div className='conversation__content'>\n <div className='conversation__content__info'>\n <div className='conversation__content__relative-time'>\n <RelativeTimestamp timestamp={lastStatus.get('created_at')} />\n </div>\n\n <div className='conversation__content__names'>\n <FormattedMessage id='conversation.with' defaultMessage='With {names}' values={{ names: <span>{names}</span> }} />\n </div>\n </div>\n\n <StatusContent\n status={lastStatus}\n onClick={this.handleClick}\n expanded={!lastStatus.get('hidden')}\n onExpandedToggle={this.handleShowMore}\n collapsable\n />\n\n {lastStatus.get('media_attachments').size > 0 && (\n <AttachmentList\n compact\n media={lastStatus.get('media_attachments')}\n />\n )}\n\n <div className='status__action-bar'>\n <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.reply)} icon='reply' onClick={this.handleReply} />\n\n <div className='status__action-bar-dropdown'>\n <DropdownMenuContainer status={lastStatus} items={menu} icon='ellipsis-h' size={18} direction='right' title={intl.formatMessage(messages.more)} />\n </div>\n </div>\n </div>\n </div>\n </HotKeys>\n );\n }\n\n}\n","import { connect } from 'react-redux';\nimport Conversation from '../components/conversation';\nimport { markConversationRead, deleteConversation } from 'mastodon/actions/conversations';\nimport { makeGetStatus } from 'mastodon/selectors';\nimport { replyCompose } from 'mastodon/actions/compose';\nimport { openModal } from 'mastodon/actions/modal';\nimport { muteStatus, unmuteStatus, hideStatus, revealStatus } from 'mastodon/actions/statuses';\nimport { defineMessages, injectIntl } from 'react-intl';\n\nconst messages = defineMessages({\n replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },\n replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },\n});\n\nconst mapStateToProps = () => {\n const getStatus = makeGetStatus();\n\n return (state, { conversationId }) => {\n const conversation = state.getIn(['conversations', 'items']).find(x => x.get('id') === conversationId);\n const lastStatusId = conversation.get('last_status', null);\n\n return {\n accounts: conversation.get('accounts').map(accountId => state.getIn(['accounts', accountId], null)),\n unread: conversation.get('unread'),\n lastStatus: lastStatusId && getStatus(state, { id: lastStatusId }),\n };\n };\n};\n\nconst mapDispatchToProps = (dispatch, { intl, conversationId }) => ({\n\n markRead () {\n dispatch(markConversationRead(conversationId));\n },\n\n reply (status, router) {\n dispatch((_, getState) => {\n let state = getState();\n\n if (state.getIn(['compose', 'text']).trim().length !== 0) {\n dispatch(openModal('CONFIRM', {\n message: intl.formatMessage(messages.replyMessage),\n confirm: intl.formatMessage(messages.replyConfirm),\n onConfirm: () => dispatch(replyCompose(status, router)),\n }));\n } else {\n dispatch(replyCompose(status, router));\n }\n });\n },\n\n delete () {\n dispatch(deleteConversation(conversationId));\n },\n\n onMute (status) {\n if (status.get('muted')) {\n dispatch(unmuteStatus(status.get('id')));\n } else {\n dispatch(muteStatus(status.get('id')));\n }\n },\n\n onToggleHidden (status) {\n if (status.get('hidden')) {\n dispatch(revealStatus(status.get('id')));\n } else {\n dispatch(hideStatus(status.get('id')));\n }\n },\n\n});\n\nexport default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Conversation));\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport ImmutablePureComponent from 'react-immutable-pure-component';\nimport ConversationContainer from '../containers/conversation_container';\nimport ScrollableList from '../../../components/scrollable_list';\nimport { debounce } from 'lodash';\n\nexport default class ConversationsList extends ImmutablePureComponent {\n\n static propTypes = {\n conversations: ImmutablePropTypes.list.isRequired,\n hasMore: PropTypes.bool,\n isLoading: PropTypes.bool,\n onLoadMore: PropTypes.func,\n shouldUpdateScroll: PropTypes.func,\n };\n\n getCurrentIndex = id => this.props.conversations.findIndex(x => x.get('id') === id)\n\n handleMoveUp = id => {\n const elementIndex = this.getCurrentIndex(id) - 1;\n this._selectChild(elementIndex, true);\n }\n\n handleMoveDown = id => {\n const elementIndex = this.getCurrentIndex(id) + 1;\n this._selectChild(elementIndex, false);\n }\n\n _selectChild (index, align_top) {\n const container = this.node.node;\n const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);\n\n if (element) {\n if (align_top && container.scrollTop > element.offsetTop) {\n element.scrollIntoView(true);\n } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {\n element.scrollIntoView(false);\n }\n element.focus();\n }\n }\n\n setRef = c => {\n this.node = c;\n }\n\n handleLoadOlder = debounce(() => {\n const last = this.props.conversations.last();\n\n if (last && last.get('last_status')) {\n this.props.onLoadMore(last.get('last_status'));\n }\n }, 300, { leading: true })\n\n render () {\n const { conversations, onLoadMore, ...other } = this.props;\n\n return (\n <ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} scrollKey='direct' ref={this.setRef}>\n {conversations.map(item => (\n <ConversationContainer\n key={item.get('id')}\n conversationId={item.get('id')}\n onMoveUp={this.handleMoveUp}\n onMoveDown={this.handleMoveDown}\n />\n ))}\n </ScrollableList>\n );\n }\n\n}\n","import { connect } from 'react-redux';\nimport ConversationsList from '../components/conversations_list';\nimport { expandConversations } from '../../../actions/conversations';\n\nconst mapStateToProps = state => ({\n conversations: state.getIn(['conversations', 'items']),\n isLoading: state.getIn(['conversations', 'isLoading'], true),\n hasMore: state.getIn(['conversations', 'hasMore'], false),\n});\n\nconst mapDispatchToProps = dispatch => ({\n onLoadMore: maxId => dispatch(expandConversations({ maxId })),\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ConversationsList);\n","import React from 'react';\nimport { connect } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport Column from '../../components/column';\nimport ColumnHeader from '../../components/column_header';\nimport { mountConversations, unmountConversations, expandConversations } from '../../actions/conversations';\nimport { addColumn, removeColumn, moveColumn } from '../../actions/columns';\nimport { defineMessages, injectIntl, FormattedMessage } from 'react-intl';\nimport { connectDirectStream } from '../../actions/streaming';\nimport ConversationsListContainer from './containers/conversations_list_container';\n\nconst messages = defineMessages({\n title: { id: 'column.direct', defaultMessage: 'Direct messages' },\n});\n\nexport default @connect()\n@injectIntl\nclass DirectTimeline extends React.PureComponent {\n\n static propTypes = {\n dispatch: PropTypes.func.isRequired,\n shouldUpdateScroll: PropTypes.func,\n columnId: PropTypes.string,\n intl: PropTypes.object.isRequired,\n hasUnread: PropTypes.bool,\n multiColumn: PropTypes.bool,\n };\n\n handlePin = () => {\n const { columnId, dispatch } = this.props;\n\n if (columnId) {\n dispatch(removeColumn(columnId));\n } else {\n dispatch(addColumn('DIRECT', {}));\n }\n }\n\n handleMove = (dir) => {\n const { columnId, dispatch } = this.props;\n dispatch(moveColumn(columnId, dir));\n }\n\n handleHeaderClick = () => {\n this.column.scrollTop();\n }\n\n componentDidMount () {\n const { dispatch } = this.props;\n\n dispatch(mountConversations());\n dispatch(expandConversations());\n this.disconnect = dispatch(connectDirectStream());\n }\n\n componentWillUnmount () {\n this.props.dispatch(unmountConversations());\n\n if (this.disconnect) {\n this.disconnect();\n this.disconnect = null;\n }\n }\n\n setRef = c => {\n this.column = c;\n }\n\n handleLoadMore = maxId => {\n this.props.dispatch(expandConversations({ maxId }));\n }\n\n render () {\n const { intl, hasUnread, columnId, multiColumn, shouldUpdateScroll } = this.props;\n const pinned = !!columnId;\n\n return (\n <Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}>\n <ColumnHeader\n icon='envelope'\n active={hasUnread}\n title={intl.formatMessage(messages.title)}\n onPin={this.handlePin}\n onMove={this.handleMove}\n onClick={this.handleHeaderClick}\n pinned={pinned}\n multiColumn={multiColumn}\n />\n\n <ConversationsListContainer\n trackScroll={!pinned}\n scrollKey={`direct_timeline-${columnId}`}\n timelineId='direct'\n onLoadMore={this.handleLoadMore}\n emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage=\"You don't have any direct messages yet. When you send or receive one, it will show up here.\" />}\n shouldUpdateScroll={shouldUpdateScroll}\n />\n </Column>\n );\n }\n\n}\n"],"sourceRoot":""} |