bellini/ts_catalog/elements/bellini-articlebox.ts

378 lines
11 KiB
TypeScript
Raw Normal View History

2025-02-03 11:31:40 +01:00
import {
DeesElement,
property,
state,
html,
customElement,
type TemplateResult,
cssManager,
css
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
import { ExtendedDate } from '@push.rocks/smarttime';
import * as belliniApi from '@bellini/api';
import '@design.estate/dees-catalog';
@customElement('bellini-articlebox')
export class BellliniArticlebox extends DeesElement {
@property({type: Object})
public selectedArticle: belliniApi.IBelliniClientState['articles'][0];
public static styles = [
cssManager.defaultStyles,
css`
#articlebox {
position: realtive;
transition: all 0.3s;
background: ${cssManager.bdTheme('#fafafa', '#111')};
border-radius: 8px;
overflow: hidden;
opacity: 0;
width: 100%;
box-shadow: 0px 0px 5px ${cssManager.bdTheme('rgba(0, 0, 0, 0.2)', 'rgba(0, 0, 0, 0.5)')};
pointer-events: none;
}
#articlebox.show {
opacity: 1;
pointer-events: all;
}
#articlebox #articleActions {
position: relative;
border-top: 1px solid ${cssManager.bdTheme('#fafafa', '#333333')};
z-index: 10;
height: 30px;
background: ${cssManager.bdTheme('#fafafa', '#252525')};
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
display: grid;
grid-template-columns: 40px auto 30px 30px 40px;
}
#articlebox #articleActions .articleAction {
transition: all 0.1s;
box-sizing: border-box;
padding-top: 7px;
padding-left: 7px;
position: relative;
height: 30px;
width: 30px;
cursor: pointer;
color: ${cssManager.bdTheme('#333', '#aaa')};
}
#articlebox #articleActions .articleAction:hover {
background: ${cssManager.bdTheme('#CCC', '#111')};
color: ${cssManager.bdTheme('#000000', '#ffffff')};
}
#articlebox #articleActions .articleAction:first-child {
margin-left: 10px;
}
#articlebox #articleFeaturedImage {
z-index: 9;
transition: all 0.1s;
bottom: 0px;
transition: all 0.1s;
position: relative;
width: 100%;
height: 350px;
}
#articlebox #articleFeaturedImage img {
width: 100%;
height: 100%;
object-fit: cover;
}
#articlebox #articleFeaturedImage:after {
transition: all 0.1s;
margin-top: 0px;
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
box-shadow: inset 0px 0px 150px rgba(0, 0, 0, 0.9);
}
#articlebox #articleHeading {
}
#articlebox #articleContent {
color: ${cssManager.bdTheme('#333', '#ccc')};
padding: 40px 80px;
font-size: 16px;
line-height: 1.4em;
}
#articlebox #articleContent p:first-child:first-letter {
color: #e4002b;
float: left;
font-family: Georgia;
font-size: 56px;
line-height: 44px;
padding-right: 8px;
padding-top: 8px;
}
#articlebox #articleContent figure {
width: 100%;
margin: 0px;
}
#articlebox #articleContent figure img {
transition: all 0.1s;
width: 100%;
height: 200px;
object-fit: cover;
overflow: hidden;
border-radius: 3px;
}
#articlebox #articleContent figure figcaption {
display: none;
}
#articlebox #articleContent figure img:hover {
}
#articlebox #articleMeta {
margin-left: 60px;
position: relative;
z-index: 10;
margin-top: -116px;
}
#articlebox #articleMeta #articleTimestamp {
padding: 10px 20px;
background: ${cssManager.bdTheme('rgba(100, 100, 100, 0.7)', 'rgba(20, 20, 20, 0.9)')};
color: ${cssManager.bdTheme('#fff', '#aaa')};
display: table;
font-size: 16px;
font-weight: 100;
font-family: 'Roboto Mono', monospace;
}
#articlebox #articleMeta #articleTitle {
color: ${cssManager.bdTheme('#333', '#eee')};
padding: 20px;
background: ${cssManager.bdTheme('rgba(250, 250, 250, 0.85)', 'rgba(0, 0, 0, 0.8)')};
display: table;
font-size: 30px;
font-family: 'Roboto Slab';
font-weight: 400;
}
#articlebox #articleMeta #articleAuthor {
padding: 10px 20px;
background: ${cssManager.bdTheme('rgba(210, 210, 210, 0.7)', 'rgba(30, 30, 30, 0.7)')};
color: ${cssManager.bdTheme('#333', '#ccc')};
display: table;
font-size: 14px;
font-weight: 300;
font-family: 'Roboto Mono', monospace;
}
#articlebox #articleMeta #articleAuthor #by {
display: inline-block;
color: ${cssManager.bdTheme('#444', '#aaa')};
line-height: 14px;
font-size: 12px;
padding-right: 5px;
}
#articlebox #articleMeta #metaDeco {
position: absolute;
width: 20px;
height: 260px;
top: -4px;
left: -10px;
--bg-color: ${cssManager.bdTheme('#00000060', '#ffffff60')};
--dot-color: #ffffff00;
--dot-size: 1px;
--dot-space: 6px;
background: linear-gradient(45deg, var(--bg-color) 1px, var(--dot-color) 2px) top left;
background-size: var(--dot-space) var(--dot-space);
}
#articlebox #articleContent {
max-width: 700px;
font-size: 18px;
line-height: 1.6em;
}
#articlebox #articleContent h2 {
margin-top: 45px;
}
#articlebox #articleContent ul {
margin-left: 0px;
padding-left: 20px;
list-style: none;
}
#articlebox #articleContent a {
font-style: italic;
text-decoration: none;
color: #999;
}
#articlebox #articleContent p {
margin-bottom: 2.3em;
}
#articlebox #articleContent ul li::before {
content: '•';
color: red;
display: inline-block;
width: 1em;
margin-left: -1em;
}
#articlebox #articleContent blockquote {
position: relative;
background: ${cssManager.bdTheme('#ffffff', '#222')};
border-left: 2px solid #e4002b;
border-top: 1px solid ${cssManager.bdTheme('#fff', '#333')};
border-radius: 3px;
padding: 20px;
margin: 0px;
text-align: left;
font-size: 16px;
font-style: italic;
font-family: 'Roboto Mono', monospace;
box-shadow: ${cssManager.bdTheme('0px 0px 5px rgba(0,0,0,0.2)', 'none')};
}
#articlebox #articleContent figure {
width: 100%;
margin-bottom: 40px;
box-sizing: border-box;
padding: 10px 10px 2px 10px;
border-radius: 3px;
background: #252525;
}
#articlebox #articleContent iframe {
width: 100%;
}
#articlebox #articleFooter {
position: relative;
border-top: 1px solid ${cssManager.bdTheme('#CCC', '#333333')};
z-index: 10;
height: 30px;
background: ${cssManager.bdTheme('#fafafa', '#151515')};
box-shadow: 0px 0px 5px ${cssManager.bdTheme('rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.5)')};
display: grid;
font-family: 'Roboto Mono', monospace;
font-size: 12px;
text-align: center;
line-height: 30px;
color: ${cssManager.bdTheme('#333', '#ccc')};
}
${cssManager.cssForPhablet(css`
#articlebox {
margin-right: -20px;
margin-left: -20px;
width: calc(100% + 40px);
border-radius: 0px;
}
#articlebox #articleMeta {
margin-left: 0px;
}
#articlebox #articleMeta #metaDeco {
height: 240px;
}
#articlebox #articleContent {
padding: 22px 20px;
}
`)}
`
]
public render(): TemplateResult {
return html`
<style>
</style>
<div id="articlebox" class="belliniRelevantContent">
<div id="articleActions">
<div
class="articleAction"
@click="${async () => {
const domtoolsInstance = await this.domtoolsPromise;
domtoolsInstance.router.pushUrl('/');
}}"
>
<dees-icon iconName="keyboard_backspace"></dees-icon>
</div>
<div class="spacer"></div>
<div class="articleAction">
<dees-icon iconName="comment"></dees-icon>
</div>
<div class="articleAction">
<dees-icon iconName="share"></dees-icon>
</div>
<div
class="articleAction"
@click="${async () => {
const domtoolsInstance = await this.domtoolsPromise;
domtoolsInstance.router.pushUrl('/');
}}"
>
<dees-icon iconName="close"></dees-icon>
</div>
</div>
<div id="articleFeaturedImage">
<img src="${this.selectedArticle.featuredImageUrl}" />
</div>
<div id="articleMeta">
<div id="articleTimestamp">
${(() => {
const extendedDate = new ExtendedDate(this.selectedArticle.timestamp);
let returnString = extendedDate.format('YYYY-MM-DD - HH:mm');
if (extendedDate.isToday()) {
returnString += ' (Today)';
}
return returnString;
})()}
</div>
<div id="articleTitle">${this.selectedArticle.title}</div>
<div id="articleAuthor">
<div id="by">by</div>
${this.selectedArticle.author.name}
</div>
<div id="metaDeco"></div>
</div>
<div id="articleContent"></div>
<div id="articleFooter">... words | ... readability score | ... comments | ... views</div>
</div>
`;
}
public async updated() {
const articleContent = this.shadowRoot.querySelector('#articleContent');
articleContent.innerHTML = this.selectedArticle.htmlArticle;
}
public async show(boolArg: boolean) {
const articlebox = this.shadowRoot.querySelector('#articlebox');
if (boolArg) {
articlebox.classList.add('show')
} else {
articlebox.classList.remove('show');
}
}
}