Ejemplo n.º 1
0
Archivo: tree.ts Proyecto: luanlv/lila
function renderChildrenOf(ctx, node, opts): MaybeVNodes {
  const cs = node.children, main = cs[0];
  if (!main) return [];
  if (opts.isMainline) {
    const isWhite = main.ply % 2 === 1;
    if (!cs[1]) return [
      isWhite ? renderIndex(main.ply, false) : null,
      ...renderMoveAndChildrenOf(ctx, main, {
        parentPath: opts.parentPath,
        isMainline: true
      })
    ];
    const mainChildren = renderChildrenOf(ctx, main, {
      parentPath: opts.parentPath + main.id,
      isMainline: true
    }),
    passOpts = {
      parentPath: opts.parentPath,
      isMainline: true
    };
    return [
      isWhite ? renderIndex(main.ply, false) : null,
      renderMoveOf(ctx, main, passOpts),
      isWhite ? emptyMove() : null,
      h('interrupt', renderLines(ctx, cs.slice(1), {
        parentPath: opts.parentPath,
        isMainline: true
      })),
      ...(isWhite && mainChildren ? [
        renderIndex(main.ply, false),
        emptyMove()
      ] : []),
      ...mainChildren
    ];
  }
  return cs[1] ? [renderLines(ctx, cs, opts)] : renderMoveAndChildrenOf(ctx, main, opts);
}
Ejemplo n.º 2
0
export default function(ctrl: Controller): VNode {
  const showCeval = ctrl.vm.showComputer();
  if (cevalShown !== showCeval) {
    if (!cevalShown) ctrl.vm.autoScrollNow = true;
    cevalShown = showCeval;
  }
  return h('div#puzzle.cg-512', [
    h('div', {
      hook: {
        insert: _ => window.lichess.pubsub.emit('reset_zoom')()
      },
      class: { gauge_displayed: ctrl.showEvalGauge() }
    }, [
      h('div.lichess_game' + (ctrl.pref.blindfold ? '.blindfold' : ''), {
        hook: {
          insert: _ => window.lichess.pubsub.emit('content_loaded')()
        }
      }, [
        visualBoard(ctrl),
        h('div.lichess_ground', [
          // we need the wrapping div here
          // so the siblings are only updated when ceval is added
          h('div', showCeval ? [
            cevalView.renderCeval(ctrl),
            cevalView.renderPvs(ctrl)
          ] : []),
          renderAnalyse(ctrl),
          feedbackView(ctrl),
          buttons(ctrl)
        ])
      ])
    ]),
    h('div.underboard', [
      h('div.center', [
        historyView(ctrl)
      ])
    ])
  ]);
};
Ejemplo n.º 3
0
function renderTournament(ctrl, tour) {
  let width = tour.minutes * scale;
  const left = leftPos(tour.startsAt);
  // moves content into viewport, for long tourneys and marathons
  const paddingLeft = tour.minutes < 90 ? 0 : Math.max(0,
    Math.min(width - 250, // max padding, reserved text space
      leftPos(now) - left - 380)); // distance from Now
      // cut right overflow to fit viewport and not widen it, for marathons
      width = Math.min(width, leftPos(stopTime) - left);

      return h('a.tournament', {
        class: tournamentClass(tour),
        attrs: {
          href: '/tournament/' + tour.id,
          style: 'width: ' + width + 'px; left: ' + left + 'px; padding-left: ' + paddingLeft + 'px'
        },
      }, [
        h('span.icon', tour.perf ? {
          attrs: {
            'data-icon': tour.perf.icon,
            title: tour.perf.name
          }
        } : {}),
        h('span.body', [
          h('span.name', tour.fullName),
          h('span.infos', [
            h('span.text', [
              displayClock(tour.clock) + ' ',
              tour.variant.key === 'standard' ? null : tour.variant.name + ' ',
              tour.position ? 'Thematic ' : null,
              tour.rated ? ctrl.trans('rated') : ctrl.trans('casual')
            ]),
            tour.nbPlayers ? h('span.nb-players', {
              attrs: { 'data-icon': 'r' }
            }, tour.nbPlayers) : null
          ])
        ])
      ]);
}
Ejemplo n.º 4
0
export function view(ctrl): VNode {
  const candidates = ctrl.candidates();
  return dialog.form({
    class: 'study_invite',
    onClose() {
      ctrl.open(false);
      ctrl.redraw();
    },
    content: [
      h('h2', 'Invite to the study'),
      h('p.info', { attrs: { 'data-icon': '' } }, [
        'Please only invite people you know,',
        h('br'),
        'and who actively want to join this study.'
      ]),
      candidates.length ? h('div.users', candidates.map(function(username) {
        return h('span.user_link.button', {
          key: username,
          attrs: { 'data-href': '/@/' + username },
          hook: bind('click', _ => ctrl.invite(username))
        }, username);
      })) : undefined,
      h('div.input-wrapper', [ // because typeahead messes up with snabbdom
        h('input', {
          attrs: { placeholder: 'Search by username' },
          hook: {
            insert: vnode => {
              const el = vnode.elm as HTMLInputElement;
              window.lichess.userAutocomplete($(el), {
                tag: 'span',
                onSelect(v) {
                  ctrl.invite(v.name);
                  $(el).typeahead('close');
                  el.value = '';
                  ctrl.redraw();
                }
              });
            }
          }
        })
      ])
    ]
  });
}
Ejemplo n.º 5
0
 ctrl.data.nowPlaying.map(function(pov) {
   return h('a.mini_board.is2d.' + pov.variant.key + (pov.isMyTurn ? '.my_turn' : ''), {
     key: pov.gameId,
     attrs: { href: '/' + pov.fullId }
   }, [
     h('div', [
       h('div.cg-board-wrap', {
         hook: {
           insert(vnode) {
             const lm = pov.lastMove;
             const config = {
               coordinates: false,
               drawable: { enabled: false, visible: false },
               resizable: false,
               viewOnly: true,
               orientation: pov.variant.key === 'racingKings' ? 'white' : pov.color,
               fen: pov.fen,
               lastMove: lm && [lm[0] + lm[1], lm[2] + lm[3]]
             };
             Chessground(vnode.elm as HTMLElement, config);
           }
         }
       }, [ h('div.cg-board') ])
     ]),
     h('span.meta', [
       pov.opponent.ai ? ctrl.trans('aiNameLevelAiLevel', 'Stockfish', pov.opponent.ai) : pov.opponent.username,
       h('span.indicator',
         pov.isMyTurn ?
         (pov.secondsLeft ? timer(pov) : ctrl.trans('yourTurn')) :
         h('span', {
           hook: {
             insert(vnode) {
               (vnode.elm as HTMLElement).innerHTML = '&nbsp;';
             }
           }
         }))
     ])
   ]);
 }));
Ejemplo n.º 6
0
export default function(ctrl, color, position) {
  if (!ctrl.node.crazy) return;
  const pocket = ctrl.node.crazy.pockets[color === 'white' ? 0 : 1];
  const dropped = ctrl.justDropped;
  let captured = ctrl.justCaptured;
  if (captured) {
    captured = captured.promoted ? 'pawn' : captured.role;
  }
  const activeColor = color === ctrl.turnColor();
  const usable = !ctrl.embed && activeColor;
  return h('div.pocket.is2d.' + position, {
    class: { usable },
    hook: {
      insert: vnode => {
        if (ctrl.embed) return;
        eventNames.forEach(name => {
          (vnode.elm as HTMLElement).addEventListener(name, e => drag(ctrl, color, e as MouchEvent));
        });
      }
    }
  }, oKeys.map(role => {
    let nb = pocket[role] || 0;
    if (activeColor) {
      if (dropped === role) nb--;
      if (captured === role) nb++;
    }
    return h('piece.' + role + '.' + color, {
      attrs: {
        'data-role': role,
        'data-color': color,
        'data-nb': nb
      }
    });
  })
  );
}
Ejemplo n.º 7
0
function renderMoves(ctrl: RoundController): MaybeVNodes {
  const steps = ctrl.data.steps,
    firstPly = round.firstPly(ctrl.data),
    lastPly = round.lastPly(ctrl.data);
  if (typeof lastPly === 'undefined') return [];

  const pairs: Array<Array<any>> = [];
  let startAt = 1;
  if (firstPly % 2 === 1) {
    pairs.push([null, steps[1]]);
    startAt = 2;
  }
  for (let i = startAt; i < steps.length; i += 2) pairs.push([steps[i], steps[i + 1]]);

  const els: MaybeVNodes = [], curPly = ctrl.ply;
  for (let i = 0; i < pairs.length; i++) {
    els.push(h('index', i + 1 + ''));
    els.push(renderMove(pairs[i][0], curPly));
    els.push(renderMove(pairs[i][1], curPly));
  }
  els.push(renderResult(ctrl));

  return els;
}
Ejemplo n.º 8
0
 return (c: Challenge) => {
   return h('div.challenge.' + dir + '.c-' + c.id, {
     class: {
       declined: !!c.declined
     }
   }, [
     h('div.content', [
       h('span.head', renderUser(dir === 'in' ? c.challenger : c.destUser)),
       h('span.desc', [
         ctrl.trans()(c.rated ? 'rated' : 'casual'),
         timeControl(c.timeControl),
         c.variant.name
       ].join(' • '))
     ]),
     h('i', {
       attrs: {'data-icon': c.perf.icon}
     }),
     h('div.buttons', (dir === 'in' ? inButtons : outButtons)(ctrl, c))
   ]);
 };
Ejemplo n.º 9
0
export function view(ctrl: BoardCtrl): VNode {

  return h('div.sub.board', [
    header(ctrl.trans.noarg('boardGeometry'), ctrl.close),
    h('div.selector', [
      h('a.text', {
        class: { active: !ctrl.data.is3d },
        attrs: { 'data-icon': 'E' },
        hook: bind('click', () => ctrl.setIs3d(false))
      }, '2D'),
      h('a.text', {
        class: { active: ctrl.data.is3d },
        attrs: { 'data-icon': 'E' },
        hook: bind('click', () => ctrl.setIs3d(true))
      }, '3D')
    ]),
    h('div.zoom', [
      h('h2', ctrl.trans.noarg('boardSize')),
      h('div.slider', {
        hook: { insert: vnode => makeSlider(ctrl, vnode.elm as HTMLElement) }
      })
    ])
  ]);
}
Ejemplo n.º 10
0
export function renderIndexAndMove(ctx: Ctx, node): VNode[] {
  return node.uci ?
  [renderIndex(node.ply, ctx.withDots)].concat(renderMove(ctx, node)) :
  [h('span.init', 'Initial position')];
}