Compare commits
4 commits
aab735bd39
...
cd4b3a9410
Author | SHA1 | Date | |
---|---|---|---|
|
cd4b3a9410 | ||
|
6ee7597805 | ||
|
662c461c94 | ||
|
ec6b10c1f2 |
5 changed files with 2232 additions and 211 deletions
214
bookmarklet.cjs
214
bookmarklet.cjs
|
@ -1,68 +1,152 @@
|
|||
let trpcState = JSON.parse(document.getElementById("trpc-dehydrated-state").innerText);
|
||||
let postData = trpcState.queries.find((q) => q.queryKey[0].includes("singlePost")).state.data.post;
|
||||
let postElement = document.createElement("cohost-post");
|
||||
postElement.setAttribute("avatarSrc", postData.postingProject.avatarURL);
|
||||
postElement.setAttribute("avatarShape", postData.postingProject.avatarShape);
|
||||
postElement.setAttribute("displayName", postData.postingProject.displayName);
|
||||
postElement.setAttribute("handle", postData.postingProject.handle);
|
||||
postElement.setAttribute("permalink", postData.singlePostPageUrl);
|
||||
postElement.setAttribute("publishedAt", postData.publishedAt);
|
||||
if (postData.headline) {
|
||||
postElement.setAttribute("singlePostHeadline", postData.headline);
|
||||
}
|
||||
postElement.setAttribute("tags", postData.tags.join(","));
|
||||
|
||||
if (postData.shareTree && postData.shareTree.length) {
|
||||
postElement.setAttribute("sharedItems", "");
|
||||
let sharedFrom = postData.shareTree[postData.shareTree.length - 1];
|
||||
postElement.setAttribute("sharedAvatarSrc", sharedFrom.postingProject.avatarURL);
|
||||
postElement.setAttribute("sharedAvatarShape", sharedFrom.postingProject.avatarShape);
|
||||
postElement.setAttribute("sharedDisplayName", sharedFrom.postingProject.displayName);
|
||||
postElement.setAttribute("sharedHandle", sharedFrom.postingProject.handle);
|
||||
|
||||
let shareTree = [...postData.shareTree, postData];
|
||||
for (sharedPost of shareTree) {
|
||||
if (sharedPost.transparentShareOfPostId !== null) {
|
||||
continue;
|
||||
(async () => {
|
||||
const COHOST_CDN_BASE = "https://staging.cohostcdn.org/";
|
||||
const COHOST_STATIC_BASE = "https://cohost.org/static/";
|
||||
const CORS_PROXY_BASE = "https://cohost-web-component.meow.garden/";
|
||||
const OUTPUT_DIV_ID = "cohost-wc-bookmarklet-output";
|
||||
const MEDIA_FLAG_DIV_ID = "cohost-wc-bookmarklet-media-flag";
|
||||
const AUDIO_PLAYER_FLAG_DIV_ID = "cohost-wc-audio-player-flag";
|
||||
async function maybeConvertToDataUri(imageUrl, shouldConvert) {
|
||||
if (!shouldConvert) { return imageUrl; }
|
||||
let proxyUrl;
|
||||
if (imageUrl.startsWith(COHOST_CDN_BASE)) {
|
||||
proxyUrl = imageUrl.replace(COHOST_CDN_BASE, CORS_PROXY_BASE + "cohostcdn-cors-proxy/");
|
||||
if (imageUrl.includes("/avatar/")) {
|
||||
proxyUrl += "?dpr=2&width=32&height=32&fit=cover&auto=webp";
|
||||
}
|
||||
} else if (imageUrl.startsWith(COHOST_STATIC_BASE)) {
|
||||
proxyUrl = imageUrl.replace(COHOST_STATIC_BASE, CORS_PROXY_BASE + "cohost-static-cors-proxy/");
|
||||
} else {
|
||||
return imageUrl;
|
||||
}
|
||||
let sharedElement = document.createElement("cohost-shared-item");
|
||||
sharedElement.setAttribute("avatarSrc", sharedPost.postingProject.avatarURL);
|
||||
sharedElement.setAttribute("avatarShape", sharedPost.postingProject.avatarShape);
|
||||
sharedElement.setAttribute("displayName", sharedPost.postingProject.displayName);
|
||||
sharedElement.setAttribute("handle", sharedPost.postingProject.handle);
|
||||
if (sharedPost.headline) {
|
||||
sharedElement.setAttribute("headline", sharedPost.headline);
|
||||
}
|
||||
sharedElement.setAttribute("permalink", sharedPost.singlePostPageUrl);
|
||||
sharedElement.setAttribute("publishedAt", sharedPost.publishedAt);
|
||||
sharedElement.setAttribute("tags", sharedPost.tags.join(","));
|
||||
let sharedIdElement = document.getElementById(`post-${sharedPost.postId}`);
|
||||
if (sharedIdElement) {
|
||||
sharedElement.innerHTML = sharedIdElement.parentElement.querySelector("[data-post-body]").innerHTML;
|
||||
}
|
||||
postElement.appendChild(sharedElement);
|
||||
let response = await fetch(proxyUrl);
|
||||
let blob = await response.blob();
|
||||
return new Promise((resolve) => {
|
||||
let reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let postIdElement = document.getElementById(`post-${postData.postId}`);
|
||||
if (postIdElement) {
|
||||
postElement.innerHTML = document.getElementById(`post-${postData.postId}`).parentElement.querySelector("[data-post-body]").innerHTML;
|
||||
|
||||
async function assembleWebComponent(dataUris) {
|
||||
let trpcState = JSON.parse(document.getElementById("trpc-dehydrated-state").innerText);
|
||||
let postData = trpcState.queries.find((q) => q.queryKey[0].includes("singlePost")).state.data.post;
|
||||
let postElement = document.createElement("cohost-post");
|
||||
postElement.setAttribute("avatarSrc", await maybeConvertToDataUri(postData.postingProject.avatarURL, dataUris));
|
||||
postElement.setAttribute("avatarShape", postData.postingProject.avatarShape);
|
||||
postElement.setAttribute("comments", postData.numComments);
|
||||
postElement.setAttribute("displayName", postData.postingProject.displayName);
|
||||
postElement.setAttribute("handle", postData.postingProject.handle);
|
||||
postElement.setAttribute("permalink", postData.singlePostPageUrl);
|
||||
if (postData.publishedAt) {
|
||||
postElement.setAttribute("publishedAt", postData.publishedAt);
|
||||
}
|
||||
if (postData.numSharedComments) {
|
||||
postElement.setAttribute("sharedComments", postData.numSharedComments);
|
||||
}
|
||||
if (postData.headline) {
|
||||
postElement.setAttribute("singlePostHeadline", postData.headline);
|
||||
}
|
||||
postElement.setAttribute("tags", postData.tags.join(","));
|
||||
|
||||
if (postData.shareTree && postData.shareTree.length) {
|
||||
postElement.setAttribute("sharedItems", "");
|
||||
let sharedFrom = postData.shareTree[postData.shareTree.length - 1];
|
||||
postElement.setAttribute("sharedAvatarSrc", await maybeConvertToDataUri(sharedFrom.postingProject.avatarURL, dataUris));
|
||||
postElement.setAttribute("sharedAvatarShape", sharedFrom.postingProject.avatarShape);
|
||||
postElement.setAttribute("sharedDisplayName", sharedFrom.postingProject.displayName);
|
||||
postElement.setAttribute("sharedHandle", sharedFrom.postingProject.handle);
|
||||
|
||||
let shareTree = [...postData.shareTree, postData];
|
||||
for (sharedPost of shareTree) {
|
||||
if (sharedPost.transparentShareOfPostId !== null) {
|
||||
continue;
|
||||
}
|
||||
let sharedElement = document.createElement("cohost-shared-item");
|
||||
sharedElement.setAttribute("avatarSrc", await maybeConvertToDataUri(sharedPost.postingProject.avatarURL, dataUris));
|
||||
sharedElement.setAttribute("avatarShape", sharedPost.postingProject.avatarShape);
|
||||
sharedElement.setAttribute("displayName", sharedPost.postingProject.displayName);
|
||||
sharedElement.setAttribute("handle", sharedPost.postingProject.handle);
|
||||
if (sharedPost.headline) {
|
||||
sharedElement.setAttribute("headline", sharedPost.headline);
|
||||
}
|
||||
sharedElement.setAttribute("permalink", sharedPost.singlePostPageUrl);
|
||||
if (sharedPost.publishedAt) {
|
||||
sharedElement.setAttribute("publishedAt", sharedPost.publishedAt);
|
||||
}
|
||||
sharedElement.setAttribute("tags", sharedPost.tags.join(","));
|
||||
let sharedIdElement = document.getElementById(`post-${sharedPost.postId}`);
|
||||
if (sharedIdElement) {
|
||||
let sharedPostBody = sharedIdElement.parentElement.querySelector("[data-post-body]");
|
||||
if (sharedPostBody) {
|
||||
sharedElement.innerHTML = sharedPostBody.innerHTML;
|
||||
}
|
||||
}
|
||||
postElement.appendChild(sharedElement);
|
||||
}
|
||||
} else {
|
||||
let postIdElement = document.getElementById(`post-${postData.postId}`);
|
||||
if (postIdElement) {
|
||||
let postBody = document.getElementById(`post-${postData.postId}`).parentElement.querySelector("[data-post-body]");
|
||||
if (postBody) {
|
||||
postElement.innerHTML = postBody.innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mediaFlag = false;
|
||||
let audioPlayerFlag = false;
|
||||
for (const mediaElement of postElement.querySelectorAll('img, audio')) {
|
||||
if (mediaElement.tagName == 'AUDIO') { audioPlayerFlag = true; }
|
||||
let src = mediaElement.getAttribute("src");
|
||||
if (dataUris && src.startsWith(COHOST_STATIC_BASE)) {
|
||||
mediaElement.setAttribute('src', await maybeConvertToDataUri(src, true));
|
||||
} else if (src.startsWith("https://cohost.org/") || src.startsWith(COHOST_CDN_BASE)) {
|
||||
mediaFlag = true;
|
||||
}
|
||||
}
|
||||
return {
|
||||
postElement,
|
||||
mediaFlag,
|
||||
audioPlayerFlag,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let outputContainer = document.createElement("div");
|
||||
outputContainer.id = "cohost-wc-bookmarklet-output"
|
||||
outputContainer.style = "position: fixed; bottom: 0.5rem; left: 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.875rem; z-index: 100";
|
||||
|
||||
let outputTextarea = document.createElement("textarea");
|
||||
outputTextarea.value = postElement.outerHTML;
|
||||
outputTextarea.rows = 5;
|
||||
outputTextarea.cols = 20;
|
||||
outputTextarea.style = "font-size: inherit; line-height: 1.4";
|
||||
outputContainer.append(outputTextarea);
|
||||
|
||||
let outputDismissButton = document.createElement("button");
|
||||
outputDismissButton.innerText = "dismiss";
|
||||
outputDismissButton.onclick = function() { outputContainer.remove(); }
|
||||
outputContainer.append(outputDismissButton);
|
||||
|
||||
document.body.append(outputContainer);
|
||||
async function renderOutput(webComponent, dataUris) {
|
||||
let template = document.createElement('template');
|
||||
template.innerHTML = `<div id="${OUTPUT_DIV_ID}" class="fixed bottom-0 p-2 flex flex-col items-center gap-2 font-sm bg-background co-themed-box border rounded-lg">
|
||||
<textarea rows="5" cols="35" style="font-size: inherit; line-height: 1.4"></textarea>
|
||||
<div id="${MEDIA_FLAG_DIV_ID}" class="co-info-box co-info text-sm mx-auto w-full rounded-lg p-3">
|
||||
Post <b>still</b> contains media hosted on cohost.<br />Consider rehosting any images or audio files on your website.
|
||||
</div>
|
||||
<div id="${AUDIO_PLAYER_FLAG_DIV_ID}" class="co-info-box co-info text-sm mx-auto w-full rounded-lg p-3">
|
||||
cohost's audio player doesn't function correctly (yet).
|
||||
</div>
|
||||
<div class="flex flex-row gap-1">
|
||||
<button id="cohost-wc-data-uris-button" class="rounded-lg bg-cherry py-2 px-4 text-sm font-bold text-notWhite hover:bg-cherry-600 active:bg-cherry-700">Convert avatars and custom emoji to data URIs</button>
|
||||
<button id="cohost-wc-dismiss-button" class="rounded-lg bg-cherry py-2 px-4 text-sm font-bold text-notWhite hover:bg-cherry-600 active:bg-cherry-700">dismiss</button>
|
||||
</div>
|
||||
</div>`;
|
||||
template.content.querySelector('textarea').value = webComponent.postElement.outerHTML;
|
||||
if (!webComponent.mediaFlag) {
|
||||
template.content.querySelector(`#${MEDIA_FLAG_DIV_ID}`).remove();
|
||||
} else if (!dataUris) {
|
||||
template.content.querySelector(`#${MEDIA_FLAG_DIV_ID} b`).remove();
|
||||
}
|
||||
if (!webComponent.audioPlayerFlag) {
|
||||
template.content.querySelector(`#${AUDIO_PLAYER_FLAG_DIV_ID}`).remove();
|
||||
}
|
||||
template.content.querySelector("#cohost-wc-data-uris-button").onclick = async () => {
|
||||
let webComponent = await assembleWebComponent(true);
|
||||
renderOutput(webComponent, true);
|
||||
}
|
||||
template.content.querySelector("#cohost-wc-dismiss-button").onclick = function() {
|
||||
document.querySelector(`#${OUTPUT_DIV_ID}`).remove();
|
||||
}
|
||||
let existingOutput = document.querySelector(`#${OUTPUT_DIV_ID}`);
|
||||
if (existingOutput) {
|
||||
existingOutput.replaceWith(template.content);
|
||||
} else {
|
||||
document.body.append(template.content);
|
||||
}
|
||||
}
|
||||
let webComponent = await assembleWebComponent(false);
|
||||
renderOutput(webComponent, false);
|
||||
})();
|
376
cohost-wc.css
376
cohost-wc.css
|
@ -142,7 +142,129 @@ cohost-post p,
|
|||
cohost-post pre {
|
||||
margin: 0;
|
||||
}
|
||||
.prose {
|
||||
cohost-post img,
|
||||
cohost-post video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
cohost-post img,
|
||||
cohost-post svg,
|
||||
cohost-post video,
|
||||
cohost-post canvas,
|
||||
cohost-post audio,
|
||||
cohost-post iframe,
|
||||
cohost-post embed,
|
||||
cohost-post object {
|
||||
display: block;
|
||||
}
|
||||
cohost-post button,
|
||||
cohost-post input,
|
||||
cohost-post optgroup,
|
||||
cohost-post select,
|
||||
cohost-post textarea {
|
||||
font-family: inherit;
|
||||
font-feature-settings: inherit;
|
||||
font-variation-settings: inherit;
|
||||
font-size: 100%;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
letter-spacing: inherit;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
cohost-post button,
|
||||
cohost-post select {
|
||||
text-transform: none;
|
||||
}
|
||||
cohost-post button,
|
||||
cohost-post [role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
cohost-post button,
|
||||
cohost-post input:where([type="button"]),
|
||||
cohost-post input:where([type="reset"]),
|
||||
cohost-post input:where([type="submit"]) {
|
||||
-webkit-appearance: button;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(code):not(
|
||||
:where([class~="not-prose"], [class~="not-prose"] *)
|
||||
)::after {
|
||||
content: "`";
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(code):not(
|
||||
:where([class~="not-prose"], [class~="not-prose"] *)
|
||||
)::before {
|
||||
content: "`";
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(code):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
|
||||
color: var(--tw-prose-code);
|
||||
font-weight: 600;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
cohost-post code,
|
||||
cohost-post kbd,
|
||||
cohost-post samp,
|
||||
cohost-post pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace;
|
||||
font-feature-settings: normal;
|
||||
font-variation-settings: normal;
|
||||
font-size: 1em;
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(pre):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
|
||||
color: var(--tw-prose-pre-code);
|
||||
background-color: var(--tw-prose-pre-bg);
|
||||
overflow-x: auto;
|
||||
font-weight: 400;
|
||||
font-size: 0.875em;
|
||||
line-height: 1.7142857;
|
||||
margin-top: 1.7142857em;
|
||||
margin-bottom: 1.7142857em;
|
||||
border-radius: 0.375rem;
|
||||
padding-top: 0.8571429em;
|
||||
padding-inline-end: 1.1428571em;
|
||||
padding-bottom: 0.8571429em;
|
||||
padding-inline-start: 1.1428571em;
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(pre code):not(
|
||||
:where([class~="not-prose"], [class~="not-prose"] *)
|
||||
)::after {
|
||||
content: none;
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(pre code):not(
|
||||
:where([class~="not-prose"], [class~="not-prose"] *)
|
||||
)::before {
|
||||
content: none;
|
||||
}
|
||||
cohost-post
|
||||
.prose
|
||||
:where(pre code):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
cohost-post .prose {
|
||||
color: light-dark(#191919, #fff9f2);
|
||||
--tw-prose-body: light-dark(#374151, #fff9f2);
|
||||
--tw-prose-headings: light-dark(#111827, #fff9f2);
|
||||
|
@ -236,6 +358,32 @@ cohost-post .co-embed {
|
|||
cohost-post .co-ui-text {
|
||||
color: light-dark(rgb(25 25 25), rgb(255 249 242));
|
||||
}
|
||||
cohost-post .mask {
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
}
|
||||
cohost-post .mask-squircle {
|
||||
-webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAwIDBDMjAgMCAwIDIwIDAgMTAwczIwIDEwMCAxMDAgMTAwIDEwMC0yMCAxMDAtMTAwUzE4MCAwIDEwMCAweiIvPjwvc3ZnPg==);
|
||||
mask-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAwIDBDMjAgMCAwIDIwIDAgMTAwczIwIDEwMCAxMDAgMTAwIDEwMC0yMCAxMDAtMTAwUzE4MCAwIDEwMCAweiIvPjwvc3ZnPg==);
|
||||
}
|
||||
cohost-post .mask-roundrect {
|
||||
border-radius: 12.5%;
|
||||
}
|
||||
cohost-post .mask-circle {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
cohost-post .co-embedded-ask {
|
||||
border-color: rgb(229 107 111);
|
||||
background-color: light-dark(rgb(255 249 242), rgb(25 25 25));
|
||||
color: light-dark(rgb(25 25 25), rgb(255 249 242));
|
||||
}
|
||||
cohost-post .co-attribution {
|
||||
color: light-dark(rgb(130 127 124), rgb(160 156 152));
|
||||
}
|
||||
|
||||
/* Hide interactive UI */
|
||||
cohost-post button.co-link-button {
|
||||
|
@ -244,31 +392,241 @@ cohost-post button.co-link-button {
|
|||
|
||||
/* Tailwind properties */
|
||||
|
||||
cohost-post .text-right {
|
||||
text-align: right;
|
||||
cohost-post .accent-mango {
|
||||
accent-color: #ffab5c;
|
||||
}
|
||||
cohost-post .p-3 {
|
||||
padding: 0.75rem;
|
||||
cohost-post .align-middle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
cohost-post .aspect-square {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
cohost-post .bg-cherry {
|
||||
background-color: rgb(131 37 79);
|
||||
}
|
||||
cohost-post .bg-notBlack {
|
||||
background-color: rgb(25 25 25);
|
||||
}
|
||||
cohost-post .border {
|
||||
border-width: 1px;
|
||||
}
|
||||
cohost-post .break-words {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
cohost-post .col-start-1 {
|
||||
grid-column-start: 1;
|
||||
}
|
||||
cohost-post .col-start-2 {
|
||||
grid-column-start: 2;
|
||||
}
|
||||
cohost-post .content-start {
|
||||
align-content: flex-start;
|
||||
}
|
||||
cohost-post .cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
cohost-post .flex {
|
||||
display: flex;
|
||||
}
|
||||
cohost-post .flex-1 {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
cohost-post .flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
cohost-post .flex-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
cohost-post .flex-initial {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
cohost-post .flex-nowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
cohost-post .flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
cohost-post .flex-shrink-0 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
cohost-post .font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
cohost-post .gap-x-3 {
|
||||
-moz-column-gap: 0.75rem;
|
||||
column-gap: 0.75rem;
|
||||
}
|
||||
cohost-post .gap-y-2 {
|
||||
row-gap: 0.5rem;
|
||||
}
|
||||
cohost-post .grid {
|
||||
display: grid;
|
||||
}
|
||||
cohost-post .grid-rows-\[2rem_1fr\] {
|
||||
grid-template-rows: 2rem 1fr;
|
||||
}
|
||||
cohost-post .grid-cols-\[2rem_1fr\] {
|
||||
grid-template-columns: 2rem 1fr;
|
||||
}
|
||||
cohost-post .h-6 {
|
||||
height: 1.5rem;
|
||||
}
|
||||
cohost-post .h-8 {
|
||||
height: 2rem;
|
||||
}
|
||||
cohost-post .h-9 {
|
||||
height: 2.25rem;
|
||||
}
|
||||
cohost-post .h-full {
|
||||
height: 100%;
|
||||
}
|
||||
cohost-post .hover\:underline:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
cohost-post .inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
cohost-post .items-center {
|
||||
align-items: center;
|
||||
}
|
||||
cohost-post .justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
cohost-post .leading-8 {
|
||||
line-height: 2rem;
|
||||
}
|
||||
cohost-post .m-0 {
|
||||
margin: 0;
|
||||
}
|
||||
cohost-post .m-3 {
|
||||
margin: 0.75rem;
|
||||
}
|
||||
cohost-post .m-auto {
|
||||
margin: auto;
|
||||
}
|
||||
cohost-post .mt-0 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
cohost-post .mx-1 {
|
||||
margin-left: 0.25rem;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
cohost-post .my-4 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
cohost-post .object-contain {
|
||||
-o-object-fit: contain;
|
||||
object-fit: contain;
|
||||
}
|
||||
cohost-post .object-cover {
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
cohost-post .overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
cohost-post .break-words {
|
||||
overflow-wrap: break-word;
|
||||
cohost-post .p-2 {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
cohost-post .p-3 {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
cohost-post .px-3 {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
cohost-post .relative {
|
||||
position: relative;
|
||||
}
|
||||
cohost-post .rounded-lg {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
cohost-post .row-start-1 {
|
||||
grid-row-start: 1;
|
||||
}
|
||||
cohost-post .sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
cohost-post .tabular-nums {
|
||||
--tw-numeric-spacing: tabular-nums;
|
||||
font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero)
|
||||
var(--tw-numeric-figure) var(--tw-numeric-spacing)
|
||||
var(--tw-numeric-fraction);
|
||||
}
|
||||
cohost-post .text-right {
|
||||
text-align: right;
|
||||
}
|
||||
cohost-post .text-xs {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
cohost-post .w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
cohost-post .w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
cohost-post .w-9 {
|
||||
width: 2.25rem;
|
||||
}
|
||||
cohost-post .w-\[76px\] {
|
||||
width: 76px;
|
||||
}
|
||||
cohost-post .w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* CSS variables */
|
||||
cohost-post {
|
||||
--color-notWhite: 255 249 242;
|
||||
--color-notBlack: 25 25 25;
|
||||
--color-cherry: 131 37 79;
|
||||
--color-strawberry: 229 107 111;
|
||||
--color-mango: 255 171 92;
|
||||
--color-longan: 255 216 168;
|
||||
--color-text: var(--color-notWhite);
|
||||
--color-bg-text: var(--color-notBlack);
|
||||
--color-foreground-100: 253 206 224;
|
||||
--color-foreground-200: 238 173 199;
|
||||
--color-foreground-300: 211 116 155;
|
||||
--color-foreground-400: 174 68 115;
|
||||
--color-foreground-500: 131 37 79;
|
||||
--color-foreground-600: 103 26 61;
|
||||
--color-foreground-700: 81 17 46;
|
||||
--color-foreground-800: 59 9 32;
|
||||
--color-foreground: var(--color-cherry);
|
||||
--color-secondary-200: 244 187 187;
|
||||
--color-secondary-300: 238 153 155;
|
||||
--color-secondary-400: 229 107 111;
|
||||
--color-secondary-600: 164 42 47;
|
||||
--color-secondary-700: 123 27 31;
|
||||
--color-secondary: var(--color-strawberry);
|
||||
--color-tertiary: var(--color-longan);
|
||||
--color-tertiary-200: 255 229 196;
|
||||
--color-tertiary-300: 255 216 168;
|
||||
--color-tertiary-400: 255 202 122;
|
||||
--color-tertiary-500: 183 133 61;
|
||||
--color-tertiary-600: 183 133 61;
|
||||
--color-tertiary-700: 132 94 38;
|
||||
--color-accent: var(--color-mango);
|
||||
--color-background: var(--color-notWhite);
|
||||
--color-sidebar-bg: var(--color-notWhite);
|
||||
--color-sidebar-text: var(--color-notBlack);
|
||||
--color-sidebar-accent: var(--color-cherry);
|
||||
--color-compose-button: var(--color-foreground);
|
||||
--color-compose-button-400: var(--color-foreground-400);
|
||||
--color-compose-button-600: var(--color-foreground-600);
|
||||
}
|
||||
|
||||
/* TODO: light */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
cohost-post {
|
||||
--color-notWhite: 255 249 242;
|
||||
|
@ -310,5 +668,7 @@ cohost-post .px-3 {
|
|||
--color-compose-button-400: var(--color-foreground-400);
|
||||
--color-compose-button-600: var(--color-foreground-600);
|
||||
--emoji-scale: 1.25em;
|
||||
--tw-border-opacity: 1;
|
||||
--tw-bg-opacity: 1;
|
||||
}
|
||||
}
|
||||
|
|
1820
package-lock.json
generated
1820
package-lock.json
generated
File diff suppressed because it is too large
Load diff
13
package.json
13
package.json
|
@ -14,19 +14,28 @@
|
|||
"lint:lit-analyzer": "lit-analyzer",
|
||||
"format": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --ignore-path ./.eslintignore --write",
|
||||
"serve": "concurrently \"tsc --watch\" \"wds --watch\"",
|
||||
"serve:prod": "MODE=prod npm run serve"
|
||||
"serve:prod": "MODE=prod npm run serve",
|
||||
"rollup": "rollup -c",
|
||||
"publish:dev": "rsync -avuz --delete build/ web@dev.xtil.net:/home/web/static/cohost-web-component.meow.garden/",
|
||||
"publish:prod": "rsync -avuz --delete build/ web@xtil.net:/home/web/static/cohost-web-component.meow.garden/"
|
||||
},
|
||||
"dependencies": {
|
||||
"lit": "^3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@web/dev-server": "^0.4.6",
|
||||
"@web/rollup-plugin-copy": "^0.5.1",
|
||||
"@web/rollup-plugin-html": "^2.3.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"concurrently": "^9.0.1",
|
||||
"eslint": "^9.10.0",
|
||||
"lit-analyzer": "^2.0.3",
|
||||
"prettier": "^3.3.3",
|
||||
"rollup": "^4.22.0",
|
||||
"rollup-plugin-summary": "^2.0.1",
|
||||
"typescript": "^5.6.2"
|
||||
},
|
||||
"customElements": "custom-elements.json"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,15 @@ function formatRelativeTime(date: Date) {
|
|||
const secondsPerMinute = 60;
|
||||
const minutesPerHour = 60;
|
||||
const hoursPerDay = 24;
|
||||
const daysPerMonth = 30; // JS date handling moment
|
||||
const daysPerMonth = 365.2425 / 12; // not how it works!
|
||||
const daysPerYear = 365.2425; // still not how it works!!
|
||||
const intervals = {
|
||||
year:
|
||||
millisecondsPerSecond *
|
||||
secondsPerMinute *
|
||||
minutesPerHour *
|
||||
hoursPerDay *
|
||||
daysPerYear,
|
||||
month:
|
||||
millisecondsPerSecond *
|
||||
secondsPerMinute *
|
||||
|
@ -379,6 +386,9 @@ export class CohostPost extends LitElement {
|
|||
@property({ type: Number })
|
||||
comments = 0;
|
||||
|
||||
@property({ type: Number })
|
||||
sharedComments = 0;
|
||||
|
||||
override render() {
|
||||
let displayTimestamp = undefined;
|
||||
let relativeTimestamp = undefined;
|
||||
|
@ -577,8 +587,13 @@ export class CohostPost extends LitElement {
|
|||
<a
|
||||
href="${ifDefined(this.permalink)}#comments"
|
||||
class="text-sm hover:underline"
|
||||
>${this.comments} comment${this.comments == 1 ? "" : "s"}</a
|
||||
>
|
||||
${this.comments}
|
||||
comment${this.comments == 1 ? "" : "s"}${when(
|
||||
this.sharedComments,
|
||||
() => html` + ${this.sharedComments} on shared posts`,
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<svg
|
||||
|
@ -749,5 +764,6 @@ export class CohostSharedItem extends LitElement {
|
|||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"cohost-post": CohostPost;
|
||||
"cohost-shared-item": CohostSharedItem;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue