Add live preview of project card stuff
This commit is contained in:
parent
51ad8d03d4
commit
22c70cda8e
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -94,4 +94,17 @@
|
|||
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;
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,17 +245,43 @@
|
|||
We don't have a good story for sharing templates between Go and JS.
|
||||
-->
|
||||
|
||||
<!-- Header image / links -->
|
||||
<div id="header_img_preview" class="project-header-img"><!-- Needs background-image -->
|
||||
<div class="flex justify-end pa3">
|
||||
<div class="flex g3">
|
||||
<div id="primary_links_preview" class="project-links hide-if-empty"></div>
|
||||
<div id="secondary_links_preview" class="project-links ph1 hide-if-empty"></div>
|
||||
<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">
|
||||
<div class="flex g3">
|
||||
<div id="primary_links_preview" class="project-links hide-if-empty"></div>
|
||||
<div id="secondary_links_preview" class="project-links ph1 hide-if-empty"></div>
|
||||
</div>
|
||||
</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 //
|
||||
//////////////////
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue