mirror of https://github.com/vizality/vizality
start setting up addon listing pages
parent
f1a2225132
commit
786e4e1ae1
@ -1,33 +1,43 @@
|
||||
@use '@vizality' as vz;
|
||||
|
||||
@forward 'screenshots';
|
||||
|
||||
.vz-addon-listing {
|
||||
// &-banner-wrapper {
|
||||
// width: 100%;
|
||||
// position: relative;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// height: 600px;
|
||||
// z-index: 9999;
|
||||
// background-image: url(https://discord.com/assets/d03d90c….svg);
|
||||
// background-image: url(https://wallpaperaccess.com/full/2461288.jpg);
|
||||
// background-repeat: no-repeat;
|
||||
// background-position: center;
|
||||
// background-size: cover;
|
||||
// -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 70%);
|
||||
// }
|
||||
// &-top-card {
|
||||
// /* z-index: 8888888888; */
|
||||
// width: calc(100% - 80px);
|
||||
// background: var(--background-tertiary);
|
||||
// height: 300px;
|
||||
// margin: -200px 40px 0;
|
||||
// /* box-sizing: border-box; */
|
||||
// border-radius: 8px;
|
||||
// position: relative;
|
||||
// /* backdrop-filter: blur(10px); */
|
||||
// /* border: 1px solid var(--background-modifier-accent); */
|
||||
// margin-top: -150px;
|
||||
// z-index: 99999;
|
||||
// opacity: .9;
|
||||
// }
|
||||
height: 5000px;
|
||||
&-banner-background {
|
||||
width: calc(100% + var(--vz-dashboard-layout-padding-horizontal) * 2);
|
||||
height: 500px;
|
||||
position: relative;
|
||||
top: calc(var(--vz-dashboard-layout-padding-vertical) * -1);
|
||||
left: calc(var(--vz-dashboard-layout-padding-horizontal) * -1);
|
||||
background-image: url('/assets/d03d90cb6f12a7ea06274b278dfa4160.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-attachment: fixed;
|
||||
mask-image: linear-gradient(to top, transparent 0%, #000 70%);
|
||||
-webkit-mask-image: linear-gradient(to top, transparent 0%, #000 70%);
|
||||
background-position: center;
|
||||
flex: 0 0 auto;
|
||||
transition: opacity 0.5s, transform 0.5s;
|
||||
[vz-theme='light'] & {
|
||||
background-image: url('/assets/7b6ed225050df29a07cb5db712d35a73.svg');
|
||||
}
|
||||
&[vz-hidden] {
|
||||
opacity: 0;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
&-top-card {
|
||||
background: var(--background-tertiary);
|
||||
height: 200px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
margin-top: -80px;
|
||||
margin-bottom: 20px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
&-content {
|
||||
margin-top: 60px;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
import React, { memo, useState, useEffect } from 'react';
|
||||
// import ColorThief from 'colorthief/dist/color-thief.umd.js';
|
||||
|
||||
export default memo(props => {
|
||||
// const pie = async () => {
|
||||
// const colorThief = new ColorThief();
|
||||
// const img = new Image();
|
||||
// let poo;
|
||||
|
||||
// img.addEventListener('load', () => {
|
||||
// console.log('well');
|
||||
// poo = colorThief.getColor(img);
|
||||
// console.log(poo);
|
||||
// });
|
||||
|
||||
// img.crossOrigin = 'Anonymous';
|
||||
// img.src = 'vz-plugin://better-code-blocks/assets/icon.png';
|
||||
|
||||
// return poo;
|
||||
// };
|
||||
|
||||
// console.log(pie());
|
||||
return (
|
||||
<>
|
||||
<div className='vz-addon-page'>
|
||||
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
@ -0,0 +1,187 @@
|
||||
import { __TabBar, StickyElement, ImageCarouselModal, Image, Markdown } from '@vizality/components';
|
||||
import { Section } from '@vizality/components/dashboard';
|
||||
import React, { memo, useEffect, useState } from 'react';
|
||||
import { openModal } from '@vizality/modal';
|
||||
import { joinClassNames } from '@vizality/util/dom';
|
||||
import { toPlural } from '@vizality/util/string';
|
||||
import { useRouteMatch } from 'react-router';
|
||||
import { Messages } from '@vizality/i18n';
|
||||
|
||||
const AddonScreenshots = memo(({ addon }) => {
|
||||
const Carousel = (items, startsWith, props) => {
|
||||
return (
|
||||
<ImageCarouselModal
|
||||
className={joinClassNames('vz-image-modal', 'vz-modal-image-carousel')}
|
||||
items={[ ...items.map(item => {
|
||||
return {
|
||||
src: item
|
||||
};
|
||||
}) ]}
|
||||
startWith={startsWith}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='vz-addon-listing-screenshots-grid-wrapper'>
|
||||
{addon?.manifest?.screenshots?.map((image, index) =>
|
||||
<Image
|
||||
className='vz-image-wrapper'
|
||||
src={image}
|
||||
onClick={() => openModal(props => Carousel(addon?.manifest?.screenshots, index, props))}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default memo(({ addonId, type, section }) => {
|
||||
const { path, url } = useRouteMatch();
|
||||
const [ hideBanner, setHideBanner ] = useState(false);
|
||||
type = type || (/(\/plugin\/)/).test(path) ? 'plugin' : (/(\/theme\/)/).test(path) ? 'theme' : 'plugin';
|
||||
addonId = addonId || url?.replace(`/vizality/${type}/`, '').split('/')[0];
|
||||
section = section || url?.replace(`/vizality/${type}/${addonId}/`, '') || 'overview';
|
||||
let addon = vizality.manager[toPlural(type)].get(addonId);
|
||||
const hasSettings = vizality.manager[toPlural(type)].hasSettings(addonId);
|
||||
const hasChangelog = vizality.manager[toPlural(type)].hasChangelog(addonId);
|
||||
const hasOverview = vizality.manager[toPlural(type)].hasOverview(addonId);
|
||||
const isEnabled = vizality.manager[toPlural(type)].isEnabled(addonId);
|
||||
const isInstalled = vizality.manager[toPlural(type)].isInstalled(addonId);
|
||||
const hasScreenshots = vizality.manager[toPlural(type)].hasScreenshots(addonId);
|
||||
const AddonSettings = hasSettings && addon?.sections?.settings?.render;
|
||||
if (!addon) {
|
||||
addon = vizality.manager.community[toPlural(type)].get(addonId);
|
||||
}
|
||||
if (!addon) {
|
||||
return;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const scroller = document.querySelector('.vz-dashboard-scroller');
|
||||
let lastScrollTop = 0;
|
||||
const onScroll = evt => {
|
||||
evt?.persist?.();
|
||||
evt?.preventDefault();
|
||||
scroller.removeEventListener('scroll', onScroll);
|
||||
|
||||
const topOfElement = document.querySelector('#vz-addon-listing-top-card')?.offsetTop;
|
||||
const down = Boolean(scroller.scrollTop > lastScrollTop);
|
||||
/**
|
||||
* On down scroll and above the top-card.
|
||||
*/
|
||||
if (scroller.scrollTop < (topOfElement - 30) && down) {
|
||||
scroller.scroll({ top: topOfElement - 30, behavior: 'smooth' });
|
||||
setHideBanner(true);
|
||||
/**
|
||||
* On down scroll and above the top-card.
|
||||
*/
|
||||
} else if (scroller.scrollTop <= topOfElement && !down) {
|
||||
setHideBanner(false);
|
||||
scroller.scroll({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
setTimeout(() => {
|
||||
lastScrollTop = scroller?.scrollTop <= 0 ? 0 : scroller?.scrollTop;
|
||||
scroller.addEventListener('scroll', onScroll);
|
||||
}, 500);
|
||||
};
|
||||
scroller.addEventListener('scroll', onScroll);
|
||||
}, []);
|
||||
|
||||
const scrollToTop = () => {
|
||||
const scroller = document.querySelector('.vz-dashboard-scroller');
|
||||
if (scroller) {
|
||||
scroller.scroll({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='vz-addon-listing'>
|
||||
<div className='vz-addon-listing-banner-background' vz-hidden={Boolean(hideBanner) && ''} />
|
||||
<div className='vz-addon-listing-top-card' id="vz-addon-listing-top-card" />
|
||||
<StickyElement wrapperClassName='vz-addon-listing-sticky-bar-wrapper' className='vz-addon-listing-sticky-bar'>
|
||||
<__TabBar type={__TabBar.Types.TOP_PILL}>
|
||||
<__TabBar.NavItem
|
||||
route={`/vizality/${type}/${addonId}/overview`}
|
||||
onClick={() => {
|
||||
scrollToTop();
|
||||
vizality.api.routes.navigateTo(`/vizality/${type}/${addonId}/overview`);
|
||||
}}
|
||||
>
|
||||
{Messages.OVERVIEW}
|
||||
</__TabBar.NavItem>
|
||||
{hasScreenshots && (
|
||||
<__TabBar.NavItem
|
||||
route={`/vizality/${type}/${addonId}/screenshots`}
|
||||
onClick={() => {
|
||||
scrollToTop();
|
||||
vizality.api.routes.navigateTo(`/vizality/${type}/${addonId}/screenshots`);
|
||||
}}
|
||||
>
|
||||
Screenshots
|
||||
</__TabBar.NavItem>
|
||||
)}
|
||||
{isInstalled && isEnabled && hasSettings && (
|
||||
<__TabBar.NavItem
|
||||
route={`/vizality/${type}/${addonId}/settings`}
|
||||
onClick={() => {
|
||||
scrollToTop();
|
||||
vizality.api.routes.navigateTo(`/vizality/${type}/${addonId}/settings`);
|
||||
}}
|
||||
>
|
||||
Settings
|
||||
</__TabBar.NavItem>
|
||||
)}
|
||||
<__TabBar.NavItem
|
||||
route={`/vizality/${type}/${addonId}/reviews`}
|
||||
onClick={() => {
|
||||
scrollToTop();
|
||||
vizality.api.routes.navigateTo(`/vizality/${type}/${addonId}/reviews`);
|
||||
}}
|
||||
disabled
|
||||
>
|
||||
Reviews
|
||||
</__TabBar.NavItem>
|
||||
{hasChangelog && (
|
||||
<__TabBar.NavItem
|
||||
route={`/vizality/${type}/${addonId}/changelog`}
|
||||
onClick={() => {
|
||||
scrollToTop();
|
||||
vizality.api.routes.navigateTo(`/vizality/${type}/${addonId}/changelog`);
|
||||
}}
|
||||
>
|
||||
Changelog
|
||||
</__TabBar.NavItem>
|
||||
)}
|
||||
</__TabBar>
|
||||
</StickyElement>
|
||||
<div className='vz-addon-listing-content'>
|
||||
{hasOverview && section === 'overview' && (
|
||||
<Section header='Overview' icon='InfoFilled'>
|
||||
<Markdown source={addon.sections.overview} addonId={addonId} type={type} />
|
||||
</Section>
|
||||
)}
|
||||
{hasScreenshots && section === 'screenshots' && (
|
||||
<Section header='Screenshots' icon='Pictures'>
|
||||
<AddonScreenshots addon={addon} />
|
||||
</Section>
|
||||
)}
|
||||
{isInstalled && isEnabled && hasSettings && section === 'settings' && (
|
||||
<Section header='Settings' icon='Gear'>
|
||||
<AddonSettings />
|
||||
</Section>
|
||||
)}
|
||||
{section === 'reviews' && (
|
||||
<Section header='Reviews' icon='Star'>
|
||||
|
||||
</Section>
|
||||
)}
|
||||
{hasChangelog && section === 'changelog' && (
|
||||
<Section header='Changelog' icon='MoreInfo'>
|
||||
<Markdown source={addon.sections.changelog} />
|
||||
</Section>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue