change layout styles, move BoardPage to separate file

This commit is contained in:
marlon-erler
2024-07-23 12:43:30 +02:00
parent 12947f8063
commit 3aae049106
7 changed files with 277 additions and 223 deletions
+10
View File
@@ -0,0 +1,10 @@
import * as React from "bloatless-react";
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
export function BoardPage(boardViewModel: BoardViewModel) {
return <div class="pane">
<div class="toolbar"></div>
<div class="content"></div>
</div>;
}
+28 -26
View File
@@ -37,32 +37,34 @@ export function MessagePage(messagePageViewModel: MessagePageViewModel) {
return (
<div id="message-page">
<div class="pane">
<div class="toolbar">
<span>{translations.chatPage.message.messagesHeadline}</span>
</div>
<div class="content">
{messageContainer}
<div id="composer">
<div class="content-width-constraint">
<div class="input-width-constraint">
<input
bind:value={messagePageViewModel.composingMessage}
on:enter={messagePageViewModel.sendMessage}
placeholder={
translations.chatPage.message.composerInputPlaceholder
}
></input>
<button
class="primary"
aria-label={
translations.chatPage.message.sendMessageButtonAudioLabel
}
on:click={messagePageViewModel.sendMessage}
toggle:disabled={messagePageViewModel.cannotSendMessage}
>
<span class="icon">send</span>
</button>
<div class="pane-wrapper">
<div class="pane">
<div class="toolbar">
<span>{translations.chatPage.message.messagesHeadline}</span>
</div>
<div class="content">
{messageContainer}
<div id="composer">
<div class="content-width-constraint">
<div class="input-width-constraint">
<input
bind:value={messagePageViewModel.composingMessage}
on:enter={messagePageViewModel.sendMessage}
placeholder={
translations.chatPage.message.composerInputPlaceholder
}
></input>
<button
class="primary"
aria-label={
translations.chatPage.message.sendMessageButtonAudioLabel
}
on:click={messagePageViewModel.sendMessage}
toggle:disabled={messagePageViewModel.cannotSendMessage}
>
<span class="icon">send</span>
</button>
</div>
</div>
</div>
</div>
+126 -118
View File
@@ -19,137 +19,145 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
return (
<div id="settings-page">
<div class="pane">
<div class="toolbar">
<span>{translations.chatPage.settings.settingsHeadline}</span>
</div>
<div class="content">
<label class="tile flex-no">
<span class="icon">forum</span>
<div>
<span>{translations.chatPage.settings.primaryChannelLabel}</span>
<input
bind:value={settingsPageViewModel.primaryChannelInput}
on:enter={settingsPageViewModel.setPrimaryChannel}
></input>
<div class="pane-wrapper">
<div class="pane">
<div class="toolbar">
<span>{translations.chatPage.settings.settingsHeadline}</span>
</div>
<div class="content">
<label class="tile flex-no">
<span class="icon">forum</span>
<div>
<span>
{translations.chatPage.settings.primaryChannelLabel}
</span>
<input
bind:value={settingsPageViewModel.primaryChannelInput}
on:enter={settingsPageViewModel.setPrimaryChannel}
></input>
</div>
</label>
<div class="flex-row justify-end width-input">
<button
class="width-50"
aria-label={
translations.chatPage.settings
.setPrimaryChannelButtonAudioLabel
}
on:click={settingsPageViewModel.setPrimaryChannel}
toggle:disabled={settingsPageViewModel.cannotSetPrimaryChannel}
>
{translations.general.setButton}
<span class="icon">check</span>
</button>
</div>
</label>
<div class="flex-row justify-end width-input">
<button
class="width-50"
aria-label={
translations.chatPage.settings.setPrimaryChannelButtonAudioLabel
}
on:click={settingsPageViewModel.setPrimaryChannel}
toggle:disabled={settingsPageViewModel.cannotSetPrimaryChannel}
>
{translations.general.setButton}
<span class="icon">check</span>
</button>
</div>
<hr></hr>
<hr></hr>
<div class="flex-row width-input margin-bottom">
<input
aria-label={
translations.chatPage.settings.newSecondaryChannelAudioLabel
}
placeholder={
translations.chatPage.settings.newSecondaryChannelPlaceholder
}
bind:value={settingsPageViewModel.newSecondaryChannelInput}
on:enter={settingsPageViewModel.addSecondaryChannel}
></input>
<button
class="primary"
aria-label={
translations.chatPage.settings
.addSecondaryChannelButtonAudioLabel
}
on:click={settingsPageViewModel.addSecondaryChannel}
toggle:disabled={settingsPageViewModel.cannotAddSecondaryChannel}
>
<span class="icon">add</span>
</button>
</div>
<div
class="flex-column gap width-input"
children:append={[
settingsPageViewModel.secondaryChannels,
secondaryChannelConverter,
]}
></div>
<hr></hr>
<label class="tile flex-no">
<span class="icon">key</span>
<div>
<span>{translations.chatPage.settings.encryptionKeyLabel}</span>
<div class="flex-row width-input margin-bottom">
<input
bind:value={settingsPageViewModel.encryptionKeyInput}
on:enter={settingsPageViewModel.setEncryptionKey}
set:type={settingsPageViewModel.encryptionKeyInputType}
aria-label={
translations.chatPage.settings.newSecondaryChannelAudioLabel
}
placeholder={
translations.chatPage.settings.newSecondaryChannelPlaceholder
}
bind:value={settingsPageViewModel.newSecondaryChannelInput}
on:enter={settingsPageViewModel.addSecondaryChannel}
></input>
<button
class="primary"
aria-label={
translations.chatPage.settings
.addSecondaryChannelButtonAudioLabel
}
on:click={settingsPageViewModel.addSecondaryChannel}
toggle:disabled={
settingsPageViewModel.cannotAddSecondaryChannel
}
>
<span class="icon">add</span>
</button>
</div>
</label>
<div class="flex-row justify-end width-input">
<button
class="width-50"
aria-label={
translations.chatPage.settings.setEncryptionKeyButtonAudioLabel
}
on:click={settingsPageViewModel.setEncryptionKey}
toggle:disabled={settingsPageViewModel.cannotSetEncryptionKey}
>
{translations.general.setButton}
<span class="icon">check</span>
</button>
</div>
<label class="inline">
<input
type="checkbox"
bind:checked={settingsPageViewModel.shouldShowEncryptionKey}
></input>
{translations.chatPage.settings.showEncryptionKey}
</label>
<div
class="flex-column gap width-input"
children:append={[
settingsPageViewModel.secondaryChannels,
secondaryChannelConverter,
]}
></div>
<hr></hr>
<hr></hr>
<div class="flex-row gap width-input">
{...Object.values(Color).map((color) => {
const isSelected = React.createProxyState(
[settingsPageViewModel.color],
() => settingsPageViewModel.color.value == color
);
<label class="tile flex-no">
<span class="icon">key</span>
<div>
<span>{translations.chatPage.settings.encryptionKeyLabel}</span>
<input
bind:value={settingsPageViewModel.encryptionKeyInput}
on:enter={settingsPageViewModel.setEncryptionKey}
set:type={settingsPageViewModel.encryptionKeyInputType}
></input>
</div>
</label>
<div class="flex-row justify-end width-input">
<button
class="width-50"
aria-label={
translations.chatPage.settings
.setEncryptionKeyButtonAudioLabel
}
on:click={settingsPageViewModel.setEncryptionKey}
toggle:disabled={settingsPageViewModel.cannotSetEncryptionKey}
>
{translations.general.setButton}
<span class="icon">check</span>
</button>
</div>
function setColor() {
settingsPageViewModel.setColor(color);
}
<label class="inline">
<input
type="checkbox"
bind:checked={settingsPageViewModel.shouldShowEncryptionKey}
></input>
{translations.chatPage.settings.showEncryptionKey}
</label>
return (
<button
color={color}
class="fill-color width-100 flex"
style="height: 2rem"
toggle:selected={isSelected}
on:click={setColor}
></button>
);
})}
</div>
<hr></hr>
<hr></hr>
<div class="flex-row gap width-input">
{...Object.values(Color).map((color) => {
const isSelected = React.createProxyState(
[settingsPageViewModel.color],
() => settingsPageViewModel.color.value == color
);
<div class="width-input">
{DangerousActionButton(
translations.chatPage.settings.deleteChatButton,
"chat_error",
settingsPageViewModel.remove
)}
function setColor() {
settingsPageViewModel.setColor(color);
}
return (
<button
color={color}
class="fill-color width-100 flex"
style="height: 2rem"
toggle:selected={isSelected}
on:click={setColor}
></button>
);
})}
</div>
<hr></hr>
<div class="width-input">
{DangerousActionButton(
translations.chatPage.settings.deleteChatButton,
"chat_error",
settingsPageViewModel.remove
)}
</div>
</div>
</div>
</div>
+34 -31
View File
@@ -1,6 +1,7 @@
import * as React from "bloatless-react";
import { BoardInfoToEntry } from "../Components/boardEntry";
import { BoardPage } from "./boardPage";
import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel";
import { translations } from "../translations";
@@ -13,53 +14,55 @@ export function TaskPage(taskPageViewModel: TaskPageViewModel) {
const selectedBoard = taskPageViewModel.selectedBoard.value;
if (selectedBoard == undefined) {
return [
<div class="content align-center justify-center">
<div class="pane align-center justify-center">
<span class="secondary">
{translations.chatPage.task.noBoardSelected}
</span>
</div>,
];
} else {
return [<div class="toolbar"></div>, <div class="content"></div>];
return BoardPage(selectedBoard);
}
}
);
return (
<div id="task-page">
<div class="pane side">
<div class="toolbar">
<div class="flex-row width-input">
<input
bind:value={taskPageViewModel.newBoardNameInput}
on:enter={taskPageViewModel.createBoard}
placeholder={translations.chatPage.task.newBoardNamePlaceholder}
></input>
<button
class="primary"
aria-label={
translations.chatPage.task.createBoardButtonAudioLabel
}
on:click={taskPageViewModel.createBoard}
toggle:disabled={taskPageViewModel.cannotCreateBoard}
>
<span class="icon">add</span>
</button>
<div class="pane-wrapper side">
<div class="pane">
<div class="toolbar">
<div class="flex-row width-input">
<input
bind:value={taskPageViewModel.newBoardNameInput}
on:enter={taskPageViewModel.createBoard}
placeholder={translations.chatPage.task.newBoardNamePlaceholder}
></input>
<button
class="primary"
aria-label={
translations.chatPage.task.createBoardButtonAudioLabel
}
on:click={taskPageViewModel.createBoard}
toggle:disabled={taskPageViewModel.cannotCreateBoard}
>
<span class="icon">add</span>
</button>
</div>
</div>
<div class="content">
<div
class="grid gap"
style="grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr))"
children:append={[
taskPageViewModel.boardViewModels,
BoardInfoToEntry,
]}
></div>
</div>
</div>
<div class="content">
<div
class="grid gap"
style="grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr))"
children:append={[
taskPageViewModel.boardViewModels,
BoardInfoToEntry,
]}
></div>
</div>
</div>
<div class="pane" children:set={paneContent}></div>
<div class="pane-wrapper" children:set={paneContent}></div>
</div>
);
}
+44 -20
View File
@@ -30,9 +30,9 @@ body[showing-chat] #chat-page-wrapper {
#chat-page > div > #ribbon,
#chat-page > div > #main,
#chat-page > div > #main > div,
#chat-page > div > #main > div > .pane,
#chat-page > div > #main > div > .pane > .toolbar,
#chat-page > div > #main > div > .pane > .content {
#chat-page > div > #main > div > .pane-wrapper > .pane,
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar,
#chat-page > div > #main > div > .pane-wrapper > .pane > .content {
display: flex;
}
@@ -50,40 +50,42 @@ body[showing-chat] #chat-page-wrapper {
}
#chat-page #main > div,
#chat-page > div > #main > div > .pane,
#chat-page > div > #main > div > .pane > .content {
#chat-page > div > #main > div > .pane-wrapper,
#chat-page > div > #main > div > .pane-wrapper > .pane,
#chat-page > div > #main > div > .pane-wrapper > .pane > .content {
width: 100%;
height: 100%;
flex: 1;
}
#chat-page > div > #main > div > .pane {
#chat-page > div > #main > div > .pane-wrapper,
#chat-page > div > #main > div > .pane-wrapper > .pane {
flex-direction: column;
scroll-snap-align: center;
min-width: 100%;
}
#chat-page > div > #main > div > .pane:not(.side),
#chat-page > div > #main > div > .pane:not(.side) .content {
#chat-page > div > #main > div > .pane-wrapper > .pane:not(.side),
#chat-page > div > #main > div > .pane-wrapper > .pane:not(.side) .content {
animation: slide-up var(--animation-duration);
}
@media (min-width: 1024px) {
#chat-page > div > #main > div > .pane {
#chat-page > div > #main > div > .pane-wrapper {
min-width: unset;
}
#chat-page > div > #main > div > .pane.side {
#chat-page > div > #main > div > .pane-wrapper.side {
max-width: 18rem;
}
}
#chat-page > div > #main > div > .pane:not(:last-child) {
#chat-page > div > #main > div > .pane-wrapper:not(:last-child) {
border-right: 1px solid var(--border);
}
#chat-page > div > #main > div > .pane > .content {
#chat-page > div > #main > div > .pane-wrapper > .pane > .content {
flex-direction: column;
overflow: auto;
padding: var(--content-padding);
@@ -97,12 +99,12 @@ body[showing-chat] #chat-page-wrapper {
/* ribbon, toolbar */
#chat-page > div > #ribbon,
#chat-page > div > #main > div > .pane > .toolbar {
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar {
align-items: center;
}
#chat-page #ribbon > span,
#chat-page > div > #main > div > .pane > .toolbar {
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar {
display: flex;
flex-direction: row;
align-items: center;
@@ -135,7 +137,7 @@ body[showing-chat] #chat-page-wrapper {
}
#chat-page > div > #ribbon button,
#chat-page > div > #main > div > .pane > .toolbar button {
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar button {
padding: 0px;
width: 100%;
@@ -148,13 +150,28 @@ body[showing-chat] #chat-page-wrapper {
}
#chat-page > div > #ribbon button.ribbon-button,
#chat-page > div > #main > div > .pane > .toolbar button.ribbon-button {
#chat-page
> div
> #main
> div
> .pane-wrapper
> .pane
> .toolbar
button.ribbon-button {
min-height: unset;
height: calc(var(--control-height) - 2 * var(--gap-between-tiles));
}
#chat-page > div > #ribbon button.ribbon-button > .icon,
#chat-page > div > #main > div > .pane > .toolbar button.ribbon-button > .icon {
#chat-page
> div
> #main
> div
> .pane-wrapper
> .pane
> .toolbar
button.ribbon-button
> .icon {
font-size: 1.1rem;
}
@@ -162,7 +179,7 @@ body[showing-chat] #chat-page-wrapper {
width: 100%;
}
#chat-page > div > #main > div > .pane > .toolbar {
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar {
height: var(--ribbon-size);
border-bottom: 1px solid var(--border);
@@ -173,11 +190,18 @@ body[showing-chat] #chat-page-wrapper {
border-top: 1px solid var(--border);
}
#chat-page > div > #main > div > .pane > .toolbar > span {
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar > span {
padding-left: var(--content-padding);
}
#chat-page > div > #main > div > .pane > .toolbar :is(input, select, button) {
#chat-page
> div
> #main
> div
> .pane-wrapper
> .pane
> .toolbar
:is(input, select, button) {
height: 100%;
flex: 1;
}