Merge branch 'nuke-scss' of git.handmade.network:hmn/hmn into nuke-scss
This commit is contained in:
commit
410c94bb51
|
@ -375,7 +375,7 @@ function editTimelineSnippet(timelineItemEl, stickyProjectId) {
|
||||||
let ownerAvatar = timelineItemEl.querySelector(".avatar")?.src;
|
let ownerAvatar = timelineItemEl.querySelector(".avatar")?.src;
|
||||||
let creationDate = new Date(timelineItemEl.querySelector("time").dateTime);
|
let creationDate = new Date(timelineItemEl.querySelector("time").dateTime);
|
||||||
let rawDesc = timelineItemEl.querySelector(".rawdesc").textContent;
|
let rawDesc = timelineItemEl.querySelector(".rawdesc").textContent;
|
||||||
let attachment = timelineItemEl.querySelector(".timeline-content-box")?.children?.[0];
|
let attachment = timelineItemEl.querySelector(".timeline-media")?.children?.[0];
|
||||||
let projectIds = [];
|
let projectIds = [];
|
||||||
let projectEls = timelineItemEl.querySelectorAll(".projects > a");
|
let projectEls = timelineItemEl.querySelectorAll(".projects > a");
|
||||||
for (let i = 0; i < projectEls.length; ++i) {
|
for (let i = 0; i < projectEls.length; ++i) {
|
||||||
|
|
|
@ -1,106 +1,24 @@
|
||||||
function TabState(tabbed) {
|
function initTabs(container, initialTab = null) {
|
||||||
this.container = tabbed;
|
const buttons = Array.from(container.querySelectorAll("[data-tab-button]"));
|
||||||
this.tabs = tabbed.querySelector(".tab");
|
const tabs = Array.from(container.querySelectorAll("[data-tab]"));
|
||||||
|
|
||||||
this.tabbar = document.createElement("div");
|
if (!initialTab) {
|
||||||
this.tabbar.classList.add("tab-bar");
|
initialTab = tabs[0].getAttribute("data-tab");
|
||||||
this.container.insertBefore(this.tabbar, this.container.firstChild);
|
|
||||||
|
|
||||||
this.current_i = -1;
|
|
||||||
this.tab_buttons = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function switch_tab_old(state, tab_i) {
|
|
||||||
return function() {
|
|
||||||
if (state.current_i >= 0) {
|
|
||||||
state.tabs[state.current_i].classList.add("hidden");
|
|
||||||
state.tab_buttons[state.current_i].classList.remove("current");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.tabs[tab_i].classList.remove("hidden");
|
function switchTo(name) {
|
||||||
state.tab_buttons[tab_i].classList.add("current");
|
|
||||||
|
|
||||||
var hash = "";
|
|
||||||
if (state.tabs[tab_i].hasAttribute("data-url-hash")) {
|
|
||||||
hash = state.tabs[tab_i].getAttribute("data-url-hash");
|
|
||||||
}
|
|
||||||
window.location.hash = hash;
|
|
||||||
|
|
||||||
state.current_i = tab_i;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
const tabContainers = document.getElementsByClassName("tabbed");
|
|
||||||
for (const container of tabContainers) {
|
|
||||||
const tabBar = document.createElement("div");
|
|
||||||
tabBar.classList.add("tab-bar");
|
|
||||||
container.insertAdjacentElement('afterbegin', tabBar);
|
|
||||||
|
|
||||||
const tabs = container.querySelectorAll(".tab");
|
|
||||||
for (let i = 0; i < tabs.length; i++) {
|
|
||||||
const tab = tabs[i];
|
|
||||||
tab.classList.toggle('dn', i > 0);
|
|
||||||
|
|
||||||
const slug = tab.getAttribute("data-slug");
|
|
||||||
|
|
||||||
// TODO: Should this element be a link?
|
|
||||||
const tabButton = document.createElement("div");
|
|
||||||
tabButton.classList.add("tab-button");
|
|
||||||
tabButton.classList.toggle("current", i === 0);
|
|
||||||
tabButton.innerText = tab.getAttribute("data-name");
|
|
||||||
tabButton.setAttribute("data-slug", slug);
|
|
||||||
|
|
||||||
tabButton.addEventListener("click", () => {
|
|
||||||
switchTab(container, slug);
|
|
||||||
});
|
|
||||||
|
|
||||||
tabBar.appendChild(tabButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialSlug = window.location.hash;
|
|
||||||
if (initialSlug) {
|
|
||||||
switchTab(container, initialSlug.substring(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function switchTab(container, slug) {
|
|
||||||
const tabs = container.querySelectorAll('.tab');
|
|
||||||
|
|
||||||
let didMatch = false;
|
|
||||||
for (const tab of tabs) {
|
for (const tab of tabs) {
|
||||||
const slugMatches = tab.getAttribute("data-slug") === slug;
|
tab.hidden = tab.getAttribute("data-tab") !== name;
|
||||||
tab.classList.toggle('dn', !slugMatches);
|
}
|
||||||
|
for (const button of buttons) {
|
||||||
if (slugMatches) {
|
button.classList.toggle("tab-button-active", button.getAttribute("data-tab-button") === name);
|
||||||
didMatch = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switchTo(initialTab);
|
||||||
|
|
||||||
const tabButtons = document.querySelectorAll(".tab-button");
|
for (const button of buttons) {
|
||||||
for (const tabButton of tabButtons) {
|
button.addEventListener("click", () => {
|
||||||
const buttonSlug = tabButton.getAttribute("data-slug");
|
switchTo(button.getAttribute("data-tab-button"));
|
||||||
tabButton.classList.toggle('current', slug === buttonSlug);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (!didMatch) {
|
|
||||||
// switch to first tab as a fallback
|
|
||||||
tabs[0].classList.remove('dn');
|
|
||||||
tabButtons[0].classList.add('current');
|
|
||||||
}
|
|
||||||
|
|
||||||
window.location.hash = slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchToTabOfElement(container, el) {
|
|
||||||
const tabs = Array.from(container.querySelectorAll('.tab'));
|
|
||||||
let target = el.parentElement;
|
|
||||||
while (target) {
|
|
||||||
if (tabs.includes(target)) {
|
|
||||||
switchTab(container, target.getAttribute("data-slug"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
target = target.parentElement;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
102
public/style.css
102
public/style.css
|
@ -7159,9 +7159,6 @@ code {
|
||||||
--color: black;
|
--color: black;
|
||||||
--link-color: #d12991;
|
--link-color: #d12991;
|
||||||
--red: #c61d24;
|
--red: #c61d24;
|
||||||
--dim-color: #333;
|
|
||||||
--dimmer-color: #999;
|
|
||||||
--dimmest-color: #bbb;
|
|
||||||
--theme-color: #b1b1b1;
|
--theme-color: #b1b1b1;
|
||||||
--theme-color-dim: #c0c0c0;
|
--theme-color-dim: #c0c0c0;
|
||||||
--theme-color-dimmer: #dddddd;
|
--theme-color-dimmer: #dddddd;
|
||||||
|
@ -7173,6 +7170,7 @@ code {
|
||||||
--card-background: #ebebeb;
|
--card-background: #ebebeb;
|
||||||
--card-background-hover: #f1f1f1;
|
--card-background-hover: #f1f1f1;
|
||||||
--card-background-transparent: #ebebeb00;
|
--card-background-transparent: #ebebeb00;
|
||||||
|
--timeline-media-background: #b4b4b466;
|
||||||
--bg-1: #f8f8f8;
|
--bg-1: #f8f8f8;
|
||||||
--bg-2: #e8e8e8;
|
--bg-2: #e8e8e8;
|
||||||
--bg-3: #d8d8d8;
|
--bg-3: #d8d8d8;
|
||||||
|
@ -7200,9 +7198,6 @@ code {
|
||||||
--color: #eee;
|
--color: #eee;
|
||||||
--link-color: #ff5dc2;
|
--link-color: #ff5dc2;
|
||||||
--color-error: #ff6666;
|
--color-error: #ff6666;
|
||||||
--dim-color: #bbb;
|
|
||||||
--dimmer-color: #999;
|
|
||||||
--dimmest-color: #777;
|
|
||||||
--theme-color: #666;
|
--theme-color: #666;
|
||||||
--theme-color-dim: #444;
|
--theme-color-dim: #444;
|
||||||
--theme-color-dimmer: #383838;
|
--theme-color-dimmer: #383838;
|
||||||
|
@ -7214,6 +7209,7 @@ code {
|
||||||
--card-background: #494949;
|
--card-background: #494949;
|
||||||
--card-background-hover: #333;
|
--card-background-hover: #333;
|
||||||
--card-background-transparent: #24242400;
|
--card-background-transparent: #24242400;
|
||||||
|
--timeline-media-background: #24242466;
|
||||||
--bg-1: #1f1f1f;
|
--bg-1: #1f1f1f;
|
||||||
--bg-2: #2f2f2f;
|
--bg-2: #2f2f2f;
|
||||||
--bg-3: #494949;
|
--bg-3: #494949;
|
||||||
|
@ -7323,27 +7319,6 @@ pre,
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.b--dim {
|
|
||||||
border-color: var(--dim-color);
|
|
||||||
}
|
|
||||||
.b--dimmer {
|
|
||||||
border-color: var(--dimmer-color);
|
|
||||||
}
|
|
||||||
.b--dimmest {
|
|
||||||
border-color: var(--dimmest-color);
|
|
||||||
}
|
|
||||||
.b--theme {
|
|
||||||
border-color: var(--theme-color);
|
|
||||||
}
|
|
||||||
.b--theme-dim {
|
|
||||||
border-color: var(--theme-color-dim);
|
|
||||||
}
|
|
||||||
.b--theme-dimmer {
|
|
||||||
border-color: var(--theme-color-dimmer);
|
|
||||||
}
|
|
||||||
.b--theme-dimmest {
|
|
||||||
border-color: var(--theme-color-dimmest);
|
|
||||||
}
|
|
||||||
.b--theme-dark {
|
.b--theme-dark {
|
||||||
border-color: var(--theme-color-dark);
|
border-color: var(--theme-color-dark);
|
||||||
}
|
}
|
||||||
|
@ -7393,24 +7368,6 @@ pre,
|
||||||
.c--inherit:active {
|
.c--inherit:active {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
.c--dim {
|
|
||||||
color: var(--dim-color);
|
|
||||||
}
|
|
||||||
.c--theme-dim {
|
|
||||||
color: var(--theme-color-dim);
|
|
||||||
}
|
|
||||||
.c--dimmer {
|
|
||||||
color: var(--dimmer-color);
|
|
||||||
}
|
|
||||||
.c--theme-dimmer {
|
|
||||||
color: var(--theme-color-dimmer);
|
|
||||||
}
|
|
||||||
.c--dimmest {
|
|
||||||
color: var(--dimmest-color);
|
|
||||||
}
|
|
||||||
.c--theme-dimmest {
|
|
||||||
color: var(--theme-color-dimmest);
|
|
||||||
}
|
|
||||||
.f8 {
|
.f8 {
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
}
|
}
|
||||||
|
@ -7809,7 +7766,7 @@ pre,
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
border-width: 0 0 1px;
|
border-width: 0 0 1px;
|
||||||
border-color: var(--dimmest-color);
|
border-color: var(--bg-3);
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 35em) {
|
@media screen and (min-width: 35em) {
|
||||||
.optionbar {
|
.optionbar {
|
||||||
|
@ -7885,7 +7842,7 @@ pre,
|
||||||
transition: all 100ms ease-in-out;
|
transition: all 100ms ease-in-out;
|
||||||
}
|
}
|
||||||
.carousel-container .carousel-button:hover {
|
.carousel-container .carousel-button:hover {
|
||||||
background-color: var(--dimmest-color);
|
background-color: var(--bg-3);
|
||||||
}
|
}
|
||||||
.carousel-container .carousel-button.active {
|
.carousel-container .carousel-button.active {
|
||||||
border-color: var(--theme-color);
|
border-color: var(--theme-color);
|
||||||
|
@ -7967,10 +7924,10 @@ pre,
|
||||||
.post-content th,
|
.post-content th,
|
||||||
.post-content td {
|
.post-content td {
|
||||||
padding: var(--spacing-extra-small) var(--spacing-small);
|
padding: var(--spacing-extra-small) var(--spacing-small);
|
||||||
border: 1px solid var(--dimmest-color);
|
border: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background-color: var(--dim-background);
|
background-color: var(--bg-3);
|
||||||
padding: .2em 0;
|
padding: .2em 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
@ -7982,12 +7939,12 @@ pre,
|
||||||
}
|
}
|
||||||
.post-content pre > code,
|
.post-content pre > code,
|
||||||
.post-content pre.hmn-code {
|
.post-content pre.hmn-code {
|
||||||
background-color: var(--dim-background);
|
background-color: var(--bg-3);
|
||||||
padding: 0.7em;
|
padding: 0.7em;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
.post-content blockquote {
|
.post-content blockquote {
|
||||||
border-color: var(--dimmest-color);
|
border-color: var(--bg-3);
|
||||||
margin-left: var(--spacing-small);
|
margin-left: var(--spacing-small);
|
||||||
padding-left: var(--spacing-small);
|
padding-left: var(--spacing-small);
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
@ -8130,7 +8087,7 @@ pre,
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
border-width: 0 0 1px 1px;
|
border-width: 0 0 1px 1px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: var(--dimmest-color);
|
border-color: var(--bg-3);
|
||||||
left: -1.5rem;
|
left: -1.5rem;
|
||||||
top: calc(1rem - var(--height));
|
top: calc(1rem - var(--height));
|
||||||
border-bottom-left-radius: 0.5rem;
|
border-bottom-left-radius: 0.5rem;
|
||||||
|
@ -8471,7 +8428,7 @@ header.old .submenu > a {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header {
|
header {
|
||||||
background-color: var(--bg-3);
|
background-color: var(--bg-2);
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
}
|
}
|
||||||
|
@ -8501,7 +8458,7 @@ header .header-nav .submenu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
min-width: 8rem;
|
min-width: 8rem;
|
||||||
background-color: var(--card-background);
|
background-color: var(--bg-2);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-top-width: 0;
|
border-top-width: 0;
|
||||||
|
@ -8887,11 +8844,20 @@ code .ss,
|
||||||
color: #a31515;
|
color: #a31515;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* src/rawdata/scss/tabs.css */
|
||||||
|
.tab-button {
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
.tab-button-active {
|
||||||
|
border-color: var(--link-color);
|
||||||
|
}
|
||||||
|
|
||||||
/* src/rawdata/scss/timeline.css */
|
/* src/rawdata/scss/timeline.css */
|
||||||
.avatar {
|
.avatar {
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: var(--dimmest-color);
|
background-color: var(--bg-3);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border: none;
|
border: none;
|
||||||
width: var(--avatar-size-normal);
|
width: var(--avatar-size-normal);
|
||||||
|
@ -8909,16 +8875,28 @@ code .ss,
|
||||||
--fade-color: var(--card-background);
|
--fade-color: var(--card-background);
|
||||||
color: var(--main-color);
|
color: var(--main-color);
|
||||||
}
|
}
|
||||||
.timeline-item .timeline-content-box.timeline-item-bg {
|
.timeline-item .timeline-media {
|
||||||
background-color: var(--timeline-content-background);
|
background-color: var(--timeline-media-background);
|
||||||
|
max-height: 60vh;
|
||||||
}
|
}
|
||||||
.timeline-item .timeline-content-box > * {
|
.timeline-item .timeline-media.timeline-embed {
|
||||||
|
height: 0;
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 56.25%;
|
||||||
|
}
|
||||||
|
.timeline-item .timeline-media.timeline-embed > iframe {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
.timeline-item .timeline-media > * {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 80vh;
|
|
||||||
}
|
|
||||||
.timeline-item .avatar {
|
|
||||||
width: 2.5rem;
|
|
||||||
}
|
}
|
||||||
.timeline-modal .container {
|
.timeline-modal .container {
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
|
|
|
@ -1,309 +0,0 @@
|
||||||
/*
|
|
||||||
Inserts a CSS expression with one or more custom variables.
|
|
||||||
You can provide an arbitrary number of strings in the second
|
|
||||||
argument, separated by spaces. Any strings corresponding to
|
|
||||||
variable names will be replaced by the correct values, while
|
|
||||||
other strings are left untouched.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
@include usevar(border-color, dimmer-color);
|
|
||||||
@include usevar(background, "linear-gradient(" dim-background-transparent "," dim-background ")");
|
|
||||||
|
|
||||||
For clarity and to avoid syntax issues, you are encouraged to
|
|
||||||
use unquoted strings for variables and quoted strings for
|
|
||||||
everything else.
|
|
||||||
|
|
||||||
For convenience in common cases, if only a single argument
|
|
||||||
is provided and it does not match an existing variable, this
|
|
||||||
will throw an error.
|
|
||||||
*/
|
|
||||||
pre, code, .codeblock {
|
|
||||||
/* Comment */
|
|
||||||
/* Error */
|
|
||||||
/* Keyword */
|
|
||||||
/* Literal */
|
|
||||||
/* Name */
|
|
||||||
/* Operator */
|
|
||||||
/* Punctuation */
|
|
||||||
/* Comment.Multiline */
|
|
||||||
/* Comment.Preproc */
|
|
||||||
/* Comment.Single */
|
|
||||||
/* Comment.Special */
|
|
||||||
/* Generic.Emph */
|
|
||||||
/* Generic.Strong */
|
|
||||||
/* Keyword.Constant */
|
|
||||||
/* Keyword.Declaration */
|
|
||||||
/* Keyword.Namespace */
|
|
||||||
/* Keyword.Pseudo */
|
|
||||||
/* Keyword.Reserved */
|
|
||||||
/* Keyword.Type */
|
|
||||||
/* Literal.Date */
|
|
||||||
/* Literal.Number */
|
|
||||||
/* Literal.String */
|
|
||||||
/* Name.Attribute */
|
|
||||||
/* Name.Builtin */
|
|
||||||
/* Name.Class */
|
|
||||||
/* Name.Constant */
|
|
||||||
/* Name.Decorator */
|
|
||||||
/* Name.Entity */
|
|
||||||
/* Name.Exception */
|
|
||||||
/* Name.Function */
|
|
||||||
/* Name.Label */
|
|
||||||
/* Name.Namespace */
|
|
||||||
/* Name.Other */
|
|
||||||
/* Name.Property */
|
|
||||||
/* Name.Tag */
|
|
||||||
/* Name.Variable */
|
|
||||||
/* Operator.Word */
|
|
||||||
/* Text.Whitespace */
|
|
||||||
/* Literal.Number.Float */
|
|
||||||
/* Literal.Number.Hex */
|
|
||||||
/* Literal.Number.Integer */
|
|
||||||
/* Literal.Number.Oct */
|
|
||||||
/* Literal.String.Backtick */
|
|
||||||
/* Literal.String.Char */
|
|
||||||
/* Literal.String.Doc */
|
|
||||||
/* Literal.String.Double */
|
|
||||||
/* Literal.String.Escape */
|
|
||||||
/* Literal.String.Heredoc */
|
|
||||||
/* Literal.String.Interpol */
|
|
||||||
/* Literal.String.Other */
|
|
||||||
/* Literal.String.Regex */
|
|
||||||
/* Literal.String.Single */
|
|
||||||
/* Literal.String.Symbol */
|
|
||||||
/* Name.Builtin.Pseudo */
|
|
||||||
/* Name.Variable.Class */
|
|
||||||
/* Name.Variable.Global */
|
|
||||||
/* Name.Variable.Instance */
|
|
||||||
/* Literal.Number.Integer.Long */
|
|
||||||
/* Generic Heading & Diff Header */
|
|
||||||
/* Generic.Subheading & Diff Unified/Comment? */
|
|
||||||
/* Generic.Deleted & Diff Deleted */
|
|
||||||
/* Generic.Inserted & Diff Inserted */ }
|
|
||||||
pre .hll, code .hll, .codeblock .hll {
|
|
||||||
background-color: #49483e; }
|
|
||||||
pre .c, code .c, .codeblock .c {
|
|
||||||
color: #75715e; }
|
|
||||||
pre .err, code .err, .codeblock .err {
|
|
||||||
color: #ff0000; }
|
|
||||||
pre .k, code .k, .codeblock .k {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .l, code .l, .codeblock .l {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .n, code .n, .codeblock .n {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .o, code .o, .codeblock .o {
|
|
||||||
color: #f92672; }
|
|
||||||
pre .p, code .p, .codeblock .p {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .cm, code .cm, .codeblock .cm {
|
|
||||||
color: #75715e; }
|
|
||||||
pre .cp, code .cp, .codeblock .cp {
|
|
||||||
color: #75715e; }
|
|
||||||
pre .c1, code .c1, .codeblock .c1 {
|
|
||||||
color: #75715e; }
|
|
||||||
pre .cs, code .cs, .codeblock .cs {
|
|
||||||
color: #75715e; }
|
|
||||||
pre .ge, code .ge, .codeblock .ge {
|
|
||||||
font-style: italic; }
|
|
||||||
pre .gs, code .gs, .codeblock .gs {
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .kc, code .kc, .codeblock .kc {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .kd, code .kd, .codeblock .kd {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .kn, code .kn, .codeblock .kn {
|
|
||||||
color: #f92672; }
|
|
||||||
pre .kp, code .kp, .codeblock .kp {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .kr, code .kr, .codeblock .kr {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .kt, code .kt, .codeblock .kt {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .ld, code .ld, .codeblock .ld {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .m, code .m, .codeblock .m {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .s, code .s, .codeblock .s {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .na, code .na, .codeblock .na {
|
|
||||||
color: #a6e22e; }
|
|
||||||
pre .nb, code .nb, .codeblock .nb {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .nc, code .nc, .codeblock .nc {
|
|
||||||
color: #a6e22e; }
|
|
||||||
pre .no, code .no, .codeblock .no {
|
|
||||||
color: #66d9ef; }
|
|
||||||
pre .nd, code .nd, .codeblock .nd {
|
|
||||||
color: #a6e22e; }
|
|
||||||
pre .ni, code .ni, .codeblock .ni {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .ne, code .ne, .codeblock .ne {
|
|
||||||
color: #a6e22e; }
|
|
||||||
pre .nf, code .nf, .codeblock .nf {
|
|
||||||
color: #a6e22e; }
|
|
||||||
pre .nl, code .nl, .codeblock .nl {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .nn, code .nn, .codeblock .nn {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .nx, code .nx, .codeblock .nx {
|
|
||||||
color: #a6e22e; }
|
|
||||||
pre .py, code .py, .codeblock .py {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .nt, code .nt, .codeblock .nt {
|
|
||||||
color: #f92672; }
|
|
||||||
pre .nv, code .nv, .codeblock .nv {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .ow, code .ow, .codeblock .ow {
|
|
||||||
color: #f92672; }
|
|
||||||
pre .w, code .w, .codeblock .w {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .mf, code .mf, .codeblock .mf {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .mh, code .mh, .codeblock .mh {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .mi, code .mi, .codeblock .mi {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .mo, code .mo, .codeblock .mo {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .sb, code .sb, .codeblock .sb {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .sc, code .sc, .codeblock .sc {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .sd, code .sd, .codeblock .sd {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .s2, code .s2, .codeblock .s2 {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .se, code .se, .codeblock .se {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .sh, code .sh, .codeblock .sh {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .si, code .si, .codeblock .si {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .sx, code .sx, .codeblock .sx {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .sr, code .sr, .codeblock .sr {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .s1, code .s1, .codeblock .s1 {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .ss, code .ss, .codeblock .ss {
|
|
||||||
color: #e6db74; }
|
|
||||||
pre .bp, code .bp, .codeblock .bp {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .vc, code .vc, .codeblock .vc {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .vg, code .vg, .codeblock .vg {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .vi, code .vi, .codeblock .vi {
|
|
||||||
color: #f8f8f2; }
|
|
||||||
pre .il, code .il, .codeblock .il {
|
|
||||||
color: #ae81ff; }
|
|
||||||
pre .gu, code .gu, .codeblock .gu {
|
|
||||||
color: #75715e; }
|
|
||||||
pre .gd, code .gd, .codeblock .gd {
|
|
||||||
color: #f92672; }
|
|
||||||
pre .gi, code .gi, .codeblock .gi {
|
|
||||||
color: #a6e22e; }
|
|
||||||
|
|
||||||
.light {
|
|
||||||
background-color: #fff;
|
|
||||||
color: #000; }
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--fg-font-color: #eee;
|
|
||||||
--theme-color: #666;
|
|
||||||
--theme-color-dim: #444;
|
|
||||||
--theme-color-dimmer: #383838;
|
|
||||||
--theme-color-dimmest: #333;
|
|
||||||
--theme-color-dark: #666;
|
|
||||||
--theme-color-light: #666;
|
|
||||||
--link-color: #aaa;
|
|
||||||
--link-border-color: #aaa;
|
|
||||||
--hr-color: #aaa;
|
|
||||||
--main-background-color: #202020;
|
|
||||||
--main-color: #eee;
|
|
||||||
--dim-color: #bbb;
|
|
||||||
--dimmer-color: #999;
|
|
||||||
--dimmest-color: #777;
|
|
||||||
--menu-bottom-border-color: #444;
|
|
||||||
--login-popup-background: #181818;
|
|
||||||
--content-background: #202020;
|
|
||||||
--content-background-transparent: rgba(32, 32, 32, 0);
|
|
||||||
--dim-background: #252525;
|
|
||||||
--dim-background-transparent: rgba(37, 37, 37, 0);
|
|
||||||
--text-background: #181818;
|
|
||||||
--spoiler-border: #777;
|
|
||||||
--background-even-background: #242424;
|
|
||||||
--project-card-border-color: #333;
|
|
||||||
--project-user-suggestions-background: #222;
|
|
||||||
--project-user-suggestions-border-color: #444;
|
|
||||||
--notice-text-color: #eee;
|
|
||||||
--notice-unapproved-color: #7a2020;
|
|
||||||
--notice-hidden-color: #494949;
|
|
||||||
--notice-hiatus-color: #876327;
|
|
||||||
--notice-dead-color: #7a2020;
|
|
||||||
--notice-lts-color: #2a681d;
|
|
||||||
--notice-lts-reqd-color: #876327;
|
|
||||||
--notice-success-color: #2a681d;
|
|
||||||
--notice-warn-color: #876327;
|
|
||||||
--notice-failure-color: #7a2020;
|
|
||||||
--optionbar-border-color: #333;
|
|
||||||
--tab-background: #181818;
|
|
||||||
--tab-border-color: #3f3f3f;
|
|
||||||
--tab-button-background: #303030;
|
|
||||||
--tab-button-background-hover: #383838;
|
|
||||||
--tab-button-background-current: #181818;
|
|
||||||
--form-check-background: #252527;
|
|
||||||
--form-check-border-color: #666;
|
|
||||||
--form-check-border-color-hover: #084068;
|
|
||||||
--form-text-background: #181818;
|
|
||||||
--form-text-background-active: #252527;
|
|
||||||
--form-text-border-color: #444;
|
|
||||||
--form-text-border-color-active: #084068;
|
|
||||||
--form-button-color: #999;
|
|
||||||
--form-button-color-active: #4c9ed9;
|
|
||||||
--form-button-background: #383838;
|
|
||||||
--form-button-background-active: #303840;
|
|
||||||
--form-button-border-color: transparent;
|
|
||||||
--form-button-inline-border-color: transparent;
|
|
||||||
--form-error-color: #c61d24;
|
|
||||||
--landing-search-background: #282828;
|
|
||||||
--landing-search-background-hover: #181818;
|
|
||||||
--editor-toolbar-background: #282828;
|
|
||||||
--editor-toolbar-border-color: #333;
|
|
||||||
--editor-toolbar-button-background: #282828;
|
|
||||||
--editor-toolbar-button-background-hover: #333;
|
|
||||||
--editor-toolbar-button-border-color: #333;
|
|
||||||
--post-blockquote-border-color: #555;
|
|
||||||
--forum-even-background: #242424;
|
|
||||||
--forum-thread-read-color: #777;
|
|
||||||
--forum-thread-read-link-color: #999;
|
|
||||||
--forum-post-author-color: #999;
|
|
||||||
--forum-diff-source-background: #181818;
|
|
||||||
--forum-diff-source-border-color: #444;
|
|
||||||
--forum-diff-replace-background: #18283a;
|
|
||||||
--forum-diff-replace-border-color: #223d5b;
|
|
||||||
--forum-diff-delete-background: #3a1818;
|
|
||||||
--forum-diff-delete-border-color: #6b1e1c;
|
|
||||||
--forum-diff-insert-background: #233a18;
|
|
||||||
--forum-diff-insert-border-color: #30591b;
|
|
||||||
--card-background: #282828;
|
|
||||||
--card-background-hover: #333;
|
|
||||||
--timeline-content-background: rgba(255, 255, 255, 0.06);
|
|
||||||
--irc-border-color: #333;
|
|
||||||
--irc-tab-current-shadow: 0px 0px 5px #000 inset;
|
|
||||||
--irc-tab-close-button-color: #bbb;
|
|
||||||
--irc-tab-close-button-background: #444;
|
|
||||||
--irc-nick-border-color: #444;
|
|
||||||
--irc-users-color: #aaa;
|
|
||||||
--irc-users-background: #181818;
|
|
||||||
--irc-users-border-color: transparent;
|
|
||||||
--irc-users-popout-background: #181818;
|
|
||||||
--irc-users-popout-border-color-left: #444;
|
|
||||||
--irc-users-popout-border-color-right: #333;
|
|
||||||
--code-line-number-color: #444;
|
|
||||||
--library-star-btn-background: #252525;
|
|
||||||
--library-star-btn-border-color: #bbb;
|
|
||||||
--library-star-btn-a-border-color: #999;
|
|
||||||
--library-star-btn-a-hover-background: #333; }
|
|
|
@ -1,327 +0,0 @@
|
||||||
/*
|
|
||||||
Inserts a CSS expression with one or more custom variables.
|
|
||||||
You can provide an arbitrary number of strings in the second
|
|
||||||
argument, separated by spaces. Any strings corresponding to
|
|
||||||
variable names will be replaced by the correct values, while
|
|
||||||
other strings are left untouched.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
@include usevar(border-color, dimmer-color);
|
|
||||||
@include usevar(background, "linear-gradient(" dim-background-transparent "," dim-background ")");
|
|
||||||
|
|
||||||
For clarity and to avoid syntax issues, you are encouraged to
|
|
||||||
use unquoted strings for variables and quoted strings for
|
|
||||||
everything else.
|
|
||||||
|
|
||||||
For convenience in common cases, if only a single argument
|
|
||||||
is provided and it does not match an existing variable, this
|
|
||||||
will throw an error.
|
|
||||||
*/
|
|
||||||
pre, code, .codeblock {
|
|
||||||
/* Comment */
|
|
||||||
/* Error */
|
|
||||||
/* Keyword */
|
|
||||||
/* Operator */
|
|
||||||
/* Comment.Multiline */
|
|
||||||
/* Comment.Preproc */
|
|
||||||
/* Comment.Single */
|
|
||||||
/* Comment.Special */
|
|
||||||
/* Generic.Deleted */
|
|
||||||
/* Generic.Emph */
|
|
||||||
/* Generic.Error */
|
|
||||||
/* Generic.Heading */
|
|
||||||
/* Generic.Inserted */
|
|
||||||
/* Generic.Output */
|
|
||||||
/* Generic.Prompt */
|
|
||||||
/* Generic.Strong */
|
|
||||||
/* Generic.Subheading */
|
|
||||||
/* Generic.Traceback */
|
|
||||||
/* Keyword.Constant */
|
|
||||||
/* Keyword.Declaration */
|
|
||||||
/* Keyword.Namespace */
|
|
||||||
/* Keyword.Pseudo */
|
|
||||||
/* Keyword.Reserved */
|
|
||||||
/* Keyword.Type */
|
|
||||||
/* Literal.Number */
|
|
||||||
/* Literal.String */
|
|
||||||
/* Name.Attribute */
|
|
||||||
/* Name.Builtin */
|
|
||||||
/* Name.Class */
|
|
||||||
/* Name.Constant */
|
|
||||||
/* Name.Decorator */
|
|
||||||
/* Name.Entity */
|
|
||||||
/* Name.Exception */
|
|
||||||
/* Name.Function */
|
|
||||||
/* Name.Label */
|
|
||||||
/* Name.Namespace */
|
|
||||||
/* Name.Tag */
|
|
||||||
/* Name.Variable */
|
|
||||||
/* Operator.Word */
|
|
||||||
/* Text.Whitespace */
|
|
||||||
/* Literal.Number.Float */
|
|
||||||
/* Literal.Number.Hex */
|
|
||||||
/* Literal.Number.Integer */
|
|
||||||
/* Literal.Number.Oct */
|
|
||||||
/* Literal.String.Backtick */
|
|
||||||
/* Literal.String.Char */
|
|
||||||
/* Literal.String.Doc */
|
|
||||||
/* Literal.String.Double */
|
|
||||||
/* Literal.String.Escape */
|
|
||||||
/* Literal.String.Heredoc */
|
|
||||||
/* Literal.String.Interpol */
|
|
||||||
/* Literal.String.Other */
|
|
||||||
/* Literal.String.Regex */
|
|
||||||
/* Literal.String.Single */
|
|
||||||
/* Literal.String.Symbol */
|
|
||||||
/* Name.Builtin.Pseudo */
|
|
||||||
/* Name.Variable.Class */
|
|
||||||
/* Name.Variable.Global */
|
|
||||||
/* Name.Variable.Instance */
|
|
||||||
/* Literal.Number.Integer.Long */ }
|
|
||||||
pre .hll, code .hll, .codeblock .hll {
|
|
||||||
background-color: #ffffcc; }
|
|
||||||
pre .c, code .c, .codeblock .c {
|
|
||||||
color: #60a0b0;
|
|
||||||
font-style: italic; }
|
|
||||||
pre .err, code .err, .codeblock .err {
|
|
||||||
color: #FF0000; }
|
|
||||||
pre .k, code .k, .codeblock .k {
|
|
||||||
color: #007020;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .o, code .o, .codeblock .o {
|
|
||||||
color: #666666; }
|
|
||||||
pre .cm, code .cm, .codeblock .cm {
|
|
||||||
color: #60a0b0;
|
|
||||||
font-style: italic; }
|
|
||||||
pre .cp, code .cp, .codeblock .cp {
|
|
||||||
color: #007020; }
|
|
||||||
pre .c1, code .c1, .codeblock .c1 {
|
|
||||||
color: #60a0b0;
|
|
||||||
font-style: italic; }
|
|
||||||
pre .cs, code .cs, .codeblock .cs {
|
|
||||||
color: #60a0b0;
|
|
||||||
background-color: #fff0f0; }
|
|
||||||
pre .gd, code .gd, .codeblock .gd {
|
|
||||||
color: #A00000; }
|
|
||||||
pre .ge, code .ge, .codeblock .ge {
|
|
||||||
font-style: italic; }
|
|
||||||
pre .gr, code .gr, .codeblock .gr {
|
|
||||||
color: #FF0000; }
|
|
||||||
pre .gh, code .gh, .codeblock .gh {
|
|
||||||
color: #000080;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .gi, code .gi, .codeblock .gi {
|
|
||||||
color: #00A000; }
|
|
||||||
pre .go, code .go, .codeblock .go {
|
|
||||||
color: #808080; }
|
|
||||||
pre .gp, code .gp, .codeblock .gp {
|
|
||||||
color: #c65d09;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .gs, code .gs, .codeblock .gs {
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .gu, code .gu, .codeblock .gu {
|
|
||||||
color: #800080;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .gt, code .gt, .codeblock .gt {
|
|
||||||
color: #0040D0; }
|
|
||||||
pre .kc, code .kc, .codeblock .kc {
|
|
||||||
color: #007020;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .kd, code .kd, .codeblock .kd {
|
|
||||||
color: #007020;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .kn, code .kn, .codeblock .kn {
|
|
||||||
color: #007020;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .kp, code .kp, .codeblock .kp {
|
|
||||||
color: #007020; }
|
|
||||||
pre .kr, code .kr, .codeblock .kr {
|
|
||||||
color: #007020;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .kt, code .kt, .codeblock .kt {
|
|
||||||
color: #902000; }
|
|
||||||
pre .m, code .m, .codeblock .m {
|
|
||||||
color: #40a070; }
|
|
||||||
pre .s, code .s, .codeblock .s {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .na, code .na, .codeblock .na {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .nb, code .nb, .codeblock .nb {
|
|
||||||
color: #007020; }
|
|
||||||
pre .nc, code .nc, .codeblock .nc {
|
|
||||||
color: #0e84b5;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .no, code .no, .codeblock .no {
|
|
||||||
color: #60add5; }
|
|
||||||
pre .nd, code .nd, .codeblock .nd {
|
|
||||||
color: #555555;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .ni, code .ni, .codeblock .ni {
|
|
||||||
color: #d55537;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .ne, code .ne, .codeblock .ne {
|
|
||||||
color: #007020; }
|
|
||||||
pre .nf, code .nf, .codeblock .nf {
|
|
||||||
color: #06287e; }
|
|
||||||
pre .nl, code .nl, .codeblock .nl {
|
|
||||||
color: #002070;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .nn, code .nn, .codeblock .nn {
|
|
||||||
color: #0e84b5;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .nt, code .nt, .codeblock .nt {
|
|
||||||
color: #062873;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .nv, code .nv, .codeblock .nv {
|
|
||||||
color: #bb60d5; }
|
|
||||||
pre .ow, code .ow, .codeblock .ow {
|
|
||||||
color: #007020;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .w, code .w, .codeblock .w {
|
|
||||||
color: #bbbbbb; }
|
|
||||||
pre .mf, code .mf, .codeblock .mf {
|
|
||||||
color: #40a070; }
|
|
||||||
pre .mh, code .mh, .codeblock .mh {
|
|
||||||
color: #40a070; }
|
|
||||||
pre .mi, code .mi, .codeblock .mi {
|
|
||||||
color: #40a070; }
|
|
||||||
pre .mo, code .mo, .codeblock .mo {
|
|
||||||
color: #40a070; }
|
|
||||||
pre .sb, code .sb, .codeblock .sb {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .sc, code .sc, .codeblock .sc {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .sd, code .sd, .codeblock .sd {
|
|
||||||
color: #4070a0;
|
|
||||||
font-style: italic; }
|
|
||||||
pre .s2, code .s2, .codeblock .s2 {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .se, code .se, .codeblock .se {
|
|
||||||
color: #4070a0;
|
|
||||||
font-weight: bold; }
|
|
||||||
pre .sh, code .sh, .codeblock .sh {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .si, code .si, .codeblock .si {
|
|
||||||
color: #70a0d0;
|
|
||||||
font-style: italic; }
|
|
||||||
pre .sx, code .sx, .codeblock .sx {
|
|
||||||
color: #c65d09; }
|
|
||||||
pre .sr, code .sr, .codeblock .sr {
|
|
||||||
color: #235388; }
|
|
||||||
pre .s1, code .s1, .codeblock .s1 {
|
|
||||||
color: #4070a0; }
|
|
||||||
pre .ss, code .ss, .codeblock .ss {
|
|
||||||
color: #517918; }
|
|
||||||
pre .bp, code .bp, .codeblock .bp {
|
|
||||||
color: #007020; }
|
|
||||||
pre .vc, code .vc, .codeblock .vc {
|
|
||||||
color: #bb60d5; }
|
|
||||||
pre .vg, code .vg, .codeblock .vg {
|
|
||||||
color: #bb60d5; }
|
|
||||||
pre .vi, code .vi, .codeblock .vi {
|
|
||||||
color: #bb60d5; }
|
|
||||||
pre .il, code .il, .codeblock .il {
|
|
||||||
color: #40a070; }
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
background-color: #222;
|
|
||||||
color: #bbb; }
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--fg-font-color: black;
|
|
||||||
--theme-color: #666;
|
|
||||||
--theme-color-dim: #aaa;
|
|
||||||
--theme-color-dimmer: #bbb;
|
|
||||||
--theme-color-dimmest: #ccc;
|
|
||||||
--theme-color-dark: #666;
|
|
||||||
--theme-color-light: #666;
|
|
||||||
--link-color: #666;
|
|
||||||
--link-border-color: #666;
|
|
||||||
--hr-color: #444;
|
|
||||||
--main-background-color: #fff;
|
|
||||||
--main-color: black;
|
|
||||||
--dim-color: #333;
|
|
||||||
--dimmer-color: #999;
|
|
||||||
--dimmest-color: #bbb;
|
|
||||||
--menu-bottom-border-color: black;
|
|
||||||
--login-popup-background: #fbfbfb;
|
|
||||||
--content-background: #f8f8f8;
|
|
||||||
--content-background-transparent: rgba(248, 248, 248, 0);
|
|
||||||
--dim-background: #f0f0f0;
|
|
||||||
--dim-background-transparent: rgba(240, 240, 240, 0);
|
|
||||||
--text-background: #f9f9f9;
|
|
||||||
--spoiler-border: #aaa;
|
|
||||||
--background-even-background: #f8f8f8;
|
|
||||||
--project-card-border-color: #aaa;
|
|
||||||
--project-user-suggestions-background: #fff;
|
|
||||||
--project-user-suggestions-border-color: #ddd;
|
|
||||||
--notice-text-color: #fff;
|
|
||||||
--notice-unapproved-color: #b42222;
|
|
||||||
--notice-hidden-color: #b6b6b6;
|
|
||||||
--notice-hiatus-color: #aa7d30;
|
|
||||||
--notice-dead-color: #b42222;
|
|
||||||
--notice-lts-color: #43a52f;
|
|
||||||
--notice-lts-reqd-color: #aa7d30;
|
|
||||||
--notice-success-color: #43a52f;
|
|
||||||
--notice-warn-color: #aa7d30;
|
|
||||||
--notice-failure-color: #b42222;
|
|
||||||
--optionbar-border-color: #ccc;
|
|
||||||
--tab-background: #fff;
|
|
||||||
--tab-border-color: #d8d8d8;
|
|
||||||
--tab-button-background: #dfdfdf;
|
|
||||||
--tab-button-background-hover: #efefef;
|
|
||||||
--tab-button-background-current: #fff;
|
|
||||||
--form-check-background: #fafafc;
|
|
||||||
--form-check-border-color: #999;
|
|
||||||
--form-check-border-color-hover: #4c9ed9;
|
|
||||||
--form-text-background: #fff;
|
|
||||||
--form-text-background-active: #fafafc;
|
|
||||||
--form-text-border-color: #999;
|
|
||||||
--form-text-border-color-active: #4c9ed9;
|
|
||||||
--form-button-color: black;
|
|
||||||
--form-button-color-active: #4c9ed9;
|
|
||||||
--form-button-background: #fff;
|
|
||||||
--form-button-background-active: #f2f2f2;
|
|
||||||
--form-button-border-color: #ccc;
|
|
||||||
--form-button-inline-border-color: #999;
|
|
||||||
--form-error-color: #c61d24;
|
|
||||||
--landing-search-background: #f8f8f8;
|
|
||||||
--landing-search-background-hover: #fefeff;
|
|
||||||
--editor-toolbar-background: #fff;
|
|
||||||
--editor-toolbar-border-color: transparent;
|
|
||||||
--editor-toolbar-button-background: transparent;
|
|
||||||
--editor-toolbar-button-background-hover: #ddd;
|
|
||||||
--editor-toolbar-button-border-color: #ccc;
|
|
||||||
--post-blockquote-border-color: #ddd;
|
|
||||||
--forum-even-background: #f0f0f0;
|
|
||||||
--forum-thread-read-color: #555;
|
|
||||||
--forum-thread-read-link-color: #888;
|
|
||||||
--forum-post-author-color: #333;
|
|
||||||
--forum-diff-source-background: #fff;
|
|
||||||
--forum-diff-source-border-color: #999;
|
|
||||||
--forum-diff-replace-background: #adcef4;
|
|
||||||
--forum-diff-replace-border-color: #4787d1;
|
|
||||||
--forum-diff-delete-background: #e57979;
|
|
||||||
--forum-diff-delete-border-color: #c12626;
|
|
||||||
--forum-diff-insert-background: #96e579;
|
|
||||||
--forum-diff-insert-border-color: #5baa3f;
|
|
||||||
--card-background: #e8e8e8;
|
|
||||||
--card-background-hover: #f0f0f0;
|
|
||||||
--timeline-content-background: rgba(0, 0, 0, 0.2);
|
|
||||||
--irc-border-color: #ddd;
|
|
||||||
--irc-tab-current-shadow: 0px 0px 5px #bbb inset;
|
|
||||||
--irc-tab-close-button-color: #fff;
|
|
||||||
--irc-tab-close-button-background: #aaa;
|
|
||||||
--irc-nick-border-color: #ccc;
|
|
||||||
--irc-users-color: black;
|
|
||||||
--irc-users-background: #fff;
|
|
||||||
--irc-users-border-color: #ccc;
|
|
||||||
--irc-users-popout-background: #fff;
|
|
||||||
--irc-users-popout-border-color-left: #bbb;
|
|
||||||
--irc-users-popout-border-color-right: #ccc;
|
|
||||||
--code-line-number-color: #777;
|
|
||||||
--library-star-btn-background: #fff;
|
|
||||||
--library-star-btn-border-color: #999;
|
|
||||||
--library-star-btn-a-border-color: #aaa;
|
|
||||||
--library-star-btn-a-hover-background: #fafafa; }
|
|
|
@ -23,6 +23,7 @@ type ProjectsQuery struct {
|
||||||
// are generally visible to all users.
|
// are generally visible to all users.
|
||||||
Lifecycles []models.ProjectLifecycle // If empty, defaults to visible lifecycles. Do not conflate this with permissions; those are checked separately.
|
Lifecycles []models.ProjectLifecycle // If empty, defaults to visible lifecycles. Do not conflate this with permissions; those are checked separately.
|
||||||
Types ProjectTypeQuery // bitfield
|
Types ProjectTypeQuery // bitfield
|
||||||
|
FeaturedOnly bool
|
||||||
IncludeHidden bool
|
IncludeHidden bool
|
||||||
|
|
||||||
// Ignored when using FetchProject
|
// Ignored when using FetchProject
|
||||||
|
@ -133,6 +134,9 @@ func FetchProjects(
|
||||||
}
|
}
|
||||||
qb.Add(`)`)
|
qb.Add(`)`)
|
||||||
}
|
}
|
||||||
|
if q.FeaturedOnly {
|
||||||
|
qb.Add(`AND project.featured`)
|
||||||
|
}
|
||||||
if !q.IncludeHidden {
|
if !q.IncludeHidden {
|
||||||
qb.Add(`AND NOT project.hidden`)
|
qb.Add(`AND NOT project.hidden`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ type SnippetQuery struct {
|
||||||
Tags []int
|
Tags []int
|
||||||
DiscordMessageIDs []string
|
DiscordMessageIDs []string
|
||||||
|
|
||||||
|
FeaturedOnly bool
|
||||||
|
|
||||||
Limit, Offset int // if empty, no pagination
|
Limit, Offset int // if empty, no pagination
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
transition: all 100ms ease-in-out;
|
transition: all 100ms ease-in-out;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--dimmest-color);
|
background-color: var(--bg-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
|
|
|
@ -87,11 +87,11 @@
|
||||||
th,
|
th,
|
||||||
td {
|
td {
|
||||||
padding: var(--spacing-extra-small) var(--spacing-small);
|
padding: var(--spacing-extra-small) var(--spacing-small);
|
||||||
border: 1px solid var(--dimmest-color);
|
border: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background-color: var(--dim-background);
|
background-color: var(--bg-3);
|
||||||
|
|
||||||
padding: .2em 0;
|
padding: .2em 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -106,14 +106,14 @@
|
||||||
|
|
||||||
pre>code,
|
pre>code,
|
||||||
pre.hmn-code {
|
pre.hmn-code {
|
||||||
background-color: var(--dim-background);
|
background-color: var(--bg-3);
|
||||||
|
|
||||||
padding: 0.7em;
|
padding: 0.7em;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
border-color: var(--dimmest-color);
|
border-color: var(--bg-3);
|
||||||
margin-left: var(--spacing-small);
|
margin-left: var(--spacing-small);
|
||||||
padding-left: var(--spacing-small);
|
padding-left: var(--spacing-small);
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
|
|
@ -108,34 +108,6 @@ pre,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.b--dim {
|
|
||||||
border-color: var(--dim-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--dimmer {
|
|
||||||
border-color: var(--dimmer-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--dimmest {
|
|
||||||
border-color: var(--dimmest-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--theme {
|
|
||||||
border-color: var(--theme-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--theme-dim {
|
|
||||||
border-color: var(--theme-color-dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--theme-dimmer {
|
|
||||||
border-color: var(--theme-color-dimmer);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--theme-dimmest {
|
|
||||||
border-color: var(--theme-color-dimmest);
|
|
||||||
}
|
|
||||||
|
|
||||||
.b--theme-dark {
|
.b--theme-dark {
|
||||||
border-color: var(--theme-color-dark);
|
border-color: var(--theme-color-dark);
|
||||||
}
|
}
|
||||||
|
@ -201,30 +173,6 @@ pre,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c--dim {
|
|
||||||
color: var(--dim-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.c--theme-dim {
|
|
||||||
color: var(--theme-color-dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
.c--dimmer {
|
|
||||||
color: var(--dimmer-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.c--theme-dimmer {
|
|
||||||
color: var(--theme-color-dimmer);
|
|
||||||
}
|
|
||||||
|
|
||||||
.c--dimmest {
|
|
||||||
color: var(--dimmest-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.c--theme-dimmest {
|
|
||||||
color: var(--theme-color-dimmest);
|
|
||||||
}
|
|
||||||
|
|
||||||
.f8 {
|
.f8 {
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
}
|
}
|
||||||
|
@ -755,7 +703,7 @@ lite variant instead.
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
border-width: 0 0 1px;
|
border-width: 0 0 1px;
|
||||||
border-color: var(--dimmest-color);
|
border-color: var(--bg-3);
|
||||||
|
|
||||||
@media screen and (min-width: 35em) {
|
@media screen and (min-width: 35em) {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
border-width: 0 0 1px 1px;
|
border-width: 0 0 1px 1px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: var(--dimmest-color);
|
border-color: var(--bg-3);
|
||||||
left: -1.5rem;
|
left: -1.5rem;
|
||||||
top: calc(1rem - var(--height));
|
top: calc(1rem - var(--height));
|
||||||
border-bottom-left-radius: 0.5rem;
|
border-bottom-left-radius: 0.5rem;
|
||||||
|
|
|
@ -114,7 +114,7 @@ header.old {
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
background-color: var(--bg-3);
|
background-color: var(--bg-2);
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ header {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
min-width: 8rem;
|
min-width: 8rem;
|
||||||
background-color: var(--card-background);
|
background-color: var(--bg-2);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-top-width: 0;
|
border-top-width: 0;
|
||||||
|
|
|
@ -16,4 +16,5 @@
|
||||||
@import "projects.css";
|
@import "projects.css";
|
||||||
@import "showcase.css";
|
@import "showcase.css";
|
||||||
@import "syntax.css";
|
@import "syntax.css";
|
||||||
|
@import "tabs.css";
|
||||||
@import "timeline.css";
|
@import "timeline.css";
|
|
@ -0,0 +1,8 @@
|
||||||
|
.tab-button {
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button-active {
|
||||||
|
border-color: var(--link-color);
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
.avatar {
|
.avatar {
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: var(--dimmest-color);
|
background-color: var(--bg-3);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
|
@ -23,22 +23,34 @@
|
||||||
--fade-color: var(--card-background);
|
--fade-color: var(--card-background);
|
||||||
color: var(--main-color);
|
color: var(--main-color);
|
||||||
|
|
||||||
.timeline-content-box {
|
.timeline-media {
|
||||||
&.timeline-item-bg {
|
background-color: var(--timeline-media-background);
|
||||||
background-color: var(--timeline-content-background);
|
max-height: 60vh;
|
||||||
|
|
||||||
|
&.timeline-embed {
|
||||||
|
/* aspect-ratio aspect-ratio--16x9 */
|
||||||
|
height: 0;
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 56.25%;
|
||||||
|
|
||||||
|
>iframe {
|
||||||
|
/* aspect-ratio--object */
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
>* {
|
>* {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 80vh;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
|
||||||
/* 40px */
|
|
||||||
width: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-modal {
|
.timeline-modal {
|
||||||
|
|
|
@ -14,10 +14,6 @@ $breakpoint-large: screen and (min-width: 60em)
|
||||||
--link-color: #d12991;
|
--link-color: #d12991;
|
||||||
--red: #c61d24;
|
--red: #c61d24;
|
||||||
|
|
||||||
--dim-color: #333;
|
|
||||||
--dimmer-color: #999;
|
|
||||||
--dimmest-color: #bbb;
|
|
||||||
|
|
||||||
/* Default theme colors in case the project.css is busted */
|
/* Default theme colors in case the project.css is busted */
|
||||||
--theme-color: #b1b1b1;
|
--theme-color: #b1b1b1;
|
||||||
--theme-color-dim: #c0c0c0;
|
--theme-color-dim: #c0c0c0;
|
||||||
|
@ -34,6 +30,8 @@ $breakpoint-large: screen and (min-width: 60em)
|
||||||
--card-background-hover: #f1f1f1;
|
--card-background-hover: #f1f1f1;
|
||||||
--card-background-transparent: #ebebeb00;
|
--card-background-transparent: #ebebeb00;
|
||||||
|
|
||||||
|
--timeline-media-background: #b4b4b466;
|
||||||
|
|
||||||
--bg-1: #f8f8f8;
|
--bg-1: #f8f8f8;
|
||||||
--bg-2: #e8e8e8;
|
--bg-2: #e8e8e8;
|
||||||
--bg-3: #d8d8d8;
|
--bg-3: #d8d8d8;
|
||||||
|
@ -71,10 +69,6 @@ $breakpoint-large: screen and (min-width: 60em)
|
||||||
--link-color: #ff5dc2;
|
--link-color: #ff5dc2;
|
||||||
--color-error: #ff6666;
|
--color-error: #ff6666;
|
||||||
|
|
||||||
--dim-color: #bbb;
|
|
||||||
--dimmer-color: #999;
|
|
||||||
--dimmest-color: #777;
|
|
||||||
|
|
||||||
--theme-color: #666;
|
--theme-color: #666;
|
||||||
--theme-color-dim: #444;
|
--theme-color-dim: #444;
|
||||||
--theme-color-dimmer: #383838;
|
--theme-color-dimmer: #383838;
|
||||||
|
@ -91,6 +85,8 @@ $breakpoint-large: screen and (min-width: 60em)
|
||||||
--card-background-hover: #333;
|
--card-background-hover: #333;
|
||||||
--card-background-transparent: #24242400;
|
--card-background-transparent: #24242400;
|
||||||
|
|
||||||
|
--timeline-media-background: #24242466;
|
||||||
|
|
||||||
--bg-1: #1f1f1f;
|
--bg-1: #1f1f1f;
|
||||||
--bg-2: #2f2f2f;
|
--bg-2: #2f2f2f;
|
||||||
--bg-3: #494949;
|
--bg-3: #494949;
|
||||||
|
|
|
@ -389,16 +389,17 @@ func TimelineItemsToJSON(items []TimelineItem) string {
|
||||||
builder.WriteString(item.Url)
|
builder.WriteString(item.Url)
|
||||||
builder.WriteString(`",`)
|
builder.WriteString(`",`)
|
||||||
|
|
||||||
|
// TODO(redesign): This only serializes a single piece of media.
|
||||||
var mediaType TimelineItemMediaType
|
var mediaType TimelineItemMediaType
|
||||||
var assetUrl string
|
var assetUrl string
|
||||||
var thumbnailUrl string
|
var thumbnailUrl string
|
||||||
var width, height int
|
var width, height int
|
||||||
if len(item.EmbedMedia) > 0 {
|
if len(item.Media) > 0 {
|
||||||
mediaType = item.EmbedMedia[0].Type
|
mediaType = item.Media[0].Type
|
||||||
assetUrl = item.EmbedMedia[0].AssetUrl
|
assetUrl = item.Media[0].AssetUrl
|
||||||
thumbnailUrl = item.EmbedMedia[0].ThumbnailUrl
|
thumbnailUrl = item.Media[0].ThumbnailUrl
|
||||||
width = item.EmbedMedia[0].Width
|
width = item.Media[0].Width
|
||||||
height = item.EmbedMedia[0].Height
|
height = item.Media[0].Height
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.WriteString(`"media_type":`)
|
builder.WriteString(`"media_type":`)
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
{{ cleancontrolchars .Description }}
|
{{ cleancontrolchars .Description }}
|
||||||
]]>
|
]]>
|
||||||
</div>
|
</div>
|
||||||
{{ range .EmbedMedia }}
|
{{ range .Media }}
|
||||||
<div>
|
<div>
|
||||||
{{ if eq .Type mediaimage }}
|
{{ if eq .Type mediaimage }}
|
||||||
<img src="{{ .AssetUrl }}"/>
|
<img src="{{ .AssetUrl }}"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="breadcrumbs f7 o-80">
|
<div class="breadcrumbs f7">
|
||||||
{{ range $i, $breadcrumb := . }}
|
{{ range $i, $breadcrumb := . }}
|
||||||
{{ if gt $i 0 }} » {{ end }}
|
{{ if gt $i 0 }} » {{ end }}
|
||||||
<a href="{{ $breadcrumb.Url }}">{{ $breadcrumb.Name }}</a>
|
<a href="{{ $breadcrumb.Url }}">{{ $breadcrumb.Name }}</a>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div>{{ trim .Description }}</div>
|
<div>{{ trim .Description }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ range .EmbedMedia }}
|
{{ range .Media }}
|
||||||
<div class="flex flex-column {{ if eq .Type mediaembed }}wide-screen{{ end }} justify-stretch iframe-fill">
|
<div class="flex flex-column {{ if eq .Type mediaembed }}wide-screen{{ end }} justify-stretch iframe-fill">
|
||||||
{{ if eq .Type mediaimage }}
|
{{ if eq .Type mediaimage }}
|
||||||
<img src="{{ .AssetUrl }}">
|
<img src="{{ .AssetUrl }}">
|
||||||
|
|
|
@ -1,43 +1,64 @@
|
||||||
<div class="timeline-item flex flex-column pa3" data-id="{{ .ID }}" {{ with .FilterTitle }}data-filter-title="{{ . }}"{{ end }}>
|
<div class="timeline-item flex flex-column pa3" data-id="{{ .ID }}" {{ with .FilterTitle }}data-filter-title="{{ . }}"{{ end }}>
|
||||||
{{/* top bar - avatar, info, date */}}
|
{{/* top bar - avatar, info, date */}}
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
{{ if .OwnerAvatarUrl }}
|
{{ if .OwnerAvatarUrl }}
|
||||||
<a class="flex flex-shrink-0" href="{{ .OwnerUrl }}">
|
<a class="flex flex-shrink-0" href="{{ .OwnerUrl }}">
|
||||||
<img class="avatar avatar-user {{ if .SmallInfo }}avatar-small mr2{{ else }}mr3{{ end }}" src="{{ .OwnerAvatarUrl }}" />
|
<img class="avatar avatar-user {{ if .ForumLayout }}mr3{{ else }}mr2{{ end }}" src="{{ .OwnerAvatarUrl }}" />
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ if .ForumLayout }}
|
||||||
<div class="overflow-hidden flex-grow-1 flex flex-column justify-center">
|
<div class="overflow-hidden flex-grow-1 flex flex-column g1 justify-center">
|
||||||
{{ if .Breadcrumbs }}
|
{{ with .Breadcrumbs }}
|
||||||
{{ template "breadcrumbs.html" .Breadcrumbs }}
|
{{ template "breadcrumbs.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if .Title }}
|
{{ if .Title }}
|
||||||
<div class="f5 {{ if not .AllowTitleWrap }}nowrap truncate{{ end }}">
|
<div class="f5 lh-title {{ if not .AllowTitleWrap }}nowrap truncate{{ end }}">
|
||||||
{{ with .TypeTitle }}<b class="dn di-ns">{{ . }}:</b>{{ end }}
|
{{ with .TypeTitle }}<b class="dn di-ns">{{ . }}:</b>{{ end }}
|
||||||
<a href="{{ .Url }}">{{ .Title }}</a>
|
<a href="{{ .Url }}">{{ .Title }}</a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<div class="details">
|
<div class="details link--normal">
|
||||||
<a class="user" href="{{ .OwnerUrl }}">{{ .OwnerName }}</a>
|
<a class="user" href="{{ .OwnerUrl }}">{{ .OwnerName }}</a>
|
||||||
{{ if not .SmallInfo }}
|
— {{ timehtml (absoluteshortdate .Date) .Date }}
|
||||||
— {{ timehtml (relativedate .Date) .Date }}
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ if .SmallInfo }}
|
|
||||||
<a href="{{ .Url }}">{{ timehtml (relativedate .Date) .Date }}</a>
|
|
||||||
{{ end }}
|
|
||||||
{{ if .Editable }}
|
{{ if .Editable }}
|
||||||
<a href="javascript:;" class="edit ml2">✎</a>
|
<a href="javascript:;" class="edit ml2">✎</a>
|
||||||
<div class="dn rawdesc">{{ .RawDescription }}</div>
|
<div class="dn rawdesc">{{ .RawDescription }}</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ else }}
|
||||||
|
<div class="overflow-hidden flex-grow-1 flex flex-column g1 justify-center link--normal">
|
||||||
|
{{ if .Breadcrumbs }}
|
||||||
|
<div>Use .ForumLayout if you want breadcrumbs :)</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ if .Title }}
|
||||||
|
<div>Use .ForumLayout if you want a title :)</div>
|
||||||
|
{{ end }}
|
||||||
|
<a class="user b" href="{{ .OwnerUrl }}">{{ .OwnerName }}</a>
|
||||||
|
<a class="f6" href="{{ .Url }}">{{ timehtml (absoluteshortdate .Date) .Date }}</a>
|
||||||
|
</div>
|
||||||
|
{{ if eq (len .Projects) 1 }}
|
||||||
|
{{ $p := index .Projects 0 }}
|
||||||
|
<div class="overflow-hidden flex flex-column g1 justify-center link--normal tr">
|
||||||
|
<a class="user b" href="{{ $p.Url }}">{{ $p.Name }}</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ range .Projects }}
|
||||||
|
{{ if .Logo }}
|
||||||
|
<a class="flex flex-shrink-0" href="{{ .Url }}">
|
||||||
|
<img class="avatar ml2" src="{{ .Logo }}">
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{/* content */}}
|
{{/* content */}}
|
||||||
|
|
||||||
{{ range .EmbedMedia }}
|
{{ range .Media }}
|
||||||
<div class="timeline-content-box mt3 {{ if eq .Type mediaembed }}embed{{ end }} overflow-hidden flex {{ if not (eq .Type mediaunknown) }}timeline-item-bg justify-center{{ end }}">
|
<div class="timeline-media mt3 {{ if eq .Type mediaembed }}timeline-embed{{ end }} overflow-hidden flex {{ if not (eq .Type mediaunknown) }}justify-center{{ end }}">
|
||||||
{{ if eq .Type mediaimage }}
|
{{ if eq .Type mediaimage }}
|
||||||
<img src="{{ .AssetUrl }}">
|
<img src="{{ .AssetUrl }}">
|
||||||
{{ else if eq .Type mediavideo }}
|
{{ else if eq .Type mediavideo }}
|
||||||
|
@ -72,14 +93,7 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ with .Projects }}
|
{{ with .DiscordMessageUrl }}
|
||||||
<div class="mt3 flex g2 projects">
|
<a class="f7 mt3 i" href="{{ . }}" target="_blank">View original message on Discord</a>
|
||||||
{{ range $i, $proj := . }}
|
|
||||||
<a data-projid="{{ $proj.ID }}" href="{{ $proj.Url }}" class="snippet-project flex flex-row items-center bg-theme-dimmer ph2 pv1">
|
|
||||||
<img src="{{ $proj.Logo }}" class="db mr1 br1 h1-5" />
|
|
||||||
<div>{{ $proj.Name }}</div>
|
|
||||||
</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
{{ define "extrahead" }}
|
{{ define "extrahead" }}
|
||||||
<script src="{{ static "js/templates.js" }}"></script>
|
<script src="{{ static "js/templates.js" }}"></script>
|
||||||
|
<script src="{{ static "js/tabs.js" }}"></script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
|
@ -87,31 +88,31 @@
|
||||||
<div class="w5 flex flex-column g2 flex-shrink-0">
|
<div class="w5 flex flex-column g2 flex-shrink-0">
|
||||||
{{ if .User }}
|
{{ if .User }}
|
||||||
<div class="sidebar-card bg--card link--normal">
|
<div class="sidebar-card bg--card link--normal">
|
||||||
<div onclick="collapse(event)" class="pa2 flex justify-between items-center pointer">
|
<div onclick="collapse(event)" class="pa3 flex justify-between items-center pointer">
|
||||||
<span class="f7">Your projects</span>
|
<span class="f7">Your projects</span>
|
||||||
<span class="sidebar-chevron svgicon-lite rot-180">{{ svg "chevron-down" }}</span>
|
<span class="sidebar-chevron svgicon-lite rot-180">{{ svg "chevron-down" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-card-content">
|
<div class="sidebar-card-content">
|
||||||
<div class="ph2 flex flex-column g2">
|
<div class="ph3 flex flex-column g2">
|
||||||
{{ range .UserProjects }}
|
{{ range .UserProjects }}
|
||||||
{{ template "list-project" . }}
|
{{ template "list-project" . }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<div class="f7 pv3 tc c--dim">You have not created any projects.</div>
|
<div class="f7 pv3 tc c--dim">You have not created any projects.</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<a class="bt mt2 pa2 flex justify-between" href="{{ .NewProjectUrl }}">
|
<a class="bt mt3 pa3 flex justify-between" href="{{ .NewProjectUrl }}">
|
||||||
<div>Create new project</div>
|
<div>Create new project</div>
|
||||||
<div class="svgicon-lite flex items-center">{{ svg "add" }}</div>
|
<div class="svgicon-lite flex items-center">{{ svg "add" }}</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-card bg--card link--normal">
|
<div class="sidebar-card bg--card link--normal">
|
||||||
<div onclick="collapse(event)" class="pa2 flex justify-between items-center pointer">
|
<div onclick="collapse(event)" class="pa3 flex justify-between items-center pointer">
|
||||||
<span class="f7">Following</span>
|
<span class="f7">Following</span>
|
||||||
<span class="sidebar-chevron svgicon-lite rot-180">{{ svg "chevron-down" }}</span>
|
<span class="sidebar-chevron svgicon-lite rot-180">{{ svg "chevron-down" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-card-content">
|
<div class="sidebar-card-content">
|
||||||
<div class="ph2 pb2 flex flex-column g2">
|
<div class="ph3 pb3 flex flex-column g2">
|
||||||
{{ range .Following }}
|
{{ range .Following }}
|
||||||
{{ template "list-follow" . }}
|
{{ template "list-follow" . }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
|
@ -122,11 +123,11 @@
|
||||||
</div>
|
</div>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<div class="bg--card link--normal">
|
<div class="bg--card link--normal">
|
||||||
<div class="pa2 flex flex-column g2">
|
<div class="pa3 flex flex-column g2">
|
||||||
<div class="b">Join the Handmade Network</div>
|
<div class="b">Join the Handmade Network</div>
|
||||||
<div class="f6 post-content">Share your own Handmade projects with the community.</div>
|
<div class="f6 post-content">Share your own Handmade projects with the community.</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="bt pa2 flex justify-between" href="{{ .LoginPageUrl }}">
|
<a class="bt pa3 flex justify-between" href="{{ .LoginPageUrl }}">
|
||||||
<div>Log in</div>
|
<div>Log in</div>
|
||||||
<div class="svgicon-lite flex items-center">{{ svg "chevron-right" }}</div>
|
<div class="svgicon-lite flex items-center">{{ svg "chevron-right" }}</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -139,14 +140,43 @@
|
||||||
|
|
||||||
<!-- Feed -->
|
<!-- Feed -->
|
||||||
<div class="flex flex-column flex-grow-1 overflow-hidden">
|
<div class="flex flex-column flex-grow-1 overflow-hidden">
|
||||||
<div class="timeline flex flex-column g3">
|
<div id="landing-tabs">
|
||||||
|
<div class="bb mb2 flex f6">
|
||||||
|
{{ if .User }}
|
||||||
|
<div data-tab-button="following" class="tab-button ph3 pv1 pointer">Following</div>
|
||||||
|
{{ end }}
|
||||||
|
<div data-tab-button="featured" class="tab-button ph3 pv1 pointer">Featured</div>
|
||||||
|
<div data-tab-button="recent" class="tab-button ph3 pv1 pointer">Recent</div>
|
||||||
|
<div data-tab-button="news" class="tab-button ph3 pv1 pointer">News</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ if .User }}
|
||||||
|
<div data-tab="following" class="timeline flex flex-column g3">
|
||||||
|
{{ range .FollowingItems }}
|
||||||
|
{{ template "timeline_item.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<div data-tab="featured" class="timeline flex flex-column g3">
|
||||||
|
{{ range .FeaturedItems }}
|
||||||
|
{{ template "timeline_item.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div data-tab="recent" class="timeline flex flex-column g3">
|
||||||
{{ range .RecentItems }}
|
{{ range .RecentItems }}
|
||||||
{{ template "timeline_item.html" . }}
|
{{ template "timeline_item.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div data-tab="news" class="timeline flex flex-column g3">
|
||||||
|
{{ range .NewsItems }}
|
||||||
|
{{ template "timeline_item.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
TODO: READ MORE LINK
|
TODO: READ MORE LINK
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -160,6 +190,8 @@
|
||||||
content.hidden = hide;
|
content.hidden = hide;
|
||||||
chevron.classList.toggle("rot-180", !hide);
|
chevron.classList.toggle("rot-180", !hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initTabs(document.querySelector("#landing-tabs"));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -76,6 +76,9 @@
|
||||||
|
|
||||||
<body class="{{ join " " .BodyClasses }}">
|
<body class="{{ join " " .BodyClasses }}">
|
||||||
<div class="bg--main m--center mw-site ph3-m ph4-l">
|
<div class="bg--main m--center mw-site ph3-m ph4-l">
|
||||||
|
<div class="notice notice-warn mt3 mb2 white ph3 pv2 br2-ns">
|
||||||
|
We are currently in the process of converting the website to the new design. Some pages, like this one, are still broken. We appreciate your patience.
|
||||||
|
</div>
|
||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
{{ template "notices.html" .Notices }}
|
{{ template "notices.html" .Notices }}
|
||||||
{{ with .Breadcrumbs }}
|
{{ with .Breadcrumbs }}
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
--theme-color-dimmer: {{ $themeDimmer }};
|
--theme-color-dimmer: {{ $themeDimmer }};
|
||||||
--theme-color-dimmest: {{ $themeDimmest }};
|
--theme-color-dimmest: {{ $themeDimmest }};
|
||||||
|
|
||||||
--timeline-content-background: rgba(255, 255, 255, 0.1);
|
--timeline-media-background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
--theme-color-dimmer: {{ $themeDimmer }};
|
--theme-color-dimmer: {{ $themeDimmer }};
|
||||||
--theme-color-dimmest: {{ $themeDimmest }};
|
--theme-color-dimmest: {{ $themeDimmest }};
|
||||||
|
|
||||||
--timeline-content-background: rgba(255, 255, 255, 0.1);
|
--timeline-media-background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
--theme-color-dimmer: {{ $themeDimmer }};
|
--theme-color-dimmer: {{ $themeDimmer }};
|
||||||
--theme-color-dimmest: {{ $themeDimmest }};
|
--theme-color-dimmest: {{ $themeDimmest }};
|
||||||
|
|
||||||
--timeline-content-background: rgba(255, 255, 255, 0.1);
|
--timeline-media-background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
{{ define "extrahead" }}
|
{{ define "extrahead" }}
|
||||||
{{ template "markdown_previews.html" .TextEditor }}
|
{{ template "markdown_previews.html" .TextEditor }}
|
||||||
<script src="{{ static "js/tabs.js" }}"></script>
|
|
||||||
<script src="{{ static "js/image_selector.js" }}"></script>
|
<script src="{{ static "js/image_selector.js" }}"></script>
|
||||||
<script src="{{ static "js/templates.js" }}"></script>
|
<script src="{{ static "js/templates.js" }}"></script>
|
||||||
<script src="{{ static "js/base64.js" }}"></script>
|
<script src="{{ static "js/base64.js" }}"></script>
|
||||||
|
|
|
@ -109,6 +109,30 @@ int main() {
|
||||||
<span class="n">GetWindowRect</span><span class="p">(</span> <span class="n">big_window</span><span class="p">,</span> <span class="o">&</span><span class="n">window_rect</span> <span class="p">);</span>
|
<span class="n">GetWindowRect</span><span class="p">(</span> <span class="n">big_window</span><span class="p">,</span> <span class="o">&</span><span class="n">window_rect</span> <span class="p">);</span>
|
||||||
<span class="n">window_rect</span><span class="p">.</span><span class="n">top</span> <span class="o">+=</span> <span class="mi">30</span><span class="p">;</span>
|
<span class="n">window_rect</span><span class="p">.</span><span class="n">top</span> <span class="o">+=</span> <span class="mi">30</span><span class="p">;</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Items</th>
|
||||||
|
<th>Expenditure</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>Donuts</th>
|
||||||
|
<td>3,000</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Stationery</th>
|
||||||
|
<td>18,000</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<th>Totals</th>
|
||||||
|
<td>21,000</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 class="mt3 mb2">Form styles</h1>
|
<h1 class="mt3 mb2">Form styles</h1>
|
||||||
|
@ -212,7 +236,7 @@ int main() {
|
||||||
|
|
||||||
<h1 class="mt3 mb2">Timeline items</h1>
|
<h1 class="mt3 mb2">Timeline items</h1>
|
||||||
|
|
||||||
<div class="hmn-form pa3 ba b--theme-dim flex flex-column g3">
|
<div class="hmn-form pa3 ba b--theme-dim flex flex-column g3 mw7">
|
||||||
{{ range .TestTimelineItems }}
|
{{ range .TestTimelineItems }}
|
||||||
{{ template "timeline_item.html" . }}
|
{{ template "timeline_item.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{{ template "base-2024.html" . }}
|
{{ template "base-2024.html" . }}
|
||||||
|
|
||||||
{{ define "extrahead" }}
|
{{ define "extrahead" }}
|
||||||
<script src="{{ static "js/tabs.js" }}"></script>
|
|
||||||
<script src="{{ static "js/image_selector.js" }}"></script>
|
<script src="{{ static "js/image_selector.js" }}"></script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
|
@ -338,9 +338,9 @@ type TimelineItem struct {
|
||||||
Description template.HTML
|
Description template.HTML
|
||||||
RawDescription string
|
RawDescription string
|
||||||
|
|
||||||
EmbedMedia []TimelineItemMedia
|
Media []TimelineItemMedia
|
||||||
|
|
||||||
SmallInfo bool
|
ForumLayout bool
|
||||||
AllowTitleWrap bool
|
AllowTitleWrap bool
|
||||||
TruncateDescription bool
|
TruncateDescription bool
|
||||||
CanShowcase bool // whether this snippet can be shown in a showcase gallery
|
CanShowcase bool // whether this snippet can be shown in a showcase gallery
|
||||||
|
|
|
@ -188,7 +188,6 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.OwnerAvatarUrl = ""
|
timelineItem.OwnerAvatarUrl = ""
|
||||||
timelineItem.SmallInfo = true
|
|
||||||
userData.Timeline = append(userData.Timeline, timelineItem)
|
userData.Timeline = append(userData.Timeline, timelineItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +209,6 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
timelineItem := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, &p.Author)
|
timelineItem := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, &p.Author)
|
||||||
timelineItem.OwnerAvatarUrl = ""
|
timelineItem.OwnerAvatarUrl = ""
|
||||||
timelineItem.SmallInfo = true
|
|
||||||
timelineItem.Description = template.HTML(p.CurrentVersion.TextParsed)
|
timelineItem.Description = template.HTML(p.CurrentVersion.TextParsed)
|
||||||
userData.Timeline = append(userData.Timeline, timelineItem)
|
userData.Timeline = append(userData.Timeline, timelineItem)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ func StyleTest(c *RequestContext) ResponseData {
|
||||||
TestTimelineItems: []templates.TimelineItem{
|
TestTimelineItems: []templates.TimelineItem{
|
||||||
// Forum post
|
// Forum post
|
||||||
{
|
{
|
||||||
|
ForumLayout: true,
|
||||||
OwnerName: "Cool User",
|
OwnerName: "Cool User",
|
||||||
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
Date: time.Now().Add(-5 * time.Second),
|
Date: time.Now().Add(-5 * time.Second),
|
||||||
|
@ -28,45 +29,73 @@ func StyleTest(c *RequestContext) ResponseData {
|
||||||
Title: "How can I a website?",
|
Title: "How can I a website?",
|
||||||
},
|
},
|
||||||
// Blog post
|
// Blog post
|
||||||
// Snippet
|
// Snippet with image
|
||||||
{
|
{
|
||||||
SmallInfo: true,
|
|
||||||
OwnerName: "Cool User",
|
OwnerName: "Cool User",
|
||||||
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
Date: time.Date(2022, 3, 20, 13, 32, 54, 0, time.UTC),
|
Date: time.Date(2022, 3, 20, 13, 32, 54, 0, time.UTC),
|
||||||
Url: "test",
|
Url: "test",
|
||||||
DiscordMessageUrl: "test",
|
DiscordMessageUrl: "test",
|
||||||
EmbedMedia: []templates.TimelineItemMedia{
|
Media: []templates.TimelineItemMedia{
|
||||||
{
|
{
|
||||||
Type: templates.TimelineItemMediaTypeImage,
|
Type: templates.TimelineItemMediaTypeImage,
|
||||||
AssetUrl: "https://assets.media.handmade.network/32ff3e7e-1d9c-4740-a062-1f8bec2e44cf/unknown.png",
|
AssetUrl: "https://assets.media.handmade.network/32ff3e7e-1d9c-4740-a062-1f8bec2e44cf/unknown.png",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Projects: []templates.Project{
|
||||||
|
{Name: "Cool Project", Logo: "https://assets.media.handmade.network/8c6a3b71-9e91-4bf6-80ef-bc8f3d21b30d/netsim.png"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Snippet with tall image
|
||||||
|
{
|
||||||
|
OwnerName: "Cool User",
|
||||||
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
|
Date: time.Date(2022, 3, 20, 13, 32, 54, 0, time.UTC),
|
||||||
|
Description: "I got my LaGUI working on Android! 😄",
|
||||||
|
Url: "test",
|
||||||
|
DiscordMessageUrl: "https://discord.com/channels/239737791225790464/404399251276169217/1245228715407966208",
|
||||||
|
Media: []templates.TimelineItemMedia{
|
||||||
|
{
|
||||||
|
Type: templates.TimelineItemMediaTypeImage,
|
||||||
|
AssetUrl: "https://assets.media.handmade.network/ea6f914a-ea00-4cbb-bbd7-586b82fdb484/Screenshot_20240529_120344_com.lagui.simplest.jpg",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Snippet with video
|
||||||
|
{
|
||||||
|
OwnerName: "Cool User",
|
||||||
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
|
Date: time.Date(2024, 1, 30, 3, 32, 54, 0, time.UTC),
|
||||||
|
Url: "test",
|
||||||
|
Description: "Using my newfound decoding knowledge I started working on a simple video editor. I also tried decoding 16 files at once, which didn't seem to bother my 3080 at all.",
|
||||||
|
DiscordMessageUrl: "https://discord.com/channels/239737791225790464/404399251276169217/1249562779619168266",
|
||||||
|
Media: []templates.TimelineItemMedia{
|
||||||
|
{
|
||||||
|
Type: templates.TimelineItemMediaTypeVideo,
|
||||||
|
AssetUrl: "https://assets.media.handmade.network/b122c7be-dc6d-41fe-a5ed-033fe991927e/show16.mp4",
|
||||||
|
ThumbnailUrl: "https://assets.media.handmade.network/b122c7be-dc6d-41fe-a5ed-033fe991927e/b122c7be-dc6d-41fe-a5ed-033fe991927e_thumb.jpg",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// Snippet with embed
|
// Snippet with embed
|
||||||
{
|
{
|
||||||
SmallInfo: true,
|
|
||||||
OwnerName: "Cool User",
|
OwnerName: "Cool User",
|
||||||
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
Date: time.Date(2021, 4, 3, 1, 44, 54, 0, time.UTC),
|
Date: time.Date(2021, 4, 3, 1, 44, 54, 0, time.UTC),
|
||||||
Url: "test",
|
Url: "test",
|
||||||
DiscordMessageUrl: "test",
|
DiscordMessageUrl: "test",
|
||||||
EmbedMedia: []templates.TimelineItemMedia{
|
Media: []templates.TimelineItemMedia{
|
||||||
youtubeMediaItem("FN9hZcTB16g"),
|
youtubeMediaItem("FN9hZcTB16g"),
|
||||||
},
|
},
|
||||||
Projects: []templates.Project{
|
|
||||||
{Name: "Cool Project", Logo: templates.UserAvatarDefaultUrl("light")},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// Snippet with two images & multiple projects
|
// Snippet with two images & multiple projects
|
||||||
{
|
{
|
||||||
SmallInfo: true,
|
|
||||||
OwnerName: "Cool User",
|
OwnerName: "Cool User",
|
||||||
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
Date: time.Now().Add(-2 * 24 * time.Hour),
|
Date: time.Now().Add(-2 * 24 * time.Hour),
|
||||||
Url: "test",
|
Url: "test",
|
||||||
DiscordMessageUrl: "test",
|
DiscordMessageUrl: "test",
|
||||||
EmbedMedia: []templates.TimelineItemMedia{
|
Media: []templates.TimelineItemMedia{
|
||||||
{
|
{
|
||||||
Type: templates.TimelineItemMediaTypeImage,
|
Type: templates.TimelineItemMediaTypeImage,
|
||||||
AssetUrl: "https://assets.media.handmade.network/979d8850-f6b6-44b4-984e-93be82eb492b/PBR_WIP_20240620_01.png",
|
AssetUrl: "https://assets.media.handmade.network/979d8850-f6b6-44b4-984e-93be82eb492b/PBR_WIP_20240620_01.png",
|
||||||
|
@ -77,19 +106,18 @@ func StyleTest(c *RequestContext) ResponseData {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Projects: []templates.Project{
|
Projects: []templates.Project{
|
||||||
{Name: "Cool Project", Logo: templates.UserAvatarDefaultUrl("light")},
|
{Name: "Cool Project", Logo: "https://assets.media.handmade.network/8c6a3b71-9e91-4bf6-80ef-bc8f3d21b30d/netsim.png"},
|
||||||
{Name: "Uncool Project"},
|
{Name: "Uncool Project"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Snippet with a video and an image
|
// Snippet with a video and an image
|
||||||
{
|
{
|
||||||
SmallInfo: true,
|
|
||||||
OwnerName: "Cool User",
|
OwnerName: "Cool User",
|
||||||
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
OwnerAvatarUrl: templates.UserAvatarDefaultUrl("dark"),
|
||||||
Date: time.Now().Add(-2 * time.Hour),
|
Date: time.Now().Add(-2 * time.Hour),
|
||||||
Url: "test",
|
Url: "test",
|
||||||
DiscordMessageUrl: "test",
|
DiscordMessageUrl: "test",
|
||||||
EmbedMedia: []templates.TimelineItemMedia{
|
Media: []templates.TimelineItemMedia{
|
||||||
{
|
{
|
||||||
Type: templates.TimelineItemMediaTypeImage,
|
Type: templates.TimelineItemMediaTypeImage,
|
||||||
AssetUrl: "https://assets.media.handmade.network/979d8850-f6b6-44b4-984e-93be82eb492b/PBR_WIP_20240620_01.png",
|
AssetUrl: "https://assets.media.handmade.network/979d8850-f6b6-44b4-984e-93be82eb492b/PBR_WIP_20240620_01.png",
|
||||||
|
@ -100,8 +128,7 @@ func StyleTest(c *RequestContext) ResponseData {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Projects: []templates.Project{
|
Projects: []templates.Project{
|
||||||
{Name: "Cool Project", Logo: templates.UserAvatarDefaultUrl("light")},
|
{Name: "Project without logo"},
|
||||||
{Name: "Uncool Project"},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Snippet with every type of embed at once
|
// Snippet with every type of embed at once
|
||||||
|
|
|
@ -271,7 +271,6 @@ func getLJ2024FeedData(c *RequestContext, maxTimelineItems int) (JamFeedDataLJ20
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,7 +450,6 @@ func JamFeed2023(c *RequestContext) ResponseData {
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,7 +617,6 @@ func JamFeed2023_Visibility(c *RequestContext) ResponseData {
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +829,6 @@ func JamFeed2022(c *RequestContext) ResponseData {
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ func Index(c *RequestContext) ResponseData {
|
||||||
type LandingTemplateData struct {
|
type LandingTemplateData struct {
|
||||||
templates.BaseData
|
templates.BaseData
|
||||||
|
|
||||||
NewsPost *templates.TimelineItem
|
|
||||||
FollowingItems []templates.TimelineItem
|
FollowingItems []templates.TimelineItem
|
||||||
FeaturedItems []templates.TimelineItem
|
FeaturedItems []templates.TimelineItem
|
||||||
RecentItems []templates.TimelineItem
|
RecentItems []templates.TimelineItem
|
||||||
|
@ -56,6 +55,24 @@ func Index(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
featuredProjects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
|
||||||
|
FeaturedOnly: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
c.Logger.Warn().Err(err).Msg("failed to fetch featured projects")
|
||||||
|
}
|
||||||
|
var featuredProjectIDs []int
|
||||||
|
for _, p := range featuredProjects {
|
||||||
|
featuredProjectIDs = append(featuredProjectIDs, p.Project.ID)
|
||||||
|
}
|
||||||
|
featuredItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, TimelineQuery{
|
||||||
|
ProjectIDs: featuredProjectIDs,
|
||||||
|
Limit: 100,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
c.Logger.Warn().Err(err).Msg("failed to fetch featured feed")
|
||||||
|
}
|
||||||
|
|
||||||
recentItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, TimelineQuery{
|
recentItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, TimelineQuery{
|
||||||
Limit: 100,
|
Limit: 100,
|
||||||
})
|
})
|
||||||
|
@ -63,27 +80,24 @@ func Index(c *RequestContext) ResponseData {
|
||||||
c.Logger.Warn().Err(err).Msg("failed to fetch recent feed")
|
c.Logger.Warn().Err(err).Msg("failed to fetch recent feed")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Perf.StartBlock("SQL", "Get news")
|
|
||||||
newsThreads, err := hmndata.FetchThreads(c, c.Conn, c.CurrentUser, hmndata.ThreadsQuery{
|
newsThreads, err := hmndata.FetchThreads(c, c.Conn, c.CurrentUser, hmndata.ThreadsQuery{
|
||||||
ProjectIDs: []int{models.HMNProjectID},
|
ProjectIDs: []int{models.HMNProjectID},
|
||||||
ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost},
|
ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost},
|
||||||
Limit: 1,
|
Limit: 100,
|
||||||
|
OrderByCreated: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch news post"))
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch news threads"))
|
||||||
}
|
}
|
||||||
var newsPostItem *templates.TimelineItem
|
for _, t := range newsThreads {
|
||||||
if len(newsThreads) > 0 {
|
item := PostToTimelineItem(c.UrlContext, lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor)
|
||||||
t := newsThreads[0]
|
|
||||||
item := PostToTimelineItem(hmndata.UrlContextForProject(&t.Project), lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor)
|
|
||||||
item.Breadcrumbs = nil
|
item.Breadcrumbs = nil
|
||||||
item.TypeTitle = ""
|
item.TypeTitle = ""
|
||||||
item.AllowTitleWrap = true
|
|
||||||
item.Description = template.HTML(t.FirstPostCurrentVersion.TextParsed)
|
item.Description = template.HTML(t.FirstPostCurrentVersion.TextParsed)
|
||||||
|
item.AllowTitleWrap = true
|
||||||
item.TruncateDescription = true
|
item.TruncateDescription = true
|
||||||
newsPostItem = &item
|
newsItems = append(newsItems, item)
|
||||||
}
|
}
|
||||||
c.Perf.EndBlock()
|
|
||||||
|
|
||||||
var projects []templates.Project
|
var projects []templates.Project
|
||||||
if c.CurrentUser != nil {
|
if c.CurrentUser != nil {
|
||||||
|
@ -117,7 +131,6 @@ func Index(c *RequestContext) ResponseData {
|
||||||
err = res.WriteTemplate("landing.html", LandingTemplateData{
|
err = res.WriteTemplate("landing.html", LandingTemplateData{
|
||||||
BaseData: baseData,
|
BaseData: baseData,
|
||||||
|
|
||||||
NewsPost: newsPostItem,
|
|
||||||
FollowingItems: followingItems,
|
FollowingItems: followingItems,
|
||||||
FeaturedItems: featuredItems,
|
FeaturedItems: featuredItems,
|
||||||
RecentItems: recentItems,
|
RecentItems: recentItems,
|
||||||
|
|
|
@ -58,7 +58,6 @@ func Snippet(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
canEdit := (c.CurrentUser != nil && (c.CurrentUser.IsStaff || c.CurrentUser.ID == s.Owner.ID))
|
canEdit := (c.CurrentUser != nil && (c.CurrentUser.IsStaff || c.CurrentUser.ID == s.Owner.ID))
|
||||||
snippet := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, canEdit)
|
snippet := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, canEdit)
|
||||||
snippet.SmallInfo = true
|
|
||||||
|
|
||||||
opengraph := []templates.OpenGraphItem{
|
opengraph := []templates.OpenGraphItem{
|
||||||
{Property: "og:site_name", Value: "Handmade Network"},
|
{Property: "og:site_name", Value: "Handmade Network"},
|
||||||
|
@ -68,8 +67,8 @@ func Snippet(c *RequestContext) ResponseData {
|
||||||
{Property: "og:description", Value: string(snippet.Description)},
|
{Property: "og:description", Value: string(snippet.Description)},
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(snippet.EmbedMedia) > 0 {
|
if len(snippet.Media) > 0 {
|
||||||
media := snippet.EmbedMedia[0]
|
media := snippet.Media[0]
|
||||||
|
|
||||||
switch media.Type {
|
switch media.Type {
|
||||||
case templates.TimelineItemMediaTypeImage:
|
case templates.TimelineItemMediaTypeImage:
|
||||||
|
|
|
@ -148,7 +148,6 @@ func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.Us
|
||||||
s.Owner,
|
s.Owner,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
item.SmallInfo = true
|
|
||||||
timelineItems = append(timelineItems, item)
|
timelineItems = append(timelineItems, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +299,8 @@ func PostToTimelineItem(
|
||||||
OwnerAvatarUrl: ownerTmpl.AvatarUrl,
|
OwnerAvatarUrl: ownerTmpl.AvatarUrl,
|
||||||
OwnerName: ownerTmpl.Name,
|
OwnerName: ownerTmpl.Name,
|
||||||
OwnerUrl: ownerTmpl.ProfileUrl,
|
OwnerUrl: ownerTmpl.ProfileUrl,
|
||||||
|
|
||||||
|
ForumLayout: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if typeTitles, ok := TimelineTypeTitleMap[post.ThreadType]; ok {
|
if typeTitles, ok := TimelineTypeTitleMap[post.ThreadType]; ok {
|
||||||
|
@ -349,7 +350,7 @@ func TwitchStreamToTimelineItem(
|
||||||
OwnerName: ownerName,
|
OwnerName: ownerName,
|
||||||
OwnerUrl: ownerUrl,
|
OwnerUrl: ownerUrl,
|
||||||
|
|
||||||
SmallInfo: true,
|
ForumLayout: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
@ -382,26 +383,26 @@ func SnippetToTimelineItem(
|
||||||
|
|
||||||
if asset != nil {
|
if asset != nil {
|
||||||
if strings.HasPrefix(asset.MimeType, "image/") {
|
if strings.HasPrefix(asset.MimeType, "image/") {
|
||||||
item.EmbedMedia = append(item.EmbedMedia, imageMediaItem(asset))
|
item.Media = append(item.Media, imageMediaItem(asset))
|
||||||
} else if strings.HasPrefix(asset.MimeType, "video/") {
|
} else if strings.HasPrefix(asset.MimeType, "video/") {
|
||||||
item.EmbedMedia = append(item.EmbedMedia, videoMediaItem(asset))
|
item.Media = append(item.Media, videoMediaItem(asset))
|
||||||
} else if strings.HasPrefix(asset.MimeType, "audio/") {
|
} else if strings.HasPrefix(asset.MimeType, "audio/") {
|
||||||
item.EmbedMedia = append(item.EmbedMedia, audioMediaItem(asset))
|
item.Media = append(item.Media, audioMediaItem(asset))
|
||||||
} else {
|
} else {
|
||||||
item.EmbedMedia = append(item.EmbedMedia, unknownMediaItem(asset))
|
item.Media = append(item.Media, unknownMediaItem(asset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if snippet.Url != nil {
|
if snippet.Url != nil {
|
||||||
url := *snippet.Url
|
url := *snippet.Url
|
||||||
if videoId := getYoutubeVideoID(url); videoId != "" {
|
if videoId := getYoutubeVideoID(url); videoId != "" {
|
||||||
item.EmbedMedia = append(item.EmbedMedia, youtubeMediaItem(videoId))
|
item.Media = append(item.Media, youtubeMediaItem(videoId))
|
||||||
item.CanShowcase = false
|
item.CanShowcase = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(item.EmbedMedia) == 0 ||
|
if len(item.Media) == 0 ||
|
||||||
(len(item.EmbedMedia) > 0 && (item.EmbedMedia[0].Width == 0 || item.EmbedMedia[0].Height == 0)) {
|
(len(item.Media) > 0 && (item.Media[0].Width == 0 || item.Media[0].Height == 0)) {
|
||||||
item.CanShowcase = false
|
item.CanShowcase = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
- [x] column
|
- [x] column
|
||||||
- [ ] content
|
- [ ] content
|
||||||
- [ ] description
|
- [ ] description
|
||||||
|
- [ ] c--dim and friends
|
||||||
- [ ] Re-evaluate form styles
|
- [ ] Re-evaluate form styles
|
||||||
- [ ] theme-color-light is used only for buttons
|
- [ ] theme-color-light is used only for buttons
|
||||||
- [x] center-layout vs. margin-center
|
- [x] center-layout vs. margin-center
|
||||||
|
|
Reference in New Issue