Add live preview of project card stuff

This commit is contained in:
Ben Visness 2024-07-02 22:11:41 -05:00
parent 51ad8d03d4
commit 22c70cda8e
7 changed files with 118 additions and 39 deletions

View File

@ -1,4 +1,7 @@
function ImageSelector(form, maxFileSize, container, defaultImageUrl) {
function ImageSelector(form, maxFileSize, container, {
defaultImageUrl = "",
onUpdate = (url) => {},
} = {}) {
this.form = form;
this.maxFileSize = maxFileSize;
this.fileInput = container.querySelector(".imginput");
@ -11,12 +14,13 @@ function ImageSelector(form, maxFileSize, container, defaultImageUrl) {
this.originalImageUrl = this.imageEl.getAttribute("data-imginput-original");
this.originalImageFilename = this.imageEl.getAttribute("data-imginput-original-filename");
this.currentImageUrl = this.originalImageUrl;
this.defaultImageUrl = defaultImageUrl || "";
this.defaultImageUrl = defaultImageUrl;
this.onUpdate = onUpdate;
this.fileInput.value = "";
this.removeImageInput.value = "";
this.setImageUrl(this.originalImageUrl);
this.setImageUrl(this.originalImageUrl, true);
this.updatePreview();
this.fileInput.addEventListener("change", function(ev) {
@ -79,7 +83,7 @@ ImageSelector.prototype.setError = function(error) {
this.fileInput.reportValidity();
}
ImageSelector.prototype.setImageUrl = function(url) {
ImageSelector.prototype.setImageUrl = function(url, initial = false) {
this.currentImageUrl = url;
this.imageEl.src = url;
if (url.length > 0) {
@ -87,6 +91,10 @@ ImageSelector.prototype.setImageUrl = function(url) {
} else {
this.imageEl.style.display = "none";
}
this.url = url;
if (!initial) {
this.onUpdate(url);
}
};
ImageSelector.prototype.updatePreview = function(file) {

View File

@ -8501,6 +8501,17 @@ span.icon-rss::before {
content: "\200b";
padding: var(--spacing-2) 0;
}
.project-homepage-card {
width: 100%;
max-width: var(--site-width-narrow);
padding: var(--spacing-3);
background-color: var(--c-transparent-background);
--link-color: var(--color);
display: flex;
gap: var(--spacing-3);
overflow: hidden;
margin-top: -4rem;
}
/* src/rawdata/scss/showcase.css */
.showcase-item .gradient {

View File

@ -95,3 +95,16 @@
padding: var(--spacing-2) 0;
}
}
.project-homepage-card {
width: 100%;
max-width: var(--site-width-narrow);
padding: var(--spacing-3);
background-color: var(--c-transparent-background);
--link-color: var(--color);
display: flex;
gap: var(--spacing-3);
overflow: hidden;
margin-top: -4rem;
}

View File

@ -7,7 +7,7 @@
{{ $filename := or (and .Asset .Asset.Filename) "" }}
<img class="w4 flex-shrink-0" data-imginput-original="{{ $url }}" data-imginput-original-filename="{{ $filename }}" src="{{ $url }}" />
<div class="w1 flex-grow-1 flex flex-column g1">
<div class="flex f6">
<div class="flex f6 g2">
<a href="javascript:;" class="imginput-reset-link">Reset</a>
<a href="javascript:;" class="imginput-remove-link">Remove</a>
</div>

View File

@ -157,26 +157,22 @@
{{ else }}
<div class="pv4 f6 tc">You are not following anything. Follow users and projects to see their posts here.</div>
{{ end }}
TODO: READ MORE LINK
</div>
{{ end }}
<div data-tab="featured" class="timeline">
{{ range .FeaturedItems }}
{{ template "timeline_item.html" . }}
{{ end }}
TODO: READ MORE LINK
</div>
<div data-tab="recent" class="timeline">
{{ range .RecentItems }}
{{ template "timeline_item.html" . }}
{{ end }}
TODO: READ MORE LINK
</div>
<div data-tab="news" class="timeline">
{{ range .NewsItems }}
{{ template "timeline_item.html" . }}
{{ end }}
TODO: READ MORE LINK
</div>
</div>
</div>

View File

@ -49,12 +49,24 @@
<div class="flex flex-column g3">
<div class="input-group">
<label>Project Title*</label>
<input required type="text" name="project_name" maxlength="255" class="textbox" value="{{ .ProjectSettings.Name }}">
<input
required
type="text"
id="project_name" name="project_name"
maxlength="255"
value="{{ .ProjectSettings.Name }}"
oninput="updateCardPreview()"
>
</div>
<div class="input-group">
<label>Short Description*</label>
<textarea id="description" required maxlength="140" name="shortdesc">
<textarea
required
id="description" name="shortdesc"
maxlength="140"
oninput="updateCardPreview()"
>
{{- .ProjectSettings.Blurb -}}
</textarea>
<div class="f6">Plaintext only. No links or markdown.</div>
@ -215,6 +227,13 @@
<!-- need href and title -->
<a data-tmpl="root" class="ph2 flex"><!-- need icon --></a>
</template>
<template id="owner_preview">
<div class="flex g1 items-center b">
<img data-tmpl="avatar" class="avatar avatar-user avatar-small"><!-- need src -->
<span data-tmpl="name"><!-- need name --></span>
</div>
</template>
<div hidden>
{{ range .AllLogos }}
<span id="link-icon-{{ .Name }}">{{ .Svg }}</span>
@ -226,6 +245,7 @@
We don't have a good story for sharing templates between Go and JS.
-->
<div class="flex flex-column items-center">
<!-- Header image / links -->
<div id="header_img_preview" class="project-header-img"><!-- Needs background-image -->
<div class="flex justify-end pa3">
@ -236,7 +256,32 @@
</div>
</div>
<!-- Card -->
<div class="project-homepage-card">
<div id="logo_preview" class="flex-shrink-0 flex">
<img class="project-card-logo" alt="Project Logo">
</div>
<div class="details flex-grow-1">
<h3 id="name_preview" class="b mb2 f4"></h3>
<div id="blurb_preview" class="blurb"></div>
<div id="owners_preview_container">
<hr class="mv3">
<div id="owners_preview" class="flex flex-wrap g2">
<!-- TODO(redesign): Actually preview owners -->
<div class="flex g1 items-center b">
<div class="avatar avatar-user avatar-small"></div>
<span>Example User</span>
</div>
</div>
</div>
<!-- TODO(redesign): Preview badges -->
</div>
</div>
</div>
<!-- Long description preview -->
<h3 class="pt4 f4">About {{ .Project.Name }}</h3>
<hr class="mv3">
<div id="desc_preview" class="w-100 post-content"></div>
</div>
</div>
@ -247,14 +292,6 @@
let projectForm = document.querySelector("#project_form");
projectForm.addEventListener("invalid", function(ev) {
switchToTabOfElement(document.body, ev.target);
}, true);
function gotoTab(tabName) {
switchTab(document.body, tabName);
}
//////////
// Tags //
//////////
@ -302,6 +339,7 @@
let ownersError = document.querySelector("#owners_error");
let ownerList = document.querySelector("#owner_list");
let ownerTemplate = makeTemplateCloner("owner_row");
let ownerPreviewTemplate = makeTemplateCloner("owner_preview");
addOwnerInput.addEventListener("keypress", function(ev) {
if (ev.which == 13) {
@ -394,38 +432,52 @@
updateAddOwnerStyles();
});
/////////////////////
// Logo management //
/////////////////////
//////////////////////////////
// Logo / header management //
//////////////////////////////
const logoMaxFileSize = {{ .LogoMaxFileSize }};
const headerMaxFileSize = {{ .HeaderMaxFileSize }};
const logoSelector = new ImageSelector(
document.querySelector("#project_form"),
logoMaxFileSize,
document.querySelector(".light_logo")
document.querySelector(".light_logo"),
{
onUpdate() {
updateCardPreview();
},
},
);
function openLogoSelector(e) {
e.preventDefault();
logoSelector.openFileInput();
}
///////////////////////
// Header management //
///////////////////////
const headerMaxFileSize = {{ .HeaderMaxFileSize }};
const headerSelector = new ImageSelector(
document.querySelector("#project_form"),
headerMaxFileSize,
document.querySelector(".header_image")
document.querySelector(".header_image"),
{
onUpdate() {
updateCardPreview();
},
},
);
function openHeaderSelector(e) {
e.preventDefault();
headerSelector.openFileInput();
}
function updateCardPreview() {
document.querySelector("#logo_preview").hidden = !logoSelector.url;
document.querySelector("#logo_preview img").src = logoSelector.url;
document.querySelector("#header_img_preview").style.backgroundImage = `url(${headerSelector.url})`;
document.querySelector("#name_preview").innerText = document.querySelector("#project_name").value;
document.querySelector("#blurb_preview").innerText = document.querySelector("#description").value;
}
updateCardPreview();
//////////////////
// Asset upload //
//////////////////

View File

@ -14,7 +14,7 @@
<div class="flex justify-between pa3">
<div class="flex g3">
{{ if .CanEdit }}
<div class="bg-transparent flex">
<div class="project-links">
<a class="ph3 pv2 flex items-center" href="{{ .EditUrl }}"><span class="mr2 flex items-center">{{ svg "edit-line" }}</span>Edit Project</a>
</div>
{{ end }}
@ -37,7 +37,7 @@
</div>
</div>
</div>
<div class="w-100 mw-site-narrow pa3 bg-transparent link-normal flex g3 overflow-hidden" style="margin-top: -4rem">
<div class="project-homepage-card">
{{ if .Project.Logo }}
<a class="flex-shrink-0 flex" href="{{ .Project.Url }}">
<img class="project-card-logo" src="{{ .Project.Logo }}" alt="Project Logo">
@ -127,7 +127,6 @@
{{ range .RecentActivity }}
{{ template "timeline_item.html" . }}
{{ end }}
TODO: READ MORE LINK
</div>
</div>
</div>