Send the 25 last messages for each channel to the client on load
This commit is contained in:
parent
c840d51e16
commit
eedc687f18
File diff suppressed because one or more lines are too long
@ -1,13 +1,14 @@
|
|||||||
import * as actions from '../actions';
|
import * as actions from '../actions';
|
||||||
import { findBreakpoints, messageHeight, linkify, timestamp } from '../util';
|
import { findBreakpoints, messageHeight, linkify, timestamp } from '../util';
|
||||||
|
|
||||||
function initMessage(message, state) {
|
function initMessage(message, server, tab, state) {
|
||||||
message.dest = message.to || message.from || message.server;
|
if (message.time) {
|
||||||
if (message.from && message.from.indexOf('.') !== -1) {
|
message.time = timestamp(new Date(message.time * 1000));
|
||||||
message.dest = message.server;
|
} else {
|
||||||
|
message.time = timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.dest.charAt(0) === '#') {
|
if (tab.charAt(0) === '#') {
|
||||||
message.channel = true;
|
message.channel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +33,13 @@ function initMessage(message, state) {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMessageTab(server, to) {
|
||||||
|
if (!to || to.indexOf('.') !== -1) {
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
export function updateMessageHeight() {
|
export function updateMessageHeight() {
|
||||||
return (dispatch, getState) => dispatch({
|
return (dispatch, getState) => dispatch({
|
||||||
type: actions.UPDATE_MESSAGE_HEIGHT,
|
type: actions.UPDATE_MESSAGE_HEIGHT,
|
||||||
@ -46,13 +54,12 @@ export function sendMessage(content, to, server) {
|
|||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: actions.SEND_MESSAGE,
|
type: actions.SEND_MESSAGE,
|
||||||
|
server,
|
||||||
|
tab: to,
|
||||||
message: initMessage({
|
message: initMessage({
|
||||||
from: state.servers.getIn([server, 'nick']),
|
from: state.servers.getIn([server, 'nick']),
|
||||||
content,
|
content
|
||||||
to,
|
}, server, to, state),
|
||||||
server,
|
|
||||||
time: timestamp()
|
|
||||||
}, state),
|
|
||||||
socket: {
|
socket: {
|
||||||
type: 'message',
|
type: 'message',
|
||||||
data: { content, to, server }
|
data: { content, to, server }
|
||||||
@ -61,27 +68,29 @@ export function sendMessage(content, to, server) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addMessage(message) {
|
export function addMessage(message, server, to) {
|
||||||
message.time = timestamp();
|
const tab = getMessageTab(server, to);
|
||||||
|
|
||||||
return (dispatch, getState) => dispatch({
|
return (dispatch, getState) => dispatch({
|
||||||
type: actions.ADD_MESSAGE,
|
type: actions.ADD_MESSAGE,
|
||||||
message: initMessage(message, getState())
|
server,
|
||||||
|
tab,
|
||||||
|
message: initMessage(message, server, tab, getState())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addMessages(messages) {
|
export function addMessages(messages, server, to) {
|
||||||
const now = timestamp();
|
const tab = getMessageTab(server, to);
|
||||||
|
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
messages.forEach(message => {
|
messages.forEach(message => initMessage(message, server, message.tab || tab, state));
|
||||||
initMessage(message, state).time = now;
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: actions.ADD_MESSAGES,
|
type: actions.ADD_MESSAGES,
|
||||||
|
server,
|
||||||
|
tab,
|
||||||
messages
|
messages
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -89,29 +98,24 @@ export function addMessages(messages) {
|
|||||||
|
|
||||||
export function broadcast(message, server, channels) {
|
export function broadcast(message, server, channels) {
|
||||||
return addMessages(channels.map(channel => ({
|
return addMessages(channels.map(channel => ({
|
||||||
server,
|
tab: channel,
|
||||||
to: channel,
|
|
||||||
content: message,
|
content: message,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})));
|
})), server);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inform(message, server, channel) {
|
export function inform(message, server, channel) {
|
||||||
if (Array.isArray(message)) {
|
if (Array.isArray(message)) {
|
||||||
return addMessages(message.map(line => ({
|
return addMessages(message.map(line => ({
|
||||||
server,
|
|
||||||
to: channel,
|
|
||||||
content: line,
|
content: line,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})));
|
})), server, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return addMessage({
|
return addMessage({
|
||||||
server,
|
|
||||||
to: channel,
|
|
||||||
content: message,
|
content: message,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
});
|
}, server, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runCommand(command, channel, server) {
|
export function runCommand(command, channel, server) {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { push, replace } from 'react-router-redux';
|
import { push, replace } from 'react-router-redux';
|
||||||
import * as actions from '../actions';
|
import * as actions from '../actions';
|
||||||
|
|
||||||
export function select(server, channel, pm) {
|
export function select(server, name) {
|
||||||
|
const pm = name && name.charAt(0) !== '#';
|
||||||
if (pm) {
|
if (pm) {
|
||||||
return push(`/${server}/pm/${channel}`);
|
return push(`/${server}/pm/${name}`);
|
||||||
} else if (channel) {
|
} else if (name) {
|
||||||
return push(`/${server}/${encodeURIComponent(channel)}`);
|
return push(`/${server}/${encodeURIComponent(name)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return push(`/${server}`);
|
return push(`/${server}`);
|
||||||
@ -22,7 +23,7 @@ export function updateSelection() {
|
|||||||
dispatch(replace('/connect'));
|
dispatch(replace('/connect'));
|
||||||
} else if (history.size > 0) {
|
} else if (history.size > 0) {
|
||||||
const tab = history.last();
|
const tab = history.last();
|
||||||
dispatch(select(tab.server, tab.channel || tab.user, tab.user));
|
dispatch(select(tab.server, tab.name));
|
||||||
} else if (servers.has(server)) {
|
} else if (servers.has(server)) {
|
||||||
dispatch(select(server));
|
dispatch(select(server));
|
||||||
} else {
|
} else {
|
||||||
@ -31,18 +32,10 @@ export function updateSelection() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setSelectedChannel(server, channel = null) {
|
export function setSelectedTab(server, name = null) {
|
||||||
return {
|
return {
|
||||||
type: actions.SELECT_TAB,
|
type: actions.SELECT_TAB,
|
||||||
server,
|
server,
|
||||||
channel
|
name
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setSelectedUser(server, user = null) {
|
|
||||||
return {
|
|
||||||
type: actions.SELECT_TAB,
|
|
||||||
server,
|
|
||||||
user
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ export default class ChatTitle extends PureComponent {
|
|||||||
handleLeaveClick = () => {
|
handleLeaveClick = () => {
|
||||||
const { tab, disconnect, part, closePrivateChat } = this.props;
|
const { tab, disconnect, part, closePrivateChat } = this.props;
|
||||||
|
|
||||||
if (tab.channel) {
|
if (tab.isChannel()) {
|
||||||
part([tab.channel], tab.server);
|
part([tab.name], tab.server);
|
||||||
} else if (tab.user) {
|
} else if (tab.name) {
|
||||||
closePrivateChat(tab.server, tab.user);
|
closePrivateChat(tab.server, tab.name);
|
||||||
} else {
|
} else {
|
||||||
disconnect(tab.server);
|
disconnect(tab.server);
|
||||||
}
|
}
|
||||||
@ -22,9 +22,9 @@ export default class ChatTitle extends PureComponent {
|
|||||||
topic = topic ? linkify(topic) : null;
|
topic = topic ? linkify(topic) : null;
|
||||||
|
|
||||||
let leaveTitle;
|
let leaveTitle;
|
||||||
if (tab.channel) {
|
if (tab.isChannel()) {
|
||||||
leaveTitle = 'Leave';
|
leaveTitle = 'Leave';
|
||||||
} else if (tab.user) {
|
} else if (tab.name) {
|
||||||
leaveTitle = 'Close';
|
leaveTitle = 'Close';
|
||||||
} else {
|
} else {
|
||||||
leaveTitle = 'Disconnect';
|
leaveTitle = 'Disconnect';
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
export default class Message extends PureComponent {
|
export default class Message extends PureComponent {
|
||||||
handleSenderClick = () => {
|
handleNickClick = () => this.props.onNickClick(this.props.message);
|
||||||
const { message, openPrivateChat, select } = this.props;
|
|
||||||
|
|
||||||
openPrivateChat(message.server, message.from);
|
|
||||||
select(message.server, message.from, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { message } = this.props;
|
const { message } = this.props;
|
||||||
@ -21,7 +16,7 @@ export default class Message extends PureComponent {
|
|||||||
<p className={className} style={style}>
|
<p className={className} style={style}>
|
||||||
<span className="message-time">{message.time}</span>
|
<span className="message-time">{message.time}</span>
|
||||||
{message.from &&
|
{message.from &&
|
||||||
<span className="message-sender" onClick={this.handleSenderClick}>
|
<span className="message-sender" onClick={this.handleNickClick}>
|
||||||
{' '}{message.from}
|
{' '}{message.from}
|
||||||
</span>
|
</span>
|
||||||
}{' '}{message.content}
|
}{' '}{message.content}
|
||||||
|
@ -31,11 +31,11 @@ export default class MessageBox extends PureComponent {
|
|||||||
listRef = el => { this.list = el; };
|
listRef = el => { this.list = el; };
|
||||||
|
|
||||||
updateWidth = (width) => {
|
updateWidth = (width) => {
|
||||||
const { isChannel, setWrapWidth, updateMessageHeight } = this.props;
|
const { tab, setWrapWidth, updateMessageHeight } = this.props;
|
||||||
let wrapWidth = width || this.width;
|
let wrapWidth = width || this.width;
|
||||||
|
|
||||||
if (width) {
|
if (width) {
|
||||||
if (isChannel && window.innerWidth > 600) {
|
if (tab.isChannel() && window.innerWidth > 600) {
|
||||||
wrapWidth += 200;
|
wrapWidth += 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +64,14 @@ export default class MessageBox extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderMessage = ({ index, style, key }) => {
|
renderMessage = ({ index, style, key }) => {
|
||||||
const { messages, select, openPrivateChat } = this.props;
|
const { messages, onNickClick } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Message
|
<Message
|
||||||
key={key}
|
key={key}
|
||||||
message={messages.get(index)}
|
message={messages.get(index)}
|
||||||
select={select}
|
|
||||||
openPrivateChat={openPrivateChat}
|
|
||||||
style={style}
|
style={style}
|
||||||
|
onNickClick={onNickClick}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,11 +11,9 @@ export default class MessageInput extends PureComponent {
|
|||||||
|
|
||||||
if (e.which === 13 && e.target.value) {
|
if (e.which === 13 && e.target.value) {
|
||||||
if (e.target.value[0] === '/') {
|
if (e.target.value[0] === '/') {
|
||||||
runCommand(e.target.value, tab.channel || tab.user, tab.server);
|
runCommand(e.target.value, tab.name, tab.server);
|
||||||
} else if (tab.channel) {
|
} else if (tab.name) {
|
||||||
sendMessage(e.target.value, tab.channel, tab.server);
|
sendMessage(e.target.value, tab.name, tab.server);
|
||||||
} else if (tab.user) {
|
|
||||||
sendMessage(e.target.value, tab.user, tab.server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addInputHistory(e.target.value);
|
addInputHistory(e.target.value);
|
||||||
|
@ -3,7 +3,7 @@ import TabListItem from './TabListItem';
|
|||||||
|
|
||||||
export default class TabList extends PureComponent {
|
export default class TabList extends PureComponent {
|
||||||
handleTabClick = (server, target) => {
|
handleTabClick = (server, target) => {
|
||||||
this.props.select(server, target, target && target.charAt(0) !== '#');
|
this.props.select(server, target);
|
||||||
this.props.hideMenu();
|
this.props.hideMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export default class TabList extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { channels, servers, privateChats, showTabList, selected } = this.props;
|
const { tab, channels, servers, privateChats, showTabList } = this.props;
|
||||||
const className = showTabList ? 'tablist off-canvas' : 'tablist';
|
const className = showTabList ? 'tablist off-canvas' : 'tablist';
|
||||||
const tabs = [];
|
const tabs = [];
|
||||||
|
|
||||||
@ -28,11 +28,7 @@ export default class TabList extends PureComponent {
|
|||||||
key={address}
|
key={address}
|
||||||
server={address}
|
server={address}
|
||||||
content={servers.getIn([address, 'name'])}
|
content={servers.getIn([address, 'name'])}
|
||||||
selected={
|
selected={tab.server === address && tab.name === null}
|
||||||
selected.server === address &&
|
|
||||||
selected.channel === null &&
|
|
||||||
selected.user === null
|
|
||||||
}
|
|
||||||
connected={servers.getIn([address, 'connected'])}
|
connected={servers.getIn([address, 'connected'])}
|
||||||
onClick={this.handleTabClick}
|
onClick={this.handleTabClick}
|
||||||
/>
|
/>
|
||||||
@ -44,7 +40,7 @@ export default class TabList extends PureComponent {
|
|||||||
server={address}
|
server={address}
|
||||||
target={name}
|
target={name}
|
||||||
content={name}
|
content={name}
|
||||||
selected={selected.server === address && selected.channel === name}
|
selected={tab.server === address && tab.name === name}
|
||||||
onClick={this.handleTabClick}
|
onClick={this.handleTabClick}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
@ -56,7 +52,7 @@ export default class TabList extends PureComponent {
|
|||||||
server={address}
|
server={address}
|
||||||
target={nick}
|
target={nick}
|
||||||
content={nick}
|
content={nick}
|
||||||
selected={selected.server === address && selected.user === nick}
|
selected={tab.server === address && tab.name === nick}
|
||||||
onClick={this.handleTabClick}
|
onClick={this.handleTabClick}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
@ -34,7 +34,7 @@ export default class UserList extends PureComponent {
|
|||||||
const className = showUserList ? 'userlist off-canvas' : 'userlist';
|
const className = showUserList ? 'userlist off-canvas' : 'userlist';
|
||||||
const style = {};
|
const style = {};
|
||||||
|
|
||||||
if (!tab.channel) {
|
if (!tab.isChannel()) {
|
||||||
style.display = 'none';
|
style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ function mapStateToProps(state) {
|
|||||||
channels: state.channels,
|
channels: state.channels,
|
||||||
privateChats: state.privateChats,
|
privateChats: state.privateChats,
|
||||||
showTabList: state.ui.showTabList,
|
showTabList: state.ui.showTabList,
|
||||||
selected: state.tab.selected
|
tab: state.tab.selected
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import UserList from '../components/UserList';
|
|||||||
import { part } from '../actions/channel';
|
import { part } from '../actions/channel';
|
||||||
import { openPrivateChat, closePrivateChat } from '../actions/privateChat';
|
import { openPrivateChat, closePrivateChat } from '../actions/privateChat';
|
||||||
import { searchMessages, toggleSearch } from '../actions/search';
|
import { searchMessages, toggleSearch } from '../actions/search';
|
||||||
import { select, setSelectedChannel, setSelectedUser } from '../actions/tab';
|
import { select, setSelectedTab } from '../actions/tab';
|
||||||
import { runCommand, sendMessage, updateMessageHeight } from '../actions/message';
|
import { runCommand, sendMessage, updateMessageHeight } from '../actions/message';
|
||||||
import { disconnect } from '../actions/server';
|
import { disconnect } from '../actions/server';
|
||||||
import { setWrapWidth, setCharWidth } from '../actions/environment';
|
import { setWrapWidth, setCharWidth } from '../actions/environment';
|
||||||
@ -20,12 +20,8 @@ import { toggleUserList } from '../actions/ui';
|
|||||||
import * as inputHistoryActions from '../actions/inputHistory';
|
import * as inputHistoryActions from '../actions/inputHistory';
|
||||||
|
|
||||||
function updateSelected({ params, dispatch }) {
|
function updateSelected({ params, dispatch }) {
|
||||||
if (params.channel) {
|
if (params.server) {
|
||||||
dispatch(setSelectedChannel(params.server, params.channel));
|
dispatch(setSelectedTab(params.server, params.channel || params.user));
|
||||||
} else if (params.user) {
|
|
||||||
dispatch(setSelectedUser(params.server, params.user));
|
|
||||||
} else if (params.server) {
|
|
||||||
dispatch(setSelectedChannel(params.server));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,19 +52,26 @@ class Chat extends PureComponent {
|
|||||||
|
|
||||||
handleSearch = phrase => {
|
handleSearch = phrase => {
|
||||||
const { dispatch, tab } = this.props;
|
const { dispatch, tab } = this.props;
|
||||||
if (tab.channel) {
|
if (tab.isChannel()) {
|
||||||
dispatch(searchMessages(tab.server, tab.channel, phrase));
|
dispatch(searchMessages(tab.server, tab.name, phrase));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleMessageNickClick = message => {
|
||||||
|
const { tab } = this.props;
|
||||||
|
|
||||||
|
this.props.openPrivateChat(tab.server, message.from);
|
||||||
|
this.props.select(tab.server, message.from);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { title, tab, channel, search, history,
|
const { title, tab, channel, search, history,
|
||||||
messages, users, showUserList, inputActions } = this.props;
|
messages, users, showUserList, inputActions } = this.props;
|
||||||
|
|
||||||
let chatClass;
|
let chatClass;
|
||||||
if (tab.channel) {
|
if (tab.isChannel()) {
|
||||||
chatClass = 'chat-channel';
|
chatClass = 'chat-channel';
|
||||||
} else if (tab.user) {
|
} else if (tab.name) {
|
||||||
chatClass = 'chat-private';
|
chatClass = 'chat-private';
|
||||||
} else {
|
} else {
|
||||||
chatClass = 'chat-server';
|
chatClass = 'chat-server';
|
||||||
@ -92,12 +95,10 @@ class Chat extends PureComponent {
|
|||||||
/>
|
/>
|
||||||
<MessageBox
|
<MessageBox
|
||||||
messages={messages}
|
messages={messages}
|
||||||
isChannel={tab.channel !== null}
|
|
||||||
tab={tab}
|
tab={tab}
|
||||||
setWrapWidth={this.props.setWrapWidth}
|
setWrapWidth={this.props.setWrapWidth}
|
||||||
updateMessageHeight={this.props.updateMessageHeight}
|
updateMessageHeight={this.props.updateMessageHeight}
|
||||||
select={this.props.select}
|
onNickClick={this.handleMessageNickClick}
|
||||||
openPrivateChat={this.props.openPrivateChat}
|
|
||||||
/>
|
/>
|
||||||
<MessageInput
|
<MessageInput
|
||||||
tab={tab}
|
tab={tab}
|
||||||
@ -136,13 +137,13 @@ const historySelector = state => {
|
|||||||
const selectedMessagesSelector = createSelector(
|
const selectedMessagesSelector = createSelector(
|
||||||
tabSelector,
|
tabSelector,
|
||||||
messageSelector,
|
messageSelector,
|
||||||
(tab, messages) => messages.getIn([tab.server, tab.channel || tab.user || tab.server], List())
|
(tab, messages) => messages.getIn([tab.server, tab.name || tab.server], List())
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedChannelSelector = createSelector(
|
const selectedChannelSelector = createSelector(
|
||||||
tabSelector,
|
tabSelector,
|
||||||
channelSelector,
|
channelSelector,
|
||||||
(tab, channels) => channels.getIn([tab.server, tab.channel], Map())
|
(tab, channels) => channels.getIn([tab.server, tab.name], Map())
|
||||||
);
|
);
|
||||||
|
|
||||||
const usersSelector = createSelector(
|
const usersSelector = createSelector(
|
||||||
@ -153,7 +154,7 @@ const usersSelector = createSelector(
|
|||||||
const titleSelector = createSelector(
|
const titleSelector = createSelector(
|
||||||
tabSelector,
|
tabSelector,
|
||||||
serverSelector,
|
serverSelector,
|
||||||
(tab, servers) => tab.channel || tab.user || servers.getIn([tab.server, 'name'])
|
(tab, servers) => tab.name || servers.getIn([tab.server, 'name'])
|
||||||
);
|
);
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
@ -10,6 +10,7 @@ import createRoutes from './routes';
|
|||||||
import Socket from './util/Socket';
|
import Socket from './util/Socket';
|
||||||
import handleSocket from './socket';
|
import handleSocket from './socket';
|
||||||
import Root from './containers/Root';
|
import Root from './containers/Root';
|
||||||
|
import { addMessages } from './actions/message';
|
||||||
|
|
||||||
const host = DEV ? `${window.location.hostname}:1337` : window.location.host;
|
const host = DEV ? `${window.location.hostname}:1337` : window.location.host;
|
||||||
const socket = new Socket(host);
|
const socket = new Socket(host);
|
||||||
@ -46,6 +47,11 @@ if (env.users) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env.messages) {
|
||||||
|
const { messages, server, to } = env.messages;
|
||||||
|
store.dispatch(addMessages(messages, server, to));
|
||||||
|
}
|
||||||
|
|
||||||
handleSocket(socket, store);
|
handleSocket(socket, store);
|
||||||
|
|
||||||
const routes = createRoutes();
|
const routes = createRoutes();
|
||||||
|
@ -5,9 +5,7 @@ import * as actions from '../actions';
|
|||||||
|
|
||||||
const Message = Record({
|
const Message = Record({
|
||||||
id: null,
|
id: null,
|
||||||
server: null,
|
|
||||||
from: null,
|
from: null,
|
||||||
to: null,
|
|
||||||
content: '',
|
content: '',
|
||||||
time: null,
|
time: null,
|
||||||
type: null,
|
type: null,
|
||||||
@ -17,46 +15,40 @@ const Message = Record({
|
|||||||
breakpoints: null
|
breakpoints: null
|
||||||
});
|
});
|
||||||
|
|
||||||
function addMessage(state, message) {
|
function addMessage(state, { server, tab, message }) {
|
||||||
return state.updateIn([message.server, message.dest], List(),
|
return state.updateIn([server, tab], List(), list => list.push(new Message(message)));
|
||||||
list => list.push(new Message(message)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createReducer(Map(), {
|
export default createReducer(Map(), {
|
||||||
[actions.SEND_MESSAGE](state, action) {
|
[actions.SEND_MESSAGE]: addMessage,
|
||||||
return addMessage(state, action.message);
|
[actions.ADD_MESSAGE]: addMessage,
|
||||||
},
|
|
||||||
|
|
||||||
[actions.ADD_MESSAGE](state, action) {
|
[actions.ADD_MESSAGES](state, { server, tab, messages }) {
|
||||||
return addMessage(state, action.message);
|
|
||||||
},
|
|
||||||
|
|
||||||
[actions.ADD_MESSAGES](state, action) {
|
|
||||||
return state.withMutations(s =>
|
return state.withMutations(s =>
|
||||||
action.messages.forEach(message =>
|
messages.forEach(message =>
|
||||||
addMessage(s, message)
|
s.updateIn([server, tab], List(), list => list.push(new Message(message)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
[actions.DISCONNECT](state, action) {
|
[actions.DISCONNECT](state, { server }) {
|
||||||
return state.delete(action.server);
|
return state.delete(server);
|
||||||
},
|
},
|
||||||
|
|
||||||
[actions.PART](state, action) {
|
[actions.PART](state, { server, channels }) {
|
||||||
return state.withMutations(s =>
|
return state.withMutations(s =>
|
||||||
action.channels.forEach(channel =>
|
channels.forEach(channel =>
|
||||||
s.deleteIn([action.server, channel])
|
s.deleteIn([server, channel])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
[actions.UPDATE_MESSAGE_HEIGHT](state, action) {
|
[actions.UPDATE_MESSAGE_HEIGHT](state, { wrapWidth, charWidth }) {
|
||||||
return state.withMutations(s =>
|
return state.withMutations(s =>
|
||||||
s.forEach((server, serverKey) =>
|
s.forEach((server, serverKey) =>
|
||||||
server.forEach((target, targetKey) =>
|
server.forEach((target, targetKey) =>
|
||||||
target.forEach((message, index) => s.setIn([serverKey, targetKey, index, 'height'],
|
target.forEach((message, index) => s.setIn([serverKey, targetKey, index, 'height'],
|
||||||
messageHeight(message, action.wrapWidth, action.charWidth, 6 * action.charWidth))
|
messageHeight(message, wrapWidth, charWidth, 6 * charWidth))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -5,10 +5,13 @@ import * as actions from '../actions';
|
|||||||
|
|
||||||
const Tab = Record({
|
const Tab = Record({
|
||||||
server: null,
|
server: null,
|
||||||
channel: null,
|
name: null
|
||||||
user: null
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Tab.prototype.isChannel = function isChannel() {
|
||||||
|
return this.name && this.name.charAt(0) === '#';
|
||||||
|
};
|
||||||
|
|
||||||
const State = Record({
|
const State = Record({
|
||||||
selected: new Tab(),
|
selected: new Tab(),
|
||||||
history: List()
|
history: List()
|
||||||
@ -24,13 +27,13 @@ export default createReducer(new State(), {
|
|||||||
|
|
||||||
[actions.PART](state, action) {
|
[actions.PART](state, action) {
|
||||||
return state.set('history', state.history.filter(tab =>
|
return state.set('history', state.history.filter(tab =>
|
||||||
!(tab.server === action.server && tab.channel === action.channels[0])
|
!(tab.server === action.server && tab.name === action.channels[0])
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|
||||||
[actions.CLOSE_PRIVATE_CHAT](state, action) {
|
[actions.CLOSE_PRIVATE_CHAT](state, action) {
|
||||||
return state.set('history', state.history.filter(tab =>
|
return state.set('history', state.history.filter(tab =>
|
||||||
!(tab.server === action.server && tab.user === action.nick)
|
!(tab.server === action.server && tab.name === action.nick)
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -22,11 +22,15 @@ function findChannels(state, server, user) {
|
|||||||
export default function handleSocket(socket, { dispatch, getState }) {
|
export default function handleSocket(socket, { dispatch, getState }) {
|
||||||
const handlers = {
|
const handlers = {
|
||||||
message(message) {
|
message(message) {
|
||||||
dispatch(addMessage(message));
|
dispatch(addMessage(message, message.server, message.to));
|
||||||
},
|
},
|
||||||
|
|
||||||
pm(message) {
|
pm(message) {
|
||||||
dispatch(addMessage(message));
|
dispatch(addMessage(message, message.server, message.from));
|
||||||
|
},
|
||||||
|
|
||||||
|
messages({ messages, server, to }) {
|
||||||
|
dispatch(addMessages(messages, server, to));
|
||||||
},
|
},
|
||||||
|
|
||||||
join(data) {
|
join(data) {
|
||||||
@ -67,11 +71,7 @@ export default function handleSocket(socket, { dispatch, getState }) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
motd({ content, server }) {
|
motd({ content, server }) {
|
||||||
dispatch(addMessages(content.map(line => ({
|
dispatch(addMessages(content.map(line => ({ content: line })), server));
|
||||||
server,
|
|
||||||
to: server,
|
|
||||||
content: line
|
|
||||||
}))));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
whois(data) {
|
whois(data) {
|
||||||
@ -84,7 +84,7 @@ export default function handleSocket(socket, { dispatch, getState }) {
|
|||||||
`Host: ${data.host}`,
|
`Host: ${data.host}`,
|
||||||
`Server: ${data.server}`,
|
`Server: ${data.server}`,
|
||||||
`Channels: ${data.channels}`
|
`Channels: ${data.channels}`
|
||||||
], tab.server, tab.channel));
|
], tab.server, tab.name));
|
||||||
},
|
},
|
||||||
|
|
||||||
print({ server, message }) {
|
print({ server, message }) {
|
||||||
|
@ -3,7 +3,7 @@ import Backoff from 'backo';
|
|||||||
export default class Socket {
|
export default class Socket {
|
||||||
constructor(host) {
|
constructor(host) {
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
||||||
this.url = `${protocol}://${host}/ws`;
|
this.url = `${protocol}://${host}/ws?path=${window.location.pathname}`;
|
||||||
|
|
||||||
this.connectTimeout = 20000;
|
this.connectTimeout = 20000;
|
||||||
this.pingTimeout = 30000;
|
this.pingTimeout = 30000;
|
||||||
|
@ -26,7 +26,7 @@ type indexData struct {
|
|||||||
Users *Userlist `json:"users,omitempty"`
|
Users *Userlist `json:"users,omitempty"`
|
||||||
|
|
||||||
// Last messages in the selected channel
|
// Last messages in the selected channel
|
||||||
Messages []storage.Message `json:"messages,omitempty"`
|
Messages *Messages `json:"messages,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIndexData(r *http.Request, session *Session) *indexData {
|
func getIndexData(r *http.Request, session *Session) *indexData {
|
||||||
@ -68,6 +68,15 @@ func getIndexData(r *http.Request, session *Session) *indexData {
|
|||||||
Users: users,
|
Users: users,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messages, err := session.user.GetLastMessages(params[0], params[1], 25)
|
||||||
|
if err == nil && len(messages) > 0 {
|
||||||
|
data.Messages = &Messages{
|
||||||
|
Server: params[0],
|
||||||
|
To: params[1],
|
||||||
|
Messages: messages,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &data
|
return &data
|
||||||
|
@ -67,6 +67,12 @@ type Message struct {
|
|||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Messages struct {
|
||||||
|
Server string `json:"server"`
|
||||||
|
To string `json:"to"`
|
||||||
|
Messages []storage.Message `json:"messages"`
|
||||||
|
}
|
||||||
|
|
||||||
type Topic struct {
|
type Topic struct {
|
||||||
Server string `json:"server"`
|
Server string `json:"server"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
|
@ -119,7 +119,7 @@ func upgradeWS(w http.ResponseWriter, r *http.Request, session *Session) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newWSHandler(conn, session).run()
|
newWSHandler(conn, session, r).run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func createHTTPSRedirect(portHTTPS string) http.HandlerFunc {
|
func createHTTPSRedirect(portHTTPS string) http.HandlerFunc {
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@ -20,13 +22,13 @@ type wsHandler struct {
|
|||||||
handlers map[string]func([]byte)
|
handlers map[string]func([]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWSHandler(conn *websocket.Conn, session *Session) *wsHandler {
|
func newWSHandler(conn *websocket.Conn, session *Session, r *http.Request) *wsHandler {
|
||||||
h := &wsHandler{
|
h := &wsHandler{
|
||||||
ws: newWSConn(conn),
|
ws: newWSConn(conn),
|
||||||
session: session,
|
session: session,
|
||||||
addr: conn.RemoteAddr().String(),
|
addr: conn.RemoteAddr().String(),
|
||||||
}
|
}
|
||||||
h.init()
|
h.init(r)
|
||||||
h.initHandlers()
|
h.initHandlers()
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
@ -55,7 +57,7 @@ func (h *wsHandler) dispatchRequest(req WSRequest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *wsHandler) init() {
|
func (h *wsHandler) init(r *http.Request) {
|
||||||
h.session.setWS(h.addr, h.ws)
|
h.session.setWS(h.addr, h.ws)
|
||||||
|
|
||||||
log.Println(h.addr, "[Session] User ID:", h.session.user.ID, "|",
|
log.Println(h.addr, "[Session] User ID:", h.session.user.ID, "|",
|
||||||
@ -63,13 +65,27 @@ func (h *wsHandler) init() {
|
|||||||
h.session.numWS(), "WebSocket connections")
|
h.session.numWS(), "WebSocket connections")
|
||||||
|
|
||||||
channels := h.session.user.GetChannels()
|
channels := h.session.user.GetChannels()
|
||||||
|
params := strings.Split(strings.Trim(r.URL.Query().Get("path"), "/"), "/")
|
||||||
|
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
|
if len(params) > 1 && channel.Server == params[0] && channel.Name == params[1] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
h.session.sendJSON("users", Userlist{
|
h.session.sendJSON("users", Userlist{
|
||||||
Server: channel.Server,
|
Server: channel.Server,
|
||||||
Channel: channel.Name,
|
Channel: channel.Name,
|
||||||
Users: channelStore.GetUsers(channel.Server, channel.Name),
|
Users: channelStore.GetUsers(channel.Server, channel.Name),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
messages, err := h.session.user.GetLastMessages(channel.Server, channel.Name, 25)
|
||||||
|
if err == nil && len(messages) > 0 {
|
||||||
|
h.session.sendJSON("messages", Messages{
|
||||||
|
Server: channel.Server,
|
||||||
|
To: channel.Name,
|
||||||
|
Messages: messages,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +22,7 @@ struct Channel {
|
|||||||
|
|
||||||
struct Message {
|
struct Message {
|
||||||
ID uint64
|
ID uint64
|
||||||
Server string
|
|
||||||
From string
|
From string
|
||||||
To string
|
|
||||||
Content string
|
Content string
|
||||||
Time int64
|
Time int64
|
||||||
}
|
}
|
||||||
|
@ -702,21 +702,6 @@ func (d *Channel) Unmarshal(buf []byte) (uint64, error) {
|
|||||||
|
|
||||||
func (d *Message) Size() (s uint64) {
|
func (d *Message) Size() (s uint64) {
|
||||||
|
|
||||||
{
|
|
||||||
l := uint64(len(d.Server))
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
t := l
|
|
||||||
for t >= 0x80 {
|
|
||||||
t >>= 7
|
|
||||||
s++
|
|
||||||
}
|
|
||||||
s++
|
|
||||||
|
|
||||||
}
|
|
||||||
s += l
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
l := uint64(len(d.From))
|
l := uint64(len(d.From))
|
||||||
|
|
||||||
@ -732,21 +717,6 @@ func (d *Message) Size() (s uint64) {
|
|||||||
}
|
}
|
||||||
s += l
|
s += l
|
||||||
}
|
}
|
||||||
{
|
|
||||||
l := uint64(len(d.To))
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
t := l
|
|
||||||
for t >= 0x80 {
|
|
||||||
t >>= 7
|
|
||||||
s++
|
|
||||||
}
|
|
||||||
s++
|
|
||||||
|
|
||||||
}
|
|
||||||
s += l
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
l := uint64(len(d.Content))
|
l := uint64(len(d.Content))
|
||||||
|
|
||||||
@ -781,25 +751,6 @@ func (d *Message) Marshal(buf []byte) ([]byte, error) {
|
|||||||
*(*uint64)(unsafe.Pointer(&buf[0])) = d.ID
|
*(*uint64)(unsafe.Pointer(&buf[0])) = d.ID
|
||||||
|
|
||||||
}
|
}
|
||||||
{
|
|
||||||
l := uint64(len(d.Server))
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
t := uint64(l)
|
|
||||||
|
|
||||||
for t >= 0x80 {
|
|
||||||
buf[i+8] = byte(t) | 0x80
|
|
||||||
t >>= 7
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
buf[i+8] = byte(t)
|
|
||||||
i++
|
|
||||||
|
|
||||||
}
|
|
||||||
copy(buf[i+8:], d.Server)
|
|
||||||
i += l
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
l := uint64(len(d.From))
|
l := uint64(len(d.From))
|
||||||
|
|
||||||
@ -819,25 +770,6 @@ func (d *Message) Marshal(buf []byte) ([]byte, error) {
|
|||||||
copy(buf[i+8:], d.From)
|
copy(buf[i+8:], d.From)
|
||||||
i += l
|
i += l
|
||||||
}
|
}
|
||||||
{
|
|
||||||
l := uint64(len(d.To))
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
t := uint64(l)
|
|
||||||
|
|
||||||
for t >= 0x80 {
|
|
||||||
buf[i+8] = byte(t) | 0x80
|
|
||||||
t >>= 7
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
buf[i+8] = byte(t)
|
|
||||||
i++
|
|
||||||
|
|
||||||
}
|
|
||||||
copy(buf[i+8:], d.To)
|
|
||||||
i += l
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
l := uint64(len(d.Content))
|
l := uint64(len(d.Content))
|
||||||
|
|
||||||
@ -876,26 +808,6 @@ func (d *Message) Unmarshal(buf []byte) (uint64, error) {
|
|||||||
{
|
{
|
||||||
l := uint64(0)
|
l := uint64(0)
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
bs := uint8(7)
|
|
||||||
t := uint64(buf[i+8] & 0x7F)
|
|
||||||
for buf[i+8]&0x80 == 0x80 {
|
|
||||||
i++
|
|
||||||
t |= uint64(buf[i+8]&0x7F) << bs
|
|
||||||
bs += 7
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
|
|
||||||
l = t
|
|
||||||
|
|
||||||
}
|
|
||||||
d.Server = string(buf[i+8 : i+8+l])
|
|
||||||
i += l
|
|
||||||
}
|
|
||||||
{
|
|
||||||
l := uint64(0)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
bs := uint8(7)
|
bs := uint8(7)
|
||||||
@ -916,26 +828,6 @@ func (d *Message) Unmarshal(buf []byte) (uint64, error) {
|
|||||||
{
|
{
|
||||||
l := uint64(0)
|
l := uint64(0)
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
bs := uint8(7)
|
|
||||||
t := uint64(buf[i+8] & 0x7F)
|
|
||||||
for buf[i+8]&0x80 == 0x80 {
|
|
||||||
i++
|
|
||||||
t |= uint64(buf[i+8]&0x7F) << bs
|
|
||||||
bs += 7
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
|
|
||||||
l = t
|
|
||||||
|
|
||||||
}
|
|
||||||
d.To = string(buf[i+8 : i+8+l])
|
|
||||||
i += l
|
|
||||||
}
|
|
||||||
{
|
|
||||||
l := uint64(0)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
bs := uint8(7)
|
bs := uint8(7)
|
||||||
|
@ -7,16 +7,21 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/blevesearch/bleve"
|
"github.com/blevesearch/bleve"
|
||||||
|
"github.com/blevesearch/bleve/analysis/analyzer/keyword"
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
ID uint64 `json:"id"`
|
ID uint64 `json:"id" bleve:"-"`
|
||||||
Server string `json:"server"`
|
Server string `json:"-" bleve:"server"`
|
||||||
From string `json:"from"`
|
From string `json:"from" bleve:"-"`
|
||||||
To string `json:"to,omitempty"`
|
To string `json:"-" bleve:"to"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content" bleve:"content"`
|
||||||
Time int64 `json:"time"`
|
Time int64 `json:"time" bleve:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Message) Type() string {
|
||||||
|
return "message"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) LogMessage(server, from, to, content string) error {
|
func (u *User) LogMessage(server, from, to, content string) error {
|
||||||
@ -167,7 +172,27 @@ func (u *User) openMessageLog() error {
|
|||||||
indexPath := Path.Index(u.Username)
|
indexPath := Path.Index(u.Username)
|
||||||
u.messageIndex, err = bleve.Open(indexPath)
|
u.messageIndex, err = bleve.Open(indexPath)
|
||||||
if err == bleve.ErrorIndexPathDoesNotExist {
|
if err == bleve.ErrorIndexPathDoesNotExist {
|
||||||
|
keywordMapping := bleve.NewTextFieldMapping()
|
||||||
|
keywordMapping.Analyzer = keyword.Name
|
||||||
|
keywordMapping.Store = false
|
||||||
|
keywordMapping.IncludeTermVectors = false
|
||||||
|
keywordMapping.IncludeInAll = false
|
||||||
|
|
||||||
|
contentMapping := bleve.NewTextFieldMapping()
|
||||||
|
contentMapping.Analyzer = "en"
|
||||||
|
contentMapping.Store = false
|
||||||
|
contentMapping.IncludeTermVectors = false
|
||||||
|
contentMapping.IncludeInAll = false
|
||||||
|
|
||||||
|
messageMapping := bleve.NewDocumentMapping()
|
||||||
|
messageMapping.StructTagKey = "bleve"
|
||||||
|
messageMapping.AddFieldMappingsAt("server", keywordMapping)
|
||||||
|
messageMapping.AddFieldMappingsAt("to", keywordMapping)
|
||||||
|
messageMapping.AddFieldMappingsAt("content", contentMapping)
|
||||||
|
|
||||||
mapping := bleve.NewIndexMapping()
|
mapping := bleve.NewIndexMapping()
|
||||||
|
mapping.AddDocumentMapping("message", messageMapping)
|
||||||
|
|
||||||
u.messageIndex, err = bleve.New(indexPath, mapping)
|
u.messageIndex, err = bleve.New(indexPath, mapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
38
vendor/github.com/blevesearch/bleve/analysis/analyzer/keyword/keyword.go
generated
vendored
Normal file
38
vendor/github.com/blevesearch/bleve/analysis/analyzer/keyword/keyword.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2014 Couchbase, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keyword
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/blevesearch/bleve/analysis"
|
||||||
|
"github.com/blevesearch/bleve/analysis/tokenizer/single"
|
||||||
|
"github.com/blevesearch/bleve/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Name = "keyword"
|
||||||
|
|
||||||
|
func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (*analysis.Analyzer, error) {
|
||||||
|
keywordTokenizer, err := cache.TokenizerNamed(single.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rv := analysis.Analyzer{
|
||||||
|
Tokenizer: keywordTokenizer,
|
||||||
|
}
|
||||||
|
return &rv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.RegisterAnalyzer(Name, AnalyzerConstructor)
|
||||||
|
}
|
49
vendor/github.com/blevesearch/bleve/analysis/tokenizer/single/single.go
generated
vendored
Normal file
49
vendor/github.com/blevesearch/bleve/analysis/tokenizer/single/single.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (c) 2014 Couchbase, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package single
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/blevesearch/bleve/analysis"
|
||||||
|
"github.com/blevesearch/bleve/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Name = "single"
|
||||||
|
|
||||||
|
type SingleTokenTokenizer struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSingleTokenTokenizer() *SingleTokenTokenizer {
|
||||||
|
return &SingleTokenTokenizer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *SingleTokenTokenizer) Tokenize(input []byte) analysis.TokenStream {
|
||||||
|
return analysis.TokenStream{
|
||||||
|
&analysis.Token{
|
||||||
|
Term: input,
|
||||||
|
Position: 1,
|
||||||
|
Start: 0,
|
||||||
|
End: len(input),
|
||||||
|
Type: analysis.AlphaNumeric,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SingleTokenTokenizerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Tokenizer, error) {
|
||||||
|
return NewSingleTokenTokenizer(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.RegisterTokenizer(Name, SingleTokenTokenizerConstructor)
|
||||||
|
}
|
12
vendor/vendor.json
vendored
12
vendor/vendor.json
vendored
@ -14,6 +14,12 @@
|
|||||||
"revision": "0b1034dcbe067789a206f3267f41c6a1f9760b56",
|
"revision": "0b1034dcbe067789a206f3267f41c6a1f9760b56",
|
||||||
"revisionTime": "2017-04-06T22:05:36Z"
|
"revisionTime": "2017-04-06T22:05:36Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "OM2QW7G5DfzaUzCoe23282875TE=",
|
||||||
|
"path": "github.com/blevesearch/bleve/analysis/analyzer/keyword",
|
||||||
|
"revision": "17e21be71ad41256baee0ae3023a048fa1826bb1",
|
||||||
|
"revisionTime": "2017-04-19T13:14:44Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "IefDmVwLU3UiILeN35DA25gPFnc=",
|
"checksumSHA1": "IefDmVwLU3UiILeN35DA25gPFnc=",
|
||||||
"path": "github.com/blevesearch/bleve/analysis/analyzer/standard",
|
"path": "github.com/blevesearch/bleve/analysis/analyzer/standard",
|
||||||
@ -56,6 +62,12 @@
|
|||||||
"revision": "0b1034dcbe067789a206f3267f41c6a1f9760b56",
|
"revision": "0b1034dcbe067789a206f3267f41c6a1f9760b56",
|
||||||
"revisionTime": "2017-04-06T22:05:36Z"
|
"revisionTime": "2017-04-06T22:05:36Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "Lnopn2j55CFd15EBle12dzqQar8=",
|
||||||
|
"path": "github.com/blevesearch/bleve/analysis/tokenizer/single",
|
||||||
|
"revision": "17e21be71ad41256baee0ae3023a048fa1826bb1",
|
||||||
|
"revisionTime": "2017-04-19T13:14:44Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "q7C04nlJLxKmemXLop0oyJhfi5M=",
|
"checksumSHA1": "q7C04nlJLxKmemXLop0oyJhfi5M=",
|
||||||
"path": "github.com/blevesearch/bleve/analysis/tokenizer/unicode",
|
"path": "github.com/blevesearch/bleve/analysis/tokenizer/unicode",
|
||||||
|
Loading…
Reference in New Issue
Block a user