move windows to subfolder
This commit is contained in:
parent
7d550d5a20
commit
6d1ad02b26
|
@ -1,5 +1,7 @@
|
|||
/* @flow */
|
||||
|
||||
import { t } from 'ttag';
|
||||
|
||||
import type {
|
||||
Action,
|
||||
ThunkAction,
|
||||
|
@ -557,42 +559,62 @@ export function initTimer(): ThunkAction {
|
|||
};
|
||||
}
|
||||
|
||||
export function showModal(modalType: string): Action {
|
||||
return {
|
||||
type: 'SHOW_MODAL',
|
||||
export function showModal(modalType: string, title: string): Action {
|
||||
return openWindow(
|
||||
modalType,
|
||||
};
|
||||
title,
|
||||
true,
|
||||
false,
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
export function showSettingsModal(): Action {
|
||||
return showModal('SETTINGS');
|
||||
return showModal(
|
||||
'SETTINGS',
|
||||
t`Settings`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showUserAreaModal(): Action {
|
||||
return showModal('USERAREA');
|
||||
}
|
||||
|
||||
export function showMinecraftModal(): Action {
|
||||
return showModal('MINECRAFT');
|
||||
return showModal(
|
||||
'USERAREA',
|
||||
t`User Area`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showRegisterModal(): Action {
|
||||
return showModal('REGISTER');
|
||||
return showModal(
|
||||
'REGISTER',
|
||||
t`Register New Account`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showForgotPasswordModal(): Action {
|
||||
return showModal('FORGOT_PASSWORD');
|
||||
return showModal(
|
||||
'FORGOT_PASSWORD',
|
||||
t`Restore my Password`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showHelpModal(): Action {
|
||||
return showModal('HELP');
|
||||
return showModal(
|
||||
'HELP',
|
||||
t`Welcome to PixelPlanet.fun`,
|
||||
);
|
||||
}
|
||||
export function showArchiveModal(): Action {
|
||||
return showModal('ARCHIVE');
|
||||
return showModal(
|
||||
'ARCHIVE',
|
||||
t`Canvas Archive`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showCanvasSelectionModal(): Action {
|
||||
return showModal('CANVAS_SELECTION');
|
||||
return showModal(
|
||||
'CANVAS_SELECTION',
|
||||
t`Canvas Selection`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showContextMenu(
|
||||
|
@ -610,6 +632,7 @@ export function showContextMenu(
|
|||
};
|
||||
}
|
||||
|
||||
// TODO CHAT MODAL
|
||||
export function showChatModal(forceModal: boolean = false): Action {
|
||||
if (window.innerWidth > 604 && !forceModal) { return toggleChatBox(); }
|
||||
return showModal('CHAT');
|
||||
|
@ -704,6 +727,53 @@ export function addToChatInputMessage(windowId: number, msg: string): Action {
|
|||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* fullscreen means to open as modal
|
||||
*/
|
||||
export function openWindow(
|
||||
windowType: string,
|
||||
title: string,
|
||||
fullscreen: boolean,
|
||||
cloneable: boolean,
|
||||
args: Object,
|
||||
): Action {
|
||||
return {
|
||||
type: 'OPEN_WINDOW',
|
||||
windowType,
|
||||
title,
|
||||
fullscreen,
|
||||
cloneable,
|
||||
args,
|
||||
};
|
||||
}
|
||||
|
||||
export function closeWindow(windowId): Action {
|
||||
return {
|
||||
type: 'CLOSE_WINDOW',
|
||||
windowId,
|
||||
};
|
||||
}
|
||||
|
||||
export function cloneWindow(windowId): Action {
|
||||
return {
|
||||
type: 'CLONE_WINDOW',
|
||||
windowId,
|
||||
};
|
||||
}
|
||||
|
||||
export function maximizeWindow(windowId): Action {
|
||||
return {
|
||||
type: 'MAXIMIZE_WINDOW',
|
||||
windowId,
|
||||
};
|
||||
}
|
||||
|
||||
export function restoreWindow(): Action {
|
||||
return {
|
||||
type: 'RESTORE_WINDOW',
|
||||
};
|
||||
}
|
||||
|
||||
export function moveWindow(windowId, xDiff, yDiff): Action {
|
||||
return {
|
||||
type: 'MOVE_WINDOW',
|
||||
|
@ -713,22 +783,20 @@ export function moveWindow(windowId, xDiff, yDiff): Action {
|
|||
};
|
||||
}
|
||||
|
||||
export function openChatWindow(): Action {
|
||||
export function resizeWindow(windowId, xDiff, yDiff): Action {
|
||||
return {
|
||||
type: 'OPEN_WINDOW',
|
||||
windowType: 'CHAT',
|
||||
title: 'chat',
|
||||
width: 700,
|
||||
height: 300,
|
||||
xPos: 100,
|
||||
yPos: 100,
|
||||
args: {
|
||||
chatChannel: 1,
|
||||
inputMessage: '',
|
||||
},
|
||||
type: 'RESIZE_WINDOW',
|
||||
windowId,
|
||||
xDiff,
|
||||
yDiff,
|
||||
};
|
||||
}
|
||||
|
||||
export function openChatWindow(): Action {
|
||||
return openWindow('CHAT', t`Chat`, false, true,
|
||||
{ chatChannel: 1, inputMessage: '' });
|
||||
}
|
||||
|
||||
/*
|
||||
* query: Object with either userId: number or userName: string
|
||||
*/
|
||||
|
@ -823,12 +891,6 @@ export function setLeaveChannel(
|
|||
};
|
||||
}
|
||||
|
||||
export function hideModal(): Action {
|
||||
return {
|
||||
type: 'HIDE_MODAL',
|
||||
};
|
||||
}
|
||||
|
||||
export function hideContextMenu(): Action {
|
||||
return {
|
||||
type: 'HIDE_CONTEXT_MENU',
|
||||
|
|
|
@ -75,7 +75,19 @@ export type Action =
|
|||
| { type: 'SET_CHAT_INPUT_MSG', windowId: number, msg: string }
|
||||
| { type: 'ADD_CHAT_INPUT_MSG', windowId: number, msg: string }
|
||||
| { type: 'SET_CHAT_FETCHING', fetching: boolean }
|
||||
| { type: 'OPEN_WINDOW',
|
||||
windowType: string,
|
||||
title: string,
|
||||
fullscreen: boolean,
|
||||
cloneable: boolean,
|
||||
args: Object,
|
||||
}
|
||||
| { type: 'CLOSE_WINDOW', windowId: number }
|
||||
| { type: 'CLONE_WINDOW', windowId: number }
|
||||
| { type: 'MAXIMIZE_WINDOW', windowId: number }
|
||||
| { type: 'RESTORE_WINDOW' }
|
||||
| { type: 'MOVE_WINDOW', windowId: number, xDiff: number, yDiff: number }
|
||||
| { type: 'RESIZE_WINDOW', windowId: number, xDiff: number, yDiff: number }
|
||||
| { type: 'BLOCK_USER', userId: number, userName: string }
|
||||
| { type: 'UNBLOCK_USER', userId: number, userName: string }
|
||||
| { type: 'SET_BLOCKING_DM', blockDm: boolean }
|
||||
|
@ -117,14 +129,12 @@ export type Action =
|
|||
| { type: 'SET_MINECRAFT_NAME', minecraftname: string }
|
||||
| { type: 'SET_MAILREG', mailreg: boolean }
|
||||
| { type: 'REM_FROM_MESSAGES', message: string }
|
||||
| { type: 'SHOW_MODAL', modalType: string }
|
||||
| { type: 'SHOW_CONTEXT_MENU',
|
||||
menuType: string,
|
||||
xPos: number,
|
||||
yPos: number,
|
||||
args: Object,
|
||||
}
|
||||
| { type: 'HIDE_MODAL' }
|
||||
| { type: 'HIDE_CONTEXT_MENU' }
|
||||
| { type: 'RELOAD_URL' }
|
||||
| { type: 'SET_HISTORICAL_TIME', date: string, time: string }
|
||||
|
|
|
@ -19,7 +19,7 @@ import Menu from './Menu';
|
|||
import UI from './UI';
|
||||
import ExpandMenuButton from './ExpandMenuButton';
|
||||
import ModalRoot from './ModalRoot';
|
||||
import WindowsRoot from './WindowsRoot';
|
||||
import WindowManager from './WindowManager';
|
||||
|
||||
const App = () => (
|
||||
<div>
|
||||
|
@ -34,7 +34,7 @@ const App = () => (
|
|||
<ExpandMenuButton />
|
||||
<UI />
|
||||
<ModalRoot />
|
||||
<WindowsRoot />
|
||||
<WindowManager />
|
||||
</IconContext.Provider>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
|
||||
import useWindowSize from '../utils/reactHookResize';
|
||||
import { showChatModal } from '../actions';
|
||||
|
||||
import Chat from './Chat';
|
||||
|
||||
|
||||
const ChatBox = () => {
|
||||
const [render, setRender] = useState(false);
|
||||
|
||||
const chatOpen = useSelector((state) => state.modal.chatOpen);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
if (chatOpen) setRender(true);
|
||||
}, 10);
|
||||
}, [chatOpen]);
|
||||
|
||||
const onTransitionEnd = () => {
|
||||
if (!chatOpen) setRender(false);
|
||||
};
|
||||
|
||||
const { width } = useWindowSize();
|
||||
if (width < 604 && chatOpen) {
|
||||
dispatch(showChatModal(true));
|
||||
}
|
||||
|
||||
return (
|
||||
(render || chatOpen) && (
|
||||
<div
|
||||
className={(chatOpen && render) ? 'chatbox show' : 'chatbox'}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
>
|
||||
<Chat showExpand />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ChatBox);
|
|
@ -14,7 +14,6 @@ import { showChatModal, openChatWindow } from '../actions';
|
|||
|
||||
|
||||
const ChatButton = ({
|
||||
modalOpen,
|
||||
chatNotify,
|
||||
channels,
|
||||
unread,
|
||||
|
@ -24,6 +23,7 @@ const ChatButton = ({
|
|||
const [unreadAny, setUnreadAny] = useState(false);
|
||||
// TODO what do here?
|
||||
const chatOpen = false;
|
||||
const modalOpen = false;
|
||||
|
||||
/*
|
||||
* almost the same as in ChannelDropDown
|
||||
|
@ -88,9 +88,6 @@ function mapDispatchToProps(dispatch) {
|
|||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const {
|
||||
modalOpen,
|
||||
} = state.windows;
|
||||
const {
|
||||
chatNotify,
|
||||
} = state.audio;
|
||||
|
@ -102,8 +99,6 @@ function mapStateToProps(state) {
|
|||
mute,
|
||||
} = state.chatRead;
|
||||
return {
|
||||
modalOpen,
|
||||
chatNotify,
|
||||
channels,
|
||||
unread,
|
||||
mute,
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import Chat from './Chat';
|
||||
|
||||
|
||||
const ChatModal = () => (
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
top: 80,
|
||||
padding: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="inarea"
|
||||
style={{
|
||||
height: '95%',
|
||||
}}
|
||||
>
|
||||
<Chat />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const data = {
|
||||
content: ChatModal,
|
||||
title: t`Chat`,
|
||||
};
|
||||
|
||||
export default data;
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import Creeper from './Creeper.svg';
|
||||
|
||||
import { showMinecraftModal } from '../actions';
|
||||
|
||||
const MinecraftButton = ({ open }) => (
|
||||
<div
|
||||
id="minecraftbutton"
|
||||
className="actionbuttons"
|
||||
onClick={open}
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<Creeper />
|
||||
</div>
|
||||
);
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
open() {
|
||||
dispatch(showMinecraftModal());
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(null, mapDispatchToProps)(MinecraftButton);
|
|
@ -5,88 +5,76 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { MdClose } from 'react-icons/md';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import {
|
||||
hideModal,
|
||||
closeWindow,
|
||||
restoreWindow,
|
||||
} from '../actions';
|
||||
|
||||
import HelpModal from './HelpModal';
|
||||
import SettingsModal from './SettingsModal';
|
||||
import UserAreaModal from './UserAreaModal';
|
||||
import RegisterModal from './RegisterModal';
|
||||
import CanvasSelectModal from './CanvasSelectModal';
|
||||
import ArchiveModal from './ArchiveModal';
|
||||
import ChatModal from './ChatModal';
|
||||
import ForgotPasswordModal from './ForgotPasswordModal';
|
||||
|
||||
|
||||
const MODAL_COMPONENTS = {
|
||||
NONE: { content: <div />, title: '' },
|
||||
HELP: HelpModal,
|
||||
SETTINGS: SettingsModal,
|
||||
USERAREA: UserAreaModal,
|
||||
REGISTER: RegisterModal,
|
||||
FORGOT_PASSWORD: ForgotPasswordModal,
|
||||
CHAT: ChatModal,
|
||||
CANVAS_SELECTION: CanvasSelectModal,
|
||||
ARCHIVE: ArchiveModal,
|
||||
/* other modals */
|
||||
};
|
||||
import COMPONENTS from './windows';
|
||||
|
||||
const ModalRoot = () => {
|
||||
const [render, setRender] = useState(false);
|
||||
|
||||
const modalType = useSelector((state) => state.windows.modalType);
|
||||
const modalOpen = useSelector((state) => state.windows.modalOpen);
|
||||
|
||||
const {
|
||||
title,
|
||||
content: SpecificModal,
|
||||
} = MODAL_COMPONENTS[modalType || 'NONE'];
|
||||
const { windowType, open, title } = useSelector(
|
||||
(state) => state.windows.modal,
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const close = useCallback(() => {
|
||||
dispatch(hideModal());
|
||||
}, [dispatch]);
|
||||
|
||||
const onTransitionEnd = () => {
|
||||
if (!modalOpen) setRender(false);
|
||||
if (!open) setRender(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
if (modalOpen) setRender(true);
|
||||
if (open) setRender(true);
|
||||
}, 10);
|
||||
}, [modalOpen]);
|
||||
}, [open]);
|
||||
|
||||
if (!windowType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const Content = COMPONENTS[windowType || 'NONE'];
|
||||
|
||||
return (
|
||||
(render || modalOpen)
|
||||
(render || open)
|
||||
&& [
|
||||
<div
|
||||
className={(modalOpen && render)
|
||||
className={(open && render)
|
||||
? 'OverlayModal show'
|
||||
: 'OverlayModal'}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
tabIndex={-1}
|
||||
onClick={close}
|
||||
onClick={() => dispatch(closeWindow(0))}
|
||||
/>,
|
||||
<div
|
||||
className={(modalOpen && render) ? 'Modal show' : 'Modal'}
|
||||
className={(open && render) ? 'Modal show' : 'Modal'}
|
||||
>
|
||||
<h2 style={{ paddingLeft: '5%' }}>{title}</h2>
|
||||
<div
|
||||
onClick={close}
|
||||
onClick={() => dispatch(closeWindow(0))}
|
||||
className="ModalClose"
|
||||
role="button"
|
||||
label="close"
|
||||
title={t`Close`}
|
||||
tabIndex={-1}
|
||||
><MdClose /></div>
|
||||
<SpecificModal windowId={0} />
|
||||
<div
|
||||
onClick={() => dispatch(restoreWindow())}
|
||||
className="ModalRestore"
|
||||
role="button"
|
||||
label="restore"
|
||||
title={t`Restore`}
|
||||
tabIndex={-1}
|
||||
>♥</div>
|
||||
<div className="win-content">
|
||||
<Content windowId={0} />
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -6,18 +6,17 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
|
||||
import Chat from './Chat';
|
||||
import {
|
||||
moveWindow,
|
||||
resizeWindow,
|
||||
closeWindow,
|
||||
maximizeWindow,
|
||||
cloneWindow,
|
||||
} from '../actions';
|
||||
import COMPONENTS from './windows';
|
||||
|
||||
const selectWindowById = (state, windowId) => state.windows.windows.find((win) => win.windowId === windowId);
|
||||
|
||||
const WINDOW_COMPONENTS = {
|
||||
NONE: <div />,
|
||||
CHAT: Chat,
|
||||
};
|
||||
|
||||
const Window = ({ id }) => {
|
||||
const win = useSelector((state) => selectWindowById(state, id));
|
||||
|
||||
|
@ -46,6 +45,33 @@ const Window = ({ id }) => {
|
|||
document.addEventListener('mouseleave', stopMove, { once: true });
|
||||
}, []);
|
||||
|
||||
const startResize = useCallback((event) => {
|
||||
event.preventDefault();
|
||||
let {
|
||||
clientX: startX,
|
||||
clientY: startY,
|
||||
} = event;
|
||||
const resize = (evt) => {
|
||||
const {
|
||||
clientX: curX,
|
||||
clientY: curY,
|
||||
} = evt;
|
||||
dispatch(resizeWindow(id, curX - startX, curY - startY));
|
||||
startX = curX;
|
||||
startY = curY;
|
||||
};
|
||||
document.addEventListener('mousemove', resize);
|
||||
const stopResize = () => {
|
||||
document.removeEventListener('mousemove', resize);
|
||||
};
|
||||
document.addEventListener('mouseup', stopResize, { once: true });
|
||||
document.addEventListener('mouseleave', stopResize, { once: true });
|
||||
}, []);
|
||||
|
||||
if (!win) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
width, height,
|
||||
xPos, yPos,
|
||||
|
@ -53,7 +79,7 @@ const Window = ({ id }) => {
|
|||
title,
|
||||
} = win;
|
||||
|
||||
const Content = WINDOW_COMPONENTS[windowType];
|
||||
const Content = COMPONENTS[windowType];
|
||||
|
||||
console.log(`render window ${id}`);
|
||||
|
||||
|
@ -71,7 +97,8 @@ const Window = ({ id }) => {
|
|||
className="win-topbar"
|
||||
>
|
||||
<span
|
||||
className="win-topbtnn"
|
||||
className="win-topbtn"
|
||||
onClick={() => dispatch(cloneWindow(id))}
|
||||
>
|
||||
+
|
||||
</span>
|
||||
|
@ -79,20 +106,30 @@ const Window = ({ id }) => {
|
|||
className="win-title"
|
||||
onMouseDown={startMove}
|
||||
>
|
||||
Move Here
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className="win-topbtnn"
|
||||
className="win-topbtn"
|
||||
onClick={() => dispatch(maximizeWindow(id))}
|
||||
>
|
||||
↑
|
||||
</span>
|
||||
<span
|
||||
className="win-topbtnn"
|
||||
className="win-topbtn"
|
||||
onClick={() => dispatch(closeWindow(id))}
|
||||
>
|
||||
X
|
||||
</span>
|
||||
</div>
|
||||
<Content windowId={id} />
|
||||
<div className="win-content">
|
||||
<Content windowId={id} />
|
||||
</div>
|
||||
<div
|
||||
onMouseDown={startResize}
|
||||
className="win-resize"
|
||||
>
|
||||
R
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ const WindowsRoot = () => {
|
|||
const windowIds = useSelector(selectWindowIds, shallowEqual);
|
||||
|
||||
return windowIds.map((id) => (
|
||||
<Window id={id} />
|
||||
<Window key={id} id={id} />
|
||||
));
|
||||
};
|
||||
|
|
@ -14,7 +14,7 @@ const imageStyle = {
|
|||
verticalAlign: 'middle',
|
||||
};
|
||||
|
||||
const ArchiveModal = () => (
|
||||
const Archive = () => (
|
||||
<p style={{ textAlign: 'center', paddingLeft: '5%', paddingRight: '5%' }}>
|
||||
<p className="modaltext">
|
||||
{t`While we tend to not delete canvases, some canvases are started for fun or as a request by users who currently like a meme. \
|
||||
|
@ -45,9 +45,4 @@ Those canvases can get boring after a while and after weeks of no major change a
|
|||
</p>
|
||||
);
|
||||
|
||||
const data = {
|
||||
content: ArchiveModal,
|
||||
title: t`Canvas Archive`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default Archive;
|
|
@ -7,13 +7,13 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import CanvasItem from './CanvasItem';
|
||||
import { showArchiveModal } from '../actions';
|
||||
import CanvasItem from '../CanvasItem';
|
||||
import { showArchiveModal } from '../../actions';
|
||||
|
||||
import type { State } from '../reducers';
|
||||
import type { State } from '../../reducers';
|
||||
|
||||
|
||||
const CanvasSelectModal = ({
|
||||
const CanvasSelect = ({
|
||||
canvases,
|
||||
showHiddenCanvases,
|
||||
showArchive,
|
||||
|
@ -62,9 +62,4 @@ function mapStateToProps(state: State) {
|
|||
return { canvases, showHiddenCanvases };
|
||||
}
|
||||
|
||||
const data = {
|
||||
content: connect(mapStateToProps, mapDispatchToProps)(CanvasSelectModal),
|
||||
title: t`Canvas Selection`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(CanvasSelect);
|
|
@ -10,9 +10,8 @@ import useStayScrolled from 'react-stay-scrolled';
|
|||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import type { State } from '../reducers';
|
||||
import ChatMessage from './ChatMessage';
|
||||
import ChannelDropDown from './ChannelDropDown';
|
||||
import ChatMessage from '../ChatMessage';
|
||||
import ChannelDropDown from '../ChannelDropDown';
|
||||
|
||||
import {
|
||||
showUserAreaModal,
|
||||
|
@ -21,9 +20,9 @@ import {
|
|||
setChatInputMessage,
|
||||
fetchChatMessages,
|
||||
showContextMenu,
|
||||
} from '../actions';
|
||||
import ProtocolClient from '../socket/ProtocolClient';
|
||||
import splitChatMessage from '../core/chatMessageFilter';
|
||||
} from '../../actions';
|
||||
import ProtocolClient from '../../socket/ProtocolClient';
|
||||
import splitChatMessage from '../../core/chatMessageFilter';
|
||||
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
|
@ -115,13 +114,7 @@ const Chat = ({
|
|||
return (
|
||||
<div
|
||||
ref={targetRef}
|
||||
style={{
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
className="chat-container"
|
||||
>
|
||||
<div
|
||||
className="chatlink"
|
|
@ -7,10 +7,10 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import { showUserAreaModal } from '../actions';
|
||||
import NewPasswordForm from './NewPasswordForm';
|
||||
import { showUserAreaModal } from '../../actions';
|
||||
import NewPasswordForm from '../NewPasswordForm';
|
||||
|
||||
const ForgotPasswordModal = ({ login }) => (
|
||||
const ForgotPassword = ({ login }) => (
|
||||
<p style={{ paddingLeft: '5%', paddingRight: '5%' }}>
|
||||
<p className="modaltext">
|
||||
{t`Enter your mail address and we will send you a new password:`}
|
||||
|
@ -32,9 +32,4 @@ function mapDispatchToProps(dispatch) {
|
|||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
content: connect(null, mapDispatchToProps)(ForgotPasswordModal),
|
||||
title: t`Restore my Password`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default connect(null, mapDispatchToProps)(ForgotPassword);
|
|
@ -11,7 +11,7 @@ import { MdTouchApp } from 'react-icons/md';
|
|||
/* eslint-disable max-len */
|
||||
|
||||
|
||||
const HelpModal = () => {
|
||||
const Help = () => {
|
||||
const bindG = <kbd>{c('keybinds').t`G`}</kbd>;
|
||||
const bindX = <kbd>{c('keybinds').t`X`}</kbd>;
|
||||
const bindH = <kbd>{c('keybinds').t`H`}</kbd>;
|
||||
|
@ -89,9 +89,4 @@ can be downloaded from mega.nz here: `}<a href="https://mega.nz/#!JpkBwAbJ!EnSLl
|
|||
);
|
||||
};
|
||||
|
||||
const data = {
|
||||
content: HelpModal,
|
||||
title: t`Welcome to PixelPlanet.fun`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default Help;
|
|
@ -7,13 +7,13 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import { showUserAreaModal } from '../actions';
|
||||
import { showUserAreaModal } from '../../actions';
|
||||
|
||||
// import { send_registration } from '../ui/register';
|
||||
import SignUpForm from './SignUpForm';
|
||||
import SignUpForm from '../SignUpForm';
|
||||
|
||||
|
||||
const RegisterModal = ({ login }) => (
|
||||
const Register = ({ login }) => (
|
||||
<p style={{ paddingLeft: '5%', paddingRight: '5%' }}>
|
||||
<p className="modaltext">{t`Register new account here`}</p><br />
|
||||
<p style={{ textAlign: 'center' }}>
|
||||
|
@ -33,9 +33,4 @@ function mapDispatchToProps(dispatch) {
|
|||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
content: connect(null, mapDispatchToProps)(RegisterModal),
|
||||
title: t`Register New Account`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default connect(null, mapDispatchToProps)(Register);
|
|
@ -7,8 +7,8 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { c, t } from 'ttag';
|
||||
|
||||
import LanguageSelect from './LanguageSelect';
|
||||
import MdToggleButtonHover from './MdToggleButtonHover';
|
||||
import LanguageSelect from '../LanguageSelect';
|
||||
import MdToggleButtonHover from '../MdToggleButtonHover';
|
||||
import {
|
||||
toggleGrid,
|
||||
togglePixelNotify,
|
||||
|
@ -20,9 +20,9 @@ import {
|
|||
toggleLightGrid,
|
||||
toggleHistoricalView,
|
||||
selectStyle,
|
||||
} from '../actions';
|
||||
} from '../../actions';
|
||||
|
||||
import type { State } from '../reducers';
|
||||
import type { State } from '../../reducers';
|
||||
|
||||
|
||||
const flexy = {
|
||||
|
@ -97,7 +97,7 @@ const SettingsItem = ({
|
|||
</div>
|
||||
);
|
||||
|
||||
function SettingsModal({
|
||||
function Settings({
|
||||
isMuted,
|
||||
isGridShown,
|
||||
isPixelNotifyShown,
|
||||
|
@ -273,9 +273,4 @@ function mapDispatchToProps(dispatch) {
|
|||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
content: connect(mapStateToProps, mapDispatchToProps)(SettingsModal),
|
||||
title: t`Settings`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Settings);
|
|
@ -7,21 +7,21 @@ import React, { Suspense } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import type { State } from '../reducers';
|
||||
import type { State } from '../../reducers';
|
||||
|
||||
|
||||
import {
|
||||
showRegisterModal, showForgotPasswordModal, setName, setMailreg,
|
||||
} from '../actions';
|
||||
import LogInForm from './LogInForm';
|
||||
import Tabs from './Tabs';
|
||||
import UserArea from './UserArea';
|
||||
import Rankings from './Rankings';
|
||||
} from '../../actions';
|
||||
import LogInForm from '../LogInForm';
|
||||
import Tabs from '../Tabs';
|
||||
import UserAreaContent from '../UserArea';
|
||||
import Rankings from '../Rankings';
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
const Converter = React.lazy(() => import(/* webpackChunkName: "converter" */ './Converter'));
|
||||
const Converter = React.lazy(() => import(/* webpackChunkName: "converter" */ '../Converter'));
|
||||
// eslint-disable-next-line max-len
|
||||
const Admintools = React.lazy(() => import(/* webpackChunkName: "admintools" */ './Admintools'));
|
||||
const Admintools = React.lazy(() => import(/* webpackChunkName: "admintools" */ '../Admintools'));
|
||||
|
||||
const logoStyle = {
|
||||
marginRight: 5,
|
||||
|
@ -86,7 +86,7 @@ const LogInArea = ({ register, forgotPassword, me }) => (
|
|||
</p>
|
||||
);
|
||||
|
||||
const UserAreaModal = ({
|
||||
const UserArea = ({
|
||||
name,
|
||||
register,
|
||||
forgotPassword,
|
||||
|
@ -105,7 +105,7 @@ const UserAreaModal = ({
|
|||
: (
|
||||
<Tabs>
|
||||
<div label={t`Profile`}>
|
||||
<UserArea
|
||||
<UserAreaContent
|
||||
setName={setUserName}
|
||||
setMailreg={setUserMailreg}
|
||||
/>
|
||||
|
@ -155,9 +155,4 @@ function mapStateToProps(state: State) {
|
|||
return { name, userlvl };
|
||||
}
|
||||
|
||||
const data = {
|
||||
content: connect(mapStateToProps, mapDispatchToProps)(UserAreaModal),
|
||||
title: t`User Area`,
|
||||
};
|
||||
|
||||
export default data;
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UserArea);
|
25
src/components/windows/index.jsx
Normal file
25
src/components/windows/index.jsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import Help from './Help';
|
||||
import Settings from './Settings';
|
||||
import UserArea from './UserArea';
|
||||
import Register from './Register';
|
||||
import CanvasSelect from './CanvasSelect';
|
||||
import Archive from './Archive';
|
||||
import Chat from './Chat';
|
||||
import ForgotPassword from './ForgotPassword';
|
||||
|
||||
export default {
|
||||
NONE: <div />,
|
||||
HELP: Help,
|
||||
SETTINGS: Settings,
|
||||
USERAREA: UserArea,
|
||||
REGISTER: Register,
|
||||
FORGOT_PASSWORD: ForgotPassword,
|
||||
CHAT: Chat,
|
||||
CANVAS_SELECTION: CanvasSelect,
|
||||
ARCHIVE: Archive,
|
||||
/* other modals */
|
||||
};
|
|
@ -6,20 +6,33 @@
|
|||
|
||||
import type { Action } from '../actions/types';
|
||||
|
||||
function generateWindowId(state) {
|
||||
let windowId = Math.floor(Math.random() * 99999) + 1;
|
||||
while (state.args[windowId]) {
|
||||
windowId += 1;
|
||||
}
|
||||
return windowId;
|
||||
}
|
||||
|
||||
export type WindowsState = {
|
||||
// modal is considerd as "fullscreen window"
|
||||
// its windowId is considered 0 and args are under args[0]
|
||||
modalOpen: boolean,
|
||||
modalType: ?string,
|
||||
modal: {
|
||||
windowType: ?string,
|
||||
title: ?string,
|
||||
open: boolean,
|
||||
},
|
||||
// [
|
||||
// {
|
||||
// windowId: number,
|
||||
// windowOpen: boolean,
|
||||
// windowType: string,
|
||||
// title: string,
|
||||
// width: number,
|
||||
// height: number,
|
||||
// xPos: percentage,
|
||||
// yPos: percentage,
|
||||
// cloneable: boolean,
|
||||
// },
|
||||
// ]
|
||||
windows: Array,
|
||||
|
@ -32,8 +45,11 @@ export type WindowsState = {
|
|||
}
|
||||
|
||||
const initialState: WindowsState = {
|
||||
modalOpen: false,
|
||||
modalType: null,
|
||||
modal: {
|
||||
windowType: null,
|
||||
title: null,
|
||||
open: false,
|
||||
},
|
||||
windows: [],
|
||||
args: {},
|
||||
};
|
||||
|
@ -47,16 +63,27 @@ export default function windows(
|
|||
const {
|
||||
windowType,
|
||||
title,
|
||||
width,
|
||||
height,
|
||||
xPos,
|
||||
yPos,
|
||||
fullscreen,
|
||||
cloneable,
|
||||
args,
|
||||
} = action;
|
||||
let windowId = Math.floor(Math.random() * 99999) + 1;
|
||||
while (state.args[windowId]) {
|
||||
windowId += 1;
|
||||
if (fullscreen) {
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
windowType,
|
||||
title,
|
||||
open: true,
|
||||
},
|
||||
args: {
|
||||
...state.args,
|
||||
0: {
|
||||
...args,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
const windowId = generateWindowId(state);
|
||||
return {
|
||||
...state,
|
||||
windows: [
|
||||
|
@ -64,12 +91,13 @@ export default function windows(
|
|||
{
|
||||
windowId,
|
||||
windowType,
|
||||
windowOpen: true,
|
||||
title,
|
||||
width,
|
||||
height,
|
||||
xPos,
|
||||
yPos,
|
||||
args,
|
||||
width: 600,
|
||||
height: 300,
|
||||
xPos: 200,
|
||||
yPos: 200,
|
||||
cloneable,
|
||||
},
|
||||
],
|
||||
args: {
|
||||
|
@ -79,10 +107,57 @@ export default function windows(
|
|||
};
|
||||
}
|
||||
|
||||
case 'REMOVE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
} = action;
|
||||
const args = { ...state.args };
|
||||
delete args[windowId];
|
||||
|
||||
if (windowId === 0) {
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
windowType: null,
|
||||
title: null,
|
||||
open: false,
|
||||
},
|
||||
args,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
windows: state.windows.filter((win) => win.windowId !== windowId),
|
||||
args,
|
||||
};
|
||||
}
|
||||
|
||||
case 'CLOSE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
} = action;
|
||||
if (windowId === 0) {
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
...state.modal,
|
||||
open: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
/*
|
||||
const newWindows = state.windows.map((win) => {
|
||||
if (win.windowId !== windowId) return win;
|
||||
return {
|
||||
...win,
|
||||
windowOpen: false,
|
||||
}
|
||||
});
|
||||
return {
|
||||
...state,
|
||||
windows: newWindows,
|
||||
};
|
||||
*/
|
||||
const args = { ...state.args };
|
||||
delete args[windowId];
|
||||
return {
|
||||
|
@ -92,6 +167,87 @@ export default function windows(
|
|||
};
|
||||
}
|
||||
|
||||
case 'CLONE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
} = action;
|
||||
const win = state.windows.find((w) => w.windowId === windowId);
|
||||
const newWindowId = generateWindowId(state);
|
||||
return {
|
||||
...state,
|
||||
windows: [
|
||||
...state.windows,
|
||||
{
|
||||
...win,
|
||||
windowId: newWindowId,
|
||||
xPos: win.xPos + 15,
|
||||
yPos: win.yPos + 15,
|
||||
},
|
||||
],
|
||||
args: {
|
||||
...state.args,
|
||||
[newWindowId]: {
|
||||
...state.args[windowId],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
case 'MAXIMIZE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
} = action;
|
||||
const args = {
|
||||
...state.args,
|
||||
0: state.args[windowId],
|
||||
};
|
||||
const { windowType, title } = state.windows.find((w) => w.windowId === windowId);
|
||||
delete args[windowId];
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
windowType,
|
||||
title,
|
||||
open: true,
|
||||
},
|
||||
windows: state.windows.filter((w) => w.windowId !== windowId),
|
||||
args,
|
||||
};
|
||||
}
|
||||
|
||||
case 'RESTORE_WINDOW': {
|
||||
const windowId = generateWindowId(state);
|
||||
const { windowType, title } = state.modal;
|
||||
const cloneable = true;
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
...state.modal,
|
||||
open: false,
|
||||
},
|
||||
windows: [
|
||||
...state.windows,
|
||||
{
|
||||
windowType,
|
||||
windowId,
|
||||
windowOpen: true,
|
||||
title,
|
||||
width: 600,
|
||||
height: 300,
|
||||
xPos: 200,
|
||||
yPos: 200,
|
||||
cloneable,
|
||||
},
|
||||
],
|
||||
args: {
|
||||
...state.args,
|
||||
[windowId]: {
|
||||
...state.args[0],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
case 'MOVE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
|
@ -112,6 +268,26 @@ export default function windows(
|
|||
};
|
||||
}
|
||||
|
||||
case 'RESIZE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
xDiff,
|
||||
yDiff,
|
||||
} = action;
|
||||
const newWindows = state.windows.map((win) => {
|
||||
if (win.windowId !== windowId) return win;
|
||||
return {
|
||||
...win,
|
||||
width: win.width + xDiff,
|
||||
height: win.height + yDiff,
|
||||
};
|
||||
});
|
||||
return {
|
||||
...state,
|
||||
windows: newWindows,
|
||||
};
|
||||
}
|
||||
|
||||
case 'CLOSE_ALL_WINDOWS': {
|
||||
return initialState;
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ tr:nth-child(even) {
|
|||
|
||||
.win-topbar {
|
||||
display: flex;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.win-title {
|
||||
|
@ -155,6 +156,29 @@ tr:nth-child(even) {
|
|||
border: solid black;
|
||||
border-width: thin;
|
||||
background-color: blue;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.win-resize {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: calc(100% - 4px);
|
||||
}
|
||||
|
||||
.win-content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100% - 16px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.contextmenu {
|
||||
|
@ -444,7 +468,7 @@ tr:nth-child(even) {
|
|||
width: 75%;
|
||||
}
|
||||
|
||||
.ModalClose {
|
||||
.ModalClose, .ModalRestore {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -459,11 +483,18 @@ tr:nth-child(even) {
|
|||
background-color: #f6f6f7;
|
||||
border-color: #dcddde;
|
||||
top: 30px;
|
||||
right: 40px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.ModalClose:hover {
|
||||
.ModalClose {
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
.ModalRestore {
|
||||
right: 90px;
|
||||
}
|
||||
|
||||
.ModalClose:hover, .ModalRestore:hover {
|
||||
background-color: #e3e3e4;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user