Skip to content

Commit

Permalink
web: show like button next to each sub header of a file
Browse files Browse the repository at this point in the history
Also fix a billion other things that you notice after starting at the UI
for 20 hours:

* issue tabs not getting active
* user page article over indented to left
  • Loading branch information
cirosantilli committed Jul 26, 2022
1 parent a9fd588 commit 407dd14
Show file tree
Hide file tree
Showing 31 changed files with 535 additions and 321 deletions.
57 changes: 40 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2907,6 +2907,10 @@ function convert_init_context(options={}, extra_returns={}) {
if (!('root_relpath' in options.template_vars)) { options.template_vars.root_relpath = ''; }
if (!('post_body' in options.template_vars)) { options.template_vars.post_body = ''; }
if (!('style' in options.template_vars)) { options.template_vars.style = ''; }
if (!('web' in options)) {
// If true, inject elements that are used for OurBigBook Web.
options.web = false;
}

// Internalish options that may get modified by sub-includes/OurBigBookExample in order
// to forward state back up. Maybe we should move them to a subdict to make this clearer
Expand Down Expand Up @@ -7804,7 +7808,12 @@ const OUTPUT_FORMATS_LIST = [
let id_attr = html_render_attrs_id(ast, context);
let ret = '';
// Div that contains h + on hover span.
ret += `<div class="h"${id_attr}>`;
let first_header = (
// May fail in some error scenarios.
context.toplevel_ast !== undefined &&
ast.id === context.toplevel_ast.id
)
ret += `<div class="h${first_header ? ' top' : ''}"${id_attr}>`;

// Self link.
let self_link_context
Expand All @@ -7821,7 +7830,7 @@ const OUTPUT_FORMATS_LIST = [
self_link_context = context
self_link_ast = ast
}
ret += `<h${level_int_capped}${attrs}><a${x_href_attr(self_link_ast, self_link_context)}>`;
ret += `<div class="notnav"><h${level_int_capped}${attrs}><a${x_href_attr(self_link_ast, self_link_context)}>`;

let x_text_options = {
show_caption_prefix: false,
Expand All @@ -7838,21 +7847,31 @@ const OUTPUT_FORMATS_LIST = [
ret += `</a>`;
ret += `</h${level_int_capped}>\n`;

const web_meta = []
if (context.options.web) {
const web_html = `<div class="web${first_header ? ' top' : ''}"></div>`
if (first_header) {
web_meta.push(web_html)
} else {
ret += web_html
}
}

// On hover metadata.
let link_to_split;
let parent_links;
{
ret += `<span class="hover-meta"> `;
const items = []
if (context.options.split_headers) {
link_to_split = link_to_split_opposite(ast, context);
if (link_to_split) {
ret += `${HEADER_MENU_ITEM_SEP}${link_to_split}`;
items.push(`${link_to_split}`);
}
}
let toc_href;
if (!is_top_level && context.has_toc) {
toc_href = html_attr('href', '#' + html_escape_attr(toc_id(ast, context)));
ret += `${HEADER_MENU_ITEM_SEP}<a${toc_href} class="ourbigbook-h-to-toc"${html_attr('title', 'ToC entry for this header')}>${TOC_MARKER}</a>`;
items.push(`<a${toc_href} class="toc"${html_attr('title', 'ToC entry for this header')}>${TOC_MARKER}</a>`);
}

// Parent links.
Expand All @@ -7865,16 +7884,24 @@ const OUTPUT_FORMATS_LIST = [
}
parent_links = parent_links.join(HEADER_MENU_ITEM_SEP);
if (parent_links) {
ret += `${HEADER_MENU_ITEM_SEP}${parent_links}`;
items.push(parent_links);
}
let descendant_count = get_descendant_count_html(context, ast.header_tree_node, { long_style: true });
if (descendant_count !== undefined) {
ret += `${HEADER_MENU_ITEM_SEP}${descendant_count}`;
items.push(`${descendant_count}`);
}

ret += `</span>`;
if (!first_header) {
ret += `<span class="hover-meta"> `;
if (!context.options.web) {
ret += HEADER_MENU_ITEM_SEP
}
ret += items.join(HEADER_MENU_ITEM_SEP)
ret += `</span>`;
}
}
ret += `</div>`;
// .notnav
ret += '</div>'

// Metadata that shows on separate lines below toplevel header.
let wiki_link;
Expand Down Expand Up @@ -7947,11 +7974,6 @@ const OUTPUT_FORMATS_LIST = [
// Calculate header_meta and header_meta
let header_meta = [];
let header_meta2 = [];
let first_header = (
// May fail in some error scenarios.
context.toplevel_ast !== undefined &&
ast.id === context.toplevel_ast.id
)
if (file_link_html !== undefined) {
header_meta2.push(file_link_html);
}
Expand All @@ -7969,7 +7991,7 @@ const OUTPUT_FORMATS_LIST = [
header_meta.push(link_to_split);
}
if (context.has_toc) {
header_meta.push(`<a${html_attr('href', '#' + Macro.TOC_ID)}>${TOC_MARKER}</a>`);
header_meta.push(`<a${html_attr('href', '#' + Macro.TOC_ID)} class="toc">${TOC_MARKER}</a>`);
}
let descendant_count_html = get_descendant_count_html(context, ast.header_tree_node, { long_style: true });
if (descendant_count_html !== undefined) {
Expand All @@ -7981,14 +8003,15 @@ const OUTPUT_FORMATS_LIST = [
if (header_has_meta) {
ret += `<nav class="h-nav h-nav-toplevel">`;
}
for (const meta of [header_meta, header_meta2]) {
for (const meta of [web_meta, header_meta, header_meta2]) {
if (meta.length > 0) {
ret += `<div class="nav"> ${meta.join(HEADER_MENU_ITEM_SEP)}</div>`;
}
}
if (header_has_meta) {
ret += `</nav>\n`;
}
ret += `</div>`;
if (showTags) {
if (children !== undefined) {
ret += header_check_child_tag_exists(ast, context, children, 'child')
Expand Down Expand Up @@ -8108,7 +8131,7 @@ const OUTPUT_FORMATS_LIST = [
root_node = root_node.children[0];
}
let descendant_count_html = get_descendant_count_html_sep(context, root_node, { long_style: false, show_descendant_count: true });
ret += `${TOC_ARROW_HTML}<span class="not-arrow"><a class="title"${x_href_attr(ast, context)}>Table of contents</a><span class="hover-metadata">${descendant_count_html}</span></span></div>\n`;
ret += `${TOC_ARROW_HTML}<span class="not-arrow"><a class="title toc"${x_href_attr(ast, context)}>Table of contents</a><span class="hover-metadata">${descendant_count_html}</span></span></div>\n`;
for (let i = root_node.children.length - 1; i >= 0; i--) {
todo_visit.push([root_node.children[i], 1]);
}
Expand Down
1 change: 1 addition & 0 deletions main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ $header-background-color: #AA0;
body {
background-color: $color;
font-family: $font-family;
padding-top: $header-font-size;

header, footer {
background-color: $header-background-color;
Expand Down
8 changes: 8 additions & 0 deletions models/id.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@ module.exports = (sequelize) => {
// ID is moved between two files. Previousy, we were nuking the DB of files to be converted,
// and just extracing IDs every time. But with timestamp skipping, we just don't know if the
// ID was moved between files or not until everything is done.
//
// Once there are no conversion errors however and the DB is stable, then they should be unique.
//unique: true,
},
// Path at which the ID is defined, relative to project toplevel. E.g.:
// animal/dog.bigb
// or on web:
// @username/dog.bigb
// It would likely have been nicer if we had just not kept the extension in there,
// but lazy to change now.
path: {
type: DataTypes.TEXT,
allowNull: false,
Expand Down
2 changes: 1 addition & 1 deletion models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function addModels(sequelize, { web, cli }={}) {
Ref.belongsTo(Id, { as: 'to', foreignKey: 'to_id', targetKey: 'idid', constraints: false })
Id.hasMany(Ref, { as: 'from', foreignKey: 'from_id', sourceKey: 'idid', constraints: false })
Ref.belongsTo(Id, { as: 'from', foreignKey: 'from_id', targetKey: 'idid', constraints: false })
Id.hasMany(File, { foreignKey: 'toplevel_id', sourceKey: 'idid', constraints: false })
Id.hasOne(File, { foreignKey: 'toplevel_id', sourceKey: 'idid', constraints: false })
File.belongsTo(Id, { foreignKey: 'toplevel_id', targetKey: 'idid', constraints: false })

// Needed for finding duplicates.
Expand Down
1 change: 1 addition & 0 deletions ourbigbook.common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ $toplevel-horizontal-padding-left: 20px;
$toplevel-horizontal-padding-right: 15px;

$font-family: Arial, Helvetica, sans-serif;
$header-font-size: 24px;

@mixin body {
background-color: $background-color;
Expand Down
66 changes: 46 additions & 20 deletions ourbigbook.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
@font-face { font-family: fa-solid-900; src: url(node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2); }

$caption-margin-bottom: 5px;
$header-font-size: 24px;
$p-margin-vert: 14px;
$max-mobile-width: 450px;
$toplevel-horizontal-padding-mobile: 5px;
Expand Down Expand Up @@ -83,6 +82,9 @@ a {
&:visited {
color: $a-color-visited;
}
&.toc {
color: $a-color;
}
}

padding-left: 0;
Expand Down Expand Up @@ -157,28 +159,30 @@ figure {
}

div.h {
font-size: $header-font-size;
font-weight: bold;
margin: 20px 0 8px;
width: 100%;
box-sizing: border-box;
h1, h2, h3, h4, h5, h6 {
> a:first-child {
color: $color;
&:visited {
div.notnav {
display: inline-block;
font-size: $header-font-size;
font-weight: bold;
width: 100%;
box-sizing: border-box;
h1, h2, h3, h4, h5, h6 {
> a:first-child {
color: $color;
&:visited {
color: $color;
}
}
display: inline;
margin: 0;
// To make `word-wrap: break-word;` work, otherwise it does not take effect.
overflow-wrap: break-word;
}
h1 {
font-size: $header-font-size * 1.5;
}
h2, h3, h4, h5, h6 {
font-size: $header-font-size;
}
display: inline;
margin: 0;
// To make `word-wrap: break-word;` work, otherwise it does not take effect.
overflow-wrap: break-word;
}
h1 {
font-size: $header-font-size * 1.5;
}
h2, h3, h4, h5, h6 {
font-size: $header-font-size;
}
.hover-meta {
@include hidden;
Expand All @@ -188,10 +192,32 @@ div.h {
@include visible;
}
}
&.top {
div.notnav {
margin-bottom: 10px;
}
}
// Also show header metadata when the header is selected as the current #fragment.
&:target .hover-meta {
@include visible;
}
.web {
display: inline;
&.top {
font-size: 18px;
}
&:not(.top) {
a,btn, button {
vertical-align: text-bottom;
}
}
.issues {
color: $a-color;
&:visited {
color: $a-color;
}
}
}
}
nav.h-nav {
margin-bottom: $p-margin-vert;
Expand Down
22 changes: 18 additions & 4 deletions web/back/ArticlePage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ourbigbook from 'ourbigbook'

import { getLoggedInUser } from 'back'
import { ArticlePageProps } from 'front/ArticlePage'
import { MyGetServerSideProps } from 'front/types'
Expand All @@ -14,20 +16,30 @@ export const getServerSidePropsArticleHoc = ({
={}): MyGetServerSideProps => {
return async ({ params: { slug }, req, res }) => {
if (slug instanceof Array) {
const slugString = slug.join('/')
const sequelize = req.sequelize
const [article, articleTopIssues, loggedInUser] = await Promise.all([

const [article, articlesInSamePage, articleTopIssues, loggedInUser] = await Promise.all([
sequelize.models.Article.getArticle({
includeIssues,
limit: 5,
sequelize,
slug: slug.join('/'),
slug: slugString,
}),
// TODO benchmark the effect of this monstrous query on article pages.
// If very slow, we could move it to after page load.
// TODO don't run this on split pages? But it requires doing a separate query step, which
// would possibly slow things down more than this actual query?
sequelize.models.Article.getArticlesInSamePage({
sequelize,
slug: slugString,
}),
sequelize.models.Article.getArticle({
includeIssues,
includeIssuesOrder: 'score',
limit: 5,
sequelize,
slug: slug.join('/'),
slug: slugString,
}),
getLoggedInUser(req, res, loggedInUserCache),
])
Expand All @@ -36,15 +48,17 @@ export const getServerSidePropsArticleHoc = ({
notFound: true
}
}
const [articleJson, issuesCount, topicArticleCount] = await Promise.all([
const [articleJson, articlesInSamePageJson, issuesCount, topicArticleCount] = await Promise.all([
article.toJson(loggedInUser),
Promise.all(articlesInSamePage.map(article => article.toJson(loggedInUser))),
includeIssues ? sequelize.models.Issue.count({ where: { articleId: article.id } }) : null,
sequelize.models.Article.count({
where: { topicId: article.topicId },
}),
])
const props: ArticlePageProps = {
article: articleJson,
articlesInSamePage: articlesInSamePageJson,
topicArticleCount,
}
if (loggedInUser) {
Expand Down
4 changes: 3 additions & 1 deletion web/back/IssuePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ export const getServerSidePropsIssueHoc = (): MyGetServerSideProps => {
getLoggedInUser(req, res),
])
if (!issue) { return { notFound: true } }
const [articleJson, comments, commentsCount, issueJson, loggedInUserJson] = await Promise.all([
const [articleJson, comments, commentsCount, issueJson, issuesCount, loggedInUserJson] = await Promise.all([
issue.issues.toJson(loggedInUser),
Promise.all(issue.comments.map(comment => comment.toJson(loggedInUser))),
sequelize.models.Comment.count({ where: { issueId: issue.id } }),
issue.toJson(loggedInUser),
sequelize.models.Issue.count({ where: { articleId: issue.articleId } }),
loggedInUser ? loggedInUser.toJson() : undefined,
])
const props: ArticlePageProps = {
article: issueJson,
comments: comments as CommentType[],
commentsCount,
issueArticle: articleJson,
issuesCount,
}
if (loggedInUser) {
props.loggedInUser = loggedInUserJson
Expand Down
5 changes: 3 additions & 2 deletions web/back/UserPage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ourbigbook from 'ourbigbook/dist/ourbigbook'
import ourbigbook from 'ourbigbook'

import { getLoggedInUser } from 'back'
import { getServerSidePropsArticleHoc } from 'back/ArticlePage'
Expand Down Expand Up @@ -96,7 +96,8 @@ export const getServerSidePropsUserHoc = (what): MyGetServerSideProps => {
} else {
const articleContext = Object.assign({}, context, { params: { slug: [ uid ] } })
const articleProps = await (getServerSidePropsArticleHoc({
includeIssues: true, loggedInUserCache: loggedInUser })(articleContext))
includeIssues: true, loggedInUserCache: loggedInUser
})(articleContext))
if ('props' in articleProps) {
Object.assign(props, articleProps.props)
}
Expand Down
1 change: 1 addition & 0 deletions web/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ async function convert({
ref_prefix: `${ourbigbook.AT_MENTION_CHAR}${author.username}`,
render,
split_headers: splitHeaders === undefined ? true : splitHeaders,
web: true,
}, convertOptions),
extra_returns,
)
Expand Down

0 comments on commit 407dd14

Please sign in to comment.