Add topic modal
This commit is contained in:
parent
aab1ad3e99
commit
24960f23b9
File diff suppressed because one or more lines are too long
@ -19,6 +19,15 @@ h6 {
|
||||
font-family: Montserrat, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0066ff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
input {
|
||||
font: 16px Roboto Mono, monospace;
|
||||
border: none;
|
||||
@ -504,20 +513,24 @@ input::-webkit-inner-spin-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editable-wrap {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.editable-wrap-editable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chat-title {
|
||||
margin-left: 10px;
|
||||
padding: 0 5px;
|
||||
margin-left: 15px;
|
||||
font: 24px Montserrat, sans-serif;
|
||||
font-weight: 700;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.chat-server .chat-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input.chat-title {
|
||||
background: none;
|
||||
cursor: text !important;
|
||||
@ -526,7 +539,7 @@ input.chat-title {
|
||||
.chat-topic-wrap {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
margin: 0 15px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.chat-topic {
|
||||
@ -535,20 +548,12 @@ input.chat-title {
|
||||
top: 3px;
|
||||
font-size: 16px;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.chat-topic a {
|
||||
color: #999;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.chat-topic a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.userlist-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -705,15 +710,6 @@ input.chat-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.message a {
|
||||
text-decoration: none;
|
||||
color: #0066ff;
|
||||
}
|
||||
|
||||
.message a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.message-input-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@ -751,7 +747,7 @@ input.message-input-nick.invalid {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 15px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.userlist {
|
||||
@ -954,6 +950,27 @@ input.message-input-nick.invalid {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.modal-channel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -980,12 +997,6 @@ input.message-input-nick.invalid {
|
||||
.modal-channel-close {
|
||||
padding: 15px;
|
||||
background: #fff;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-channel-close:hover {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.modal-channel-result {
|
||||
@ -1057,8 +1068,12 @@ input.message-input-nick.invalid {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.chat-topic {
|
||||
font-size: 12px;
|
||||
.chat-title-bar .editable-wrap {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.chat-topic-wrap {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.userlist-bar {
|
||||
|
@ -114,7 +114,10 @@ const AddChannel = ({ search, payload: { server }, onClose, ...props }) => {
|
||||
onKeyDown={handleKey}
|
||||
onChange={handleSearch}
|
||||
/>
|
||||
<i className="icon-cancel modal-channel-close" onClick={onClose} />
|
||||
<i
|
||||
className="icon-cancel modal-close modal-channel-close"
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
<div ref={resultsEl} className="modal-channel-results">
|
||||
{search.results.map(channel => (
|
||||
|
19
client/js/components/modals/Topic.js
Normal file
19
client/js/components/modals/Topic.js
Normal file
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import withModal from 'components/modals/withModal';
|
||||
import { linkify } from 'utils';
|
||||
|
||||
const Topic = ({ payload: { topic, channel }, onClose }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="modal-header">
|
||||
<h2>Topic in {channel}</h2>
|
||||
<i className="icon-cancel modal-close" onClick={onClose} />
|
||||
</div>
|
||||
<p className="modal-content">{linkify(topic)}</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default withModal({
|
||||
name: 'topic'
|
||||
})(Topic);
|
@ -1,11 +1,13 @@
|
||||
import React, { memo } from 'react';
|
||||
import AddChannel from 'components/modals/AddChannel';
|
||||
import Confirm from 'components/modals/Confirm';
|
||||
import Topic from 'components/modals/Topic';
|
||||
|
||||
const Modals = () => (
|
||||
<>
|
||||
<AddChannel />
|
||||
<Confirm />
|
||||
<Topic />
|
||||
</>
|
||||
);
|
||||
|
||||
|
@ -65,6 +65,7 @@ export default class Chat extends Component {
|
||||
addFetchedMessages,
|
||||
fetchMessages,
|
||||
inputActions,
|
||||
openModal,
|
||||
runCommand,
|
||||
sendMessage,
|
||||
toggleSearch,
|
||||
@ -86,6 +87,7 @@ export default class Chat extends Component {
|
||||
status={status}
|
||||
tab={tab}
|
||||
title={title}
|
||||
openModal={openModal}
|
||||
onCloseClick={this.handleCloseClick}
|
||||
onTitleChange={this.handleTitleChange}
|
||||
onToggleSearch={toggleSearch}
|
||||
|
@ -2,13 +2,14 @@ import React, { memo } from 'react';
|
||||
import Navicon from 'containers/Navicon';
|
||||
import Editable from 'components/ui/Editable';
|
||||
import { isValidServerName } from 'state/servers';
|
||||
import { isChannel, linkify } from 'utils';
|
||||
import { isChannel } from 'utils';
|
||||
|
||||
const ChatTitle = ({
|
||||
status,
|
||||
title,
|
||||
tab,
|
||||
channel,
|
||||
openModal,
|
||||
onTitleChange,
|
||||
onToggleSearch,
|
||||
onToggleUserList,
|
||||
@ -44,9 +45,19 @@ const ChatTitle = ({
|
||||
<span className="chat-title">{title}</span>
|
||||
</Editable>
|
||||
<div className="chat-topic-wrap">
|
||||
<span className="chat-topic">
|
||||
{channel && linkify(channel.topic)}
|
||||
</span>
|
||||
{channel && channel.topic && (
|
||||
<span
|
||||
className="chat-topic"
|
||||
onClick={() =>
|
||||
openModal('topic', {
|
||||
topic: channel.topic,
|
||||
channel: channel.name
|
||||
})
|
||||
}
|
||||
>
|
||||
{channel.topic}
|
||||
</span>
|
||||
)}
|
||||
{serverError}
|
||||
</div>
|
||||
<i className="icon-search" title="Search" onClick={onToggleSearch} />
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { PureComponent, createRef } from 'react';
|
||||
import cn from 'classnames';
|
||||
import { stringWidth } from 'utils';
|
||||
|
||||
export default class Editable extends PureComponent {
|
||||
@ -75,7 +76,7 @@ export default class Editable extends PureComponent {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { children, className, value } = this.props;
|
||||
const { children, className, editable, value } = this.props;
|
||||
|
||||
const style = {
|
||||
width: this.state.width,
|
||||
@ -86,7 +87,7 @@ export default class Editable extends PureComponent {
|
||||
return this.state.editing ? (
|
||||
<input
|
||||
ref={this.inputEl}
|
||||
className={className}
|
||||
className={`editable-wrap ${className}`}
|
||||
type="text"
|
||||
value={value}
|
||||
onBlur={this.handleBlur}
|
||||
@ -97,7 +98,14 @@ export default class Editable extends PureComponent {
|
||||
spellCheck={false}
|
||||
/>
|
||||
) : (
|
||||
<div onClick={this.startEditing}>{children}</div>
|
||||
<div
|
||||
className={cn('editable-wrap', {
|
||||
'editable-wrap-editable': editable
|
||||
})}
|
||||
onClick={this.startEditing}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
fetchMessages,
|
||||
addFetchedMessages
|
||||
} from 'state/messages';
|
||||
import { openModal } from 'state/modals';
|
||||
import { openPrivateChat, closePrivateChat } from 'state/privateChats';
|
||||
import { getSearch, searchMessages, toggleSearch } from 'state/search';
|
||||
import {
|
||||
@ -58,6 +59,7 @@ const mapDispatch = dispatch => ({
|
||||
closePrivateChat,
|
||||
disconnect,
|
||||
fetchMessages,
|
||||
openModal,
|
||||
openPrivateChat,
|
||||
part,
|
||||
runCommand,
|
||||
|
@ -61,7 +61,7 @@ function init(state, server, channel) {
|
||||
state[server] = {};
|
||||
}
|
||||
if (channel && !state[server][channel]) {
|
||||
state[server][channel] = { users: [], joined: false };
|
||||
state[server][channel] = { name: channel, users: [], joined: false };
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,6 +135,7 @@ export default createReducer(
|
||||
[actions.socket.JOIN](state, { server, channels, user }) {
|
||||
const channel = channels[0];
|
||||
init(state, server, channel);
|
||||
state[server][channel].name = channel;
|
||||
state[server][channel].joined = true;
|
||||
state[server][channel].users.push(createUser(user));
|
||||
},
|
||||
|
@ -80,7 +80,7 @@ func (d *Dispatch) initFileServer() {
|
||||
|
||||
if cfg.Dev {
|
||||
renderIndexPage(indexTemplateData{
|
||||
Scripts: []string{"boot.js", "main.js"},
|
||||
Scripts: []string{"/boot.js", "/main.js"},
|
||||
})
|
||||
} else {
|
||||
bootloader := decompressedAsset(findAssetName("boot*.js"))
|
||||
|
Loading…
Reference in New Issue
Block a user