Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3c7ce97
resizeable broadcast sides
schlawg Mar 31, 2025
1a4073c
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 1, 2025
1414490
isCol1() means displayColumns() === 1
schlawg Apr 2, 2025
0e89a05
Merge remote-tracking branch 'upstream/master' into ui-broadcast-drag…
schlawg Apr 3, 2025
08afd36
move vertical resize separator to lib/controls, fix broadcast resize …
schlawg Apr 3, 2025
9a15f78
merge and make lint happy
schlawg Apr 3, 2025
65b44d4
Merge branch 'master' into ui-broadcast-draggable-side-divider
schlawg Apr 4, 2025
c387d5c
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 5, 2025
e53282f
fix oversized games list on first time broadcast with many boards
schlawg Apr 5, 2025
f8ac4bf
make adequate room for chessground
schlawg Apr 5, 2025
6e924ce
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 8, 2025
c8645ae
fix merge conflicts
ornicar Apr 8, 2025
c7c61c5
extract to lib/view/verticalResize
ornicar Apr 8, 2025
2ff182d
minor tweaks while reading verticalResize
ornicar Apr 8, 2025
b916290
tweak relay tournament resizer id generation
ornicar Apr 8, 2025
39e86d2
vertical resizer style tweaks
ornicar Apr 8, 2025
cd88c46
Merge remote-tracking branch 'upstream/master' into ui-broadcast-drag…
schlawg Apr 8, 2025
7760ce2
dont use separate snabbdom patch for analysis chat
schlawg Apr 9, 2025
f26ee69
remove viewers text popin
schlawg Apr 9, 2025
61b7434
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 9, 2025
2831f9b
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 9, 2025
f550ecc
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 9, 2025
82a6060
rename to ui/lib/chat/standalone
ornicar Apr 9, 2025
6e90971
to use liveboard plugin one must add liveboard plugin
schlawg Apr 9, 2025
fee3cb6
immediate chat scroll to bottom on resets
schlawg Apr 9, 2025
7932524
calculate min chat height and dont change grid behavior on touch devices
schlawg Apr 9, 2025
0236957
larger resize controls less claustrophobic
schlawg Apr 9, 2025
7a39d8a
Merge branch 'master' into ui-broadcast-draggable-side-divider
ornicar Apr 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 64 additions & 31 deletions ui/analyse/css/study/relay/_layout.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
$mq-col3-side-height: calc(100vh - #{$site-header-outer-height} - #{$col1-uniboard-controls});

body {
---site-header-margin: #{$site-header-margin-extra};
---allow-video: false;
Expand All @@ -9,6 +7,19 @@ body {
}
}

@mixin resizable-side {
.vertical-resize-separator {
display: flex;
}
.mchat {
margin-top: 0;
min-height: 52px;
}
.relay-admin {
margin-top: 0;
}
}

main.is-relay {
.relay-tour {
grid-area: relay-tour;
Expand All @@ -25,8 +36,11 @@ main.is-relay {
button.streamer-show {
display: block;
}
.mchat {
flex: 1 1 50%;
@media (pointer: fine) {
.relay-admin__container {
grid-area: none;
}
@include resizable-side;
}
}
}
Expand All @@ -39,31 +53,21 @@ main.is-relay.has-relay-tour {
'side'
'relay-admin';
.relay-games {
max-height: 40vh;
height: 40vh;
}

@include mq-at-least-col2 {
grid-template-rows: 80vh;
grid-template-areas:
'relay-tour . side'
'relay-tour . relay-admin';
.mchat {
margin-top: $analyse-block-gap;
flex: 5 0 30%;
}
.relay-games {
max-height: unset;
grid-template-areas: 'relay-tour . side';
@media (pointer: fine) {
@include resizable-side;
}
}

@include mq-at-least-col3 {
grid-template-columns:
$col3-uniboard-side $analyse-block-gap var(---col3-uniboard-width)
$analyse-block-gap $col3-uniboard-table;
grid-template-rows: $mq-col3-side-height;
grid-template-areas:
'side . relay-tour relay-tour relay-tour'
'relay-admin . relay-tour relay-tour relay-tour';
grid-template-areas: 'side . relay-tour relay-tour relay-tour';
}
}

Expand Down Expand Up @@ -105,22 +109,14 @@ main.analyse.is-relay:not(.has-relay-tour) {
grid-template-areas:
'side . board gauge tools'
'side . board . controls'
'side . under under under'
'relay-admin . under under under';
.relay-tour__side {
max-height: $mq-col3-side-height;
}
'side . under under under';
.mchat,
.chat__members {
display: flex;
}
.mchat {
margin-top: $analyse-block-gap;
flex: 5 0 30%;

&:has(.liveboard.mchat__tab-active) {
min-height: 374px;
}
.mchat:has(.liveboard.mchat__tab-active) {
max-height: 380px;
min-height: 380px; // constrain height set by vertical-resize-separator
}
}
.eval-chart-and-training {
Expand All @@ -139,3 +135,40 @@ main.analyse.is-relay:not(.has-relay-tour) {
}
}
}

.vertical-resize-separator {
@extend %flex-column;
@include transition;
position: relative;
display: none;
justify-content: center;
align-items: center;
cursor: row-resize;
width: 100%;
height: 22px;

&:hover {
background: $m-primary--fade-70;
hr {
background: $c-font;
width: 40px;
}
}
hr {
@include transition;
margin: 0;
width: 14px;
height: 1px;
pointer-events: none;
}
.chat__members {
position: absolute;
top: 0;
left: 0;
margin: 4px;
}
}

.vertical-spacer {
height: $block-gap; // in lieu of resize divider when there is no games list
}
20 changes: 10 additions & 10 deletions ui/analyse/src/ctrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,7 @@ import { debounce, throttle } from 'lib/async';
import type GamebookPlayCtrl from './study/gamebook/gamebookPlayCtrl';
import type StudyCtrl from './study/studyCtrl';
import { isTouchDevice } from 'lib/device';
import type {
AnalyseOpts,
AnalyseData,
ServerEvalData,
JustCaptured,
NvuiPlugin,
MultiRedraw,
} from './interfaces';
import type { AnalyseOpts, AnalyseData, ServerEvalData, JustCaptured, NvuiPlugin } from './interfaces';
import type { Api as ChessgroundApi } from 'chessground/api';
import { Autoplay, AutoplayDelay } from './autoplay';
import { build as makeTree, path as treePath, ops as treeOps, type TreeWrapper } from 'lib/tree/tree';
Expand Down Expand Up @@ -52,6 +45,7 @@ import ForecastCtrl from './forecast/forecastCtrl';
import { type ArrowKey, type KeyboardMove, ctrl as makeKeyboardMove } from 'keyboardMove';
import * as control from './control';
import type { PgnError } from 'chessops/pgn';
import { ChatCtrl } from 'lib/chat/chatCtrl';
import { confirm } from 'lib/view/dialogs';
import api from './api';

Expand Down Expand Up @@ -83,6 +77,7 @@ export default class AnalyseCtrl {
study?: StudyCtrl;
studyPractice?: StudyPracticeCtrl;
promotion: PromotionCtrl;
chatCtrl: ChatCtrl;
wiki?: WikiTheory;

// state flags
Expand Down Expand Up @@ -131,7 +126,7 @@ export default class AnalyseCtrl {

constructor(
readonly opts: AnalyseOpts,
readonly redraw: MultiRedraw,
readonly redraw: Redraw,
makeStudy?: typeof StudyCtrl,
) {
this.data = opts.data;
Expand Down Expand Up @@ -190,7 +185,12 @@ export default class AnalyseCtrl {
}
site.redirect('/analysis');
}

if (this.opts.chat && !this.isEmbed) {
this.chatCtrl = new ChatCtrl(
{ ...this.opts.chat, enhance: { plies: true, boards: !!this.study?.relay } },
this.redraw,
);
}
pubsub.on('jump', (ply: string) => {
this.jumpToMain(parseInt(ply));
this.redraw();
Expand Down
8 changes: 2 additions & 6 deletions ui/analyse/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Player, Status, Source, Clock } from 'lib/game/game';
import type { ForecastData } from './forecast/interfaces';
import type { StudyPracticeData, Goal as PracticeGoal } from './study/practice/interfaces';
import type { RelayData } from './study/relay/interfaces';
import type { ChatCtrl, ChatPlugin } from 'lib/chat/chat';
import type { ChatCtrl, ChatPlugin, ChatOpts } from 'lib/chat/interfaces';
import type { ExplorerOpts } from './explorer/interfaces';
import type { StudyDataFromServer } from './study/interfaces';
import type { AnalyseSocketSend } from './socket';
Expand Down Expand Up @@ -148,7 +148,7 @@ export interface AnalyseOpts {
relay?: RelayData;
$side?: Cash;
$underboard?: Cash;
chat: {
chat: ChatOpts & {
plugin: ChatPlugin;
enhance: EnhanceOpts;
instance?: ChatCtrl;
Expand Down Expand Up @@ -185,7 +185,3 @@ export interface AnalyseState {
path: Tree.Path | undefined;
flipped: boolean;
}

export type MultiRedraw = Redraw & {
add: (redraw: Redraw) => void;
};
17 changes: 2 additions & 15 deletions ui/analyse/src/start.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import makeCtrl from './ctrl';
import menuHover from 'lib/menuHover';
import makeView from './view/main';
import type { AnalyseApi, AnalyseOpts, MultiRedraw } from './interfaces';
import type { AnalyseApi, AnalyseOpts } from './interfaces';
import type { VNode } from 'snabbdom';
import type * as studyDeps from './study/studyDeps';

Expand All @@ -12,7 +12,7 @@ export default function (
return function (opts: AnalyseOpts): AnalyseApi {
opts.element = document.querySelector('main.analyse') as HTMLElement;

const ctrl = (site.analysis = new makeCtrl(opts, multiRedraw(redraw), deps?.StudyCtrl));
const ctrl = (site.analysis = new makeCtrl(opts, redraw, deps?.StudyCtrl));
const view = makeView(deps);

const blueprint = view(ctrl);
Expand All @@ -34,16 +34,3 @@ export default function (
};
};
}

function multiRedraw(base: Redraw): MultiRedraw {
// to build redraws involving multiple patch functions.
const redraws: Redraw[] = [base];
const multi: MultiRedraw = () => {
for (const r of redraws) r();
};

multi.add = (r: Redraw) => {
redraws.push(r);
};
return multi;
}
Original file line number Diff line number Diff line change
@@ -1,51 +1,26 @@
import { type RelayViewContext } from '../../view/components';
import { looseH as h, VNode, onInsert } from 'lib/snabbdom';
import { looseH as h, VNode } from 'lib/snabbdom';
import { getChessground, initMiniBoardWith } from 'lib/view/miniBoard';
import { fenColor, uciToMove } from 'lib/game/chess';
import { type ChatPlugin, makeChat } from 'lib/chat/chat';
import { type TreeWrapper } from 'lib/tree/tree';
import { type ChatPlugin } from 'lib/chat/interfaces';
import type AnalyseCtrl from '@/ctrl';
import { mainlineNodeList } from 'lib/tree/ops';
import { watchers } from 'lib/view/watchers';
import { frag } from 'lib';
import { type ChapterId } from '../interfaces';
import { type StudyChapters } from '../studyChapters';
import { spinnerVdom } from 'lib/view/controls';

type BoardConfig = CgConfig & { lastUci?: Uci };

export function relayChatView({ ctrl, relay }: RelayViewContext): VNode | undefined {
if (ctrl.isEmbed || !ctrl.opts.chat) return undefined;
return h('section.mchat.mchat-optional', {
hook: onInsert(() => {
ctrl.opts.chat.instance?.destroy();
ctrl.opts.chat.instance = makeChat({
...ctrl.opts.chat,
plugin: relay.chatCtrl,
persistent: true,
enhance: { plies: true, boards: true },
});
const members = frag<HTMLElement>('<div class="chat__members">');
document.querySelector('.relay-tour__side')?.append(members);
watchers(members, false);
}),
});
}

export class RelayChatPlugin implements ChatPlugin {
export class LiveboardPlugin implements ChatPlugin {
private animate = false;
private board: BoardConfig | undefined;
private chapter: ChapterId | undefined;
key = 'liveboard';
name = i18n.broadcast.liveboard;
kidSafe = true;
redraw: Redraw;
isDisabled = () => true;

constructor(
readonly previews: () => StudyChapters,
readonly localTree: () => TreeWrapper,
readonly relayPath: () => Tree.Path | undefined,
readonly orientation: () => Color,
readonly ctrl: AnalyseCtrl,
readonly isDisabled: () => boolean,
private chapter: ChapterId | undefined,
) {}

reset = () => {
Expand All @@ -61,15 +36,15 @@ export class RelayChatPlugin implements ChatPlugin {
}

view(): VNode {
const path = this.relayPath();
const tree = this.localTree();
const path = this.ctrl.study?.data.chapter.relayPath;
const tree = this.ctrl.tree;
const localMainline = mainlineNodeList(tree.root);
const node = localMainline[localMainline.length - 1];
if (path) {
const node = tree.nodeAtPath(path);
this.board = { fen: node.fen, check: !!node.check && fenColor(node.fen), lastUci: node.uci };
} else if (this.chapter && !this.board) {
const preview = this.previews().get(this.chapter);
const preview = this.ctrl.study?.chapters.list.get(this.chapter);
if (!preview) return spinnerVdom();
this.board = {
fen: preview.fen,
Expand All @@ -80,7 +55,7 @@ export class RelayChatPlugin implements ChatPlugin {
this.board ??= { fen: node.fen, lastUci: node.uci, check: !!node.check && fenColor(node.fen) };
this.board.animation = { enabled: this.animate };
this.board.lastMove = uciToMove(this.board.lastUci);
this.board.orientation = this.orientation();
this.board.orientation = this.ctrl.bottomColor();
this.animate = true;

return h('div.chat-liveboard', {
Expand Down
Loading