mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-12 05:18:34 +03:00
some styling fixes (#178)
* logos at bottom * use GT-Zirkon font * update filter/category copy * add a fallback font * stop tracking * make timeline smaller for smaller laptops * fix for firefox responsive intropopup * mobile fallback * update design system version
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@ tags.lock
|
||||
tags.temp
|
||||
|
||||
src/\.DS_Store
|
||||
src/assets/fonts
|
||||
|
||||
\.DS_Store
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"lint:fix": "npm run lint -- --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@forensic-architecture/design-system": "0.6.0",
|
||||
"@forensic-architecture/design-system": "0.6.1",
|
||||
"d3": "^5.7.0",
|
||||
"joi": "^14.0.1",
|
||||
"leaflet": "^1.0.3",
|
||||
|
||||
BIN
src/assets/fonts/timemapfont.woff
Normal file
BIN
src/assets/fonts/timemapfont.woff
Normal file
Binary file not shown.
@@ -126,9 +126,9 @@
|
||||
"filters": "Filters",
|
||||
"filters_label": "Filters",
|
||||
"explore_by_filter__title": "Explore by filter",
|
||||
"explore_by_filter__description": "‘Filters’ refer to the types of incident. Select multiple filters to introduce colour-coding, up to a maximum of six filters. If no filters are selected, all datapoints are displayed.",
|
||||
"explore_by_filter__description": "'Filters' refer to the types of incident. Select multiple filters to introduce colour-coding, up to a maximum of four filters.<br><br>If no filters are selected, all datapoints are displayed.",
|
||||
"explore_by_category__title": "Explore events by category",
|
||||
"explore_by_category__description": "‘Categories’ refer to the victims of a given incident. If no categories are selected, all datapoints are displayed."
|
||||
"explore_by_category__description": "‘Categories’ refer to the victims of a given incident.<br><br>If no categories are selected, all datapoints are displayed."
|
||||
},
|
||||
"timeline": {
|
||||
"zooms": [
|
||||
|
||||
@@ -109,7 +109,8 @@ class CardStack extends React.Component {
|
||||
title: 'Type of Violation',
|
||||
value: event.associations.slice(0, -1).map(association => ({
|
||||
text: association,
|
||||
color: getFilterIdxFromColorSet(association, this.props.coloringSet) >= 0 ? this.props.colors[getFilterIdxFromColorSet(association, this.props.coloringSet)] : null
|
||||
color: getFilterIdxFromColorSet(association, this.props.coloringSet) >= 0 ? this.props.colors[getFilterIdxFromColorSet(association, this.props.coloringSet)] : null,
|
||||
normalCursor: true
|
||||
}))
|
||||
},
|
||||
{
|
||||
@@ -117,7 +118,8 @@ class CardStack extends React.Component {
|
||||
title: 'Against',
|
||||
value: event.associations.slice(-1).map(category => ({
|
||||
text: category,
|
||||
color: null
|
||||
color: null,
|
||||
normalCursor: true
|
||||
}))
|
||||
}
|
||||
],
|
||||
|
||||
@@ -239,13 +239,48 @@ class Dashboard extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
renderIntroPopup (isMobile, styles) {
|
||||
const { app, actions } = this.props
|
||||
|
||||
const extraContent = isMobile ? <div style={{ position: 'relative', bottom: 0 }}>
|
||||
<h3 style={{ color: 'var(--error-red)' }}>This platform is not suitable for mobile.<br /><br />Please re-visit the site on a device with a larger screen.</h3>
|
||||
</div> : null
|
||||
|
||||
return <Popup
|
||||
title='Introduction to the platform'
|
||||
theme='dark'
|
||||
isOpen={app.flags.isIntropopup}
|
||||
onClose={actions.toggleIntroPopup}
|
||||
content={app.intro}
|
||||
styles={styles}
|
||||
isMobile={isMobile}
|
||||
>
|
||||
{extraContent}
|
||||
</Popup>
|
||||
}
|
||||
|
||||
render () {
|
||||
const { actions, app, domain, features } = this.props
|
||||
if (isMobile || window.innerWidth < 600) {
|
||||
const dateHeight = 80
|
||||
const padding = 2
|
||||
const checkMobile = (isMobile || window.innerWidth < 600)
|
||||
|
||||
const popupStyles = {
|
||||
height: checkMobile ? '100vh' : 'fit-content',
|
||||
display: checkMobile ? 'block' : 'table',
|
||||
width: checkMobile ? '100vw' : window.innerWidth > 768 ? '60vw' : `calc(100vw - var(--toolbar-width))`,
|
||||
maxWidth: checkMobile ? '100vw' : 600,
|
||||
maxHeight: checkMobile ? '100vh' : window.innerHeight > 768 ? `calc(100vh - ${app.timeline.dimensions.height}px - ${dateHeight}px)` : `100vh`,
|
||||
left: checkMobile ? padding : 'inherit',
|
||||
top: 0,
|
||||
overflowY: 'scroll'
|
||||
}
|
||||
|
||||
if (checkMobile) {
|
||||
const msg = 'This platform is not suitable for mobile. Please re-visit the site on a device with a larger screen.'
|
||||
return (
|
||||
<div>
|
||||
{features.USE_COVER ? (
|
||||
{(features.USE_COVER && !app.intro) && (
|
||||
<StaticPage showing={app.flags.isCover}>
|
||||
{/* enable USE_COVER in config.js features, and customise your header */}
|
||||
{/* pass 'actions.toggleCover' as a prop to your custom header */}
|
||||
@@ -255,21 +290,17 @@ class Dashboard extends React.Component {
|
||||
/* eslint-enable no-undef */
|
||||
}} />
|
||||
</StaticPage>
|
||||
) : <div className='fixedTooSmallMessage'>{msg}</div>}
|
||||
)}
|
||||
{app.intro && <>
|
||||
{this.renderIntroPopup(true, popupStyles)}
|
||||
</>}
|
||||
{!app.intro && !features.USE_COVER && (
|
||||
<div className='fixedTooSmallMessage'>{msg}</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const dateHeight = 80
|
||||
const popupStyles = {
|
||||
height: `fit-content`,
|
||||
width: window.innerWidth > 768 ? '60vw' : `calc(100vw - var(--toolbar-width))`,
|
||||
maxWidth: 600,
|
||||
maxHeight: window.innerHeight > 768 ? `calc(100vh - ${app.timeline.dimensions.height}px - ${dateHeight}px)` : `100vh`,
|
||||
top: 0,
|
||||
overflowY: 'scroll'
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Toolbar
|
||||
@@ -327,14 +358,7 @@ class Dashboard extends React.Component {
|
||||
isOpen={app.flags.isInfopopup}
|
||||
onClose={actions.toggleInfoPopup}
|
||||
/>
|
||||
<Popup
|
||||
title='Introduction to the platform'
|
||||
theme='dark'
|
||||
isOpen={app.flags.isIntropopup}
|
||||
onClose={actions.toggleIntroPopup}
|
||||
content={app.intro}
|
||||
styles={popupStyles}
|
||||
/>
|
||||
{this.renderIntroPopup(false)}
|
||||
{app.debug ? <Notification
|
||||
isNotification={app.flags.isNotification}
|
||||
notifications={domain.notifications}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react'
|
||||
import marked from 'marked'
|
||||
import Checkbox from '../presentational/Checkbox'
|
||||
import copy from '../../common/data/copy.json'
|
||||
|
||||
@@ -31,7 +32,7 @@ export default ({
|
||||
return (
|
||||
<div className='react-innertabpanel'>
|
||||
<h2>{copy[language].toolbar.categories}</h2>
|
||||
<p>{copy[language].toolbar.explore_by_category__description}</p>
|
||||
<p dangerouslySetInnerHTML={{ __html: marked(copy[language].toolbar.explore_by_category__description) }} />
|
||||
{renderCategoryTree()}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import Checkbox from '../presentational/Checkbox'
|
||||
import marked from 'marked'
|
||||
import copy from '../../common/data/copy.json'
|
||||
import { getFilterIdxFromColorSet } from '../../common/utilities'
|
||||
|
||||
@@ -85,7 +86,7 @@ function FilterListPanel ({
|
||||
return (
|
||||
<div className='react-innertabpanel'>
|
||||
<h2>{copy[language].toolbar.filters}</h2>
|
||||
<p>{copy[language].toolbar.explore_by_filter__description}</p>
|
||||
<p dangerouslySetInnerHTML={{ __html: marked(copy[language].toolbar.explore_by_filter__description) }} />
|
||||
{renderTree(filters)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -9,15 +9,18 @@ export default ({
|
||||
isOpen = true,
|
||||
onClose,
|
||||
title,
|
||||
theme = 'light'
|
||||
theme = 'light',
|
||||
isMobile = false,
|
||||
children
|
||||
}) => (
|
||||
<div>
|
||||
<div className={`infopopup ${isOpen ? '' : 'hidden'} ${theme === 'dark' ? 'dark' : 'light'}`} style={{ ...styles, fontSize }}>
|
||||
<div className={`infopopup ${isOpen ? '' : 'hidden'} ${theme === 'dark' ? 'dark' : 'light'} ${isMobile ? 'mobile' : ''}`} style={{ ...styles, fontSize }}>
|
||||
<div className='legend-header'>
|
||||
<button onClick={onClose} className='side-menu-burg over-white is-active'><span /></button>
|
||||
<h2>{title}</h2>
|
||||
</div>
|
||||
{content.map(t => <div dangerouslySetInnerHTML={{ __html: marked(t) }} />)}
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
@font-face {
|
||||
font-family: 'GT-Zirkon';
|
||||
src: url(../assets/fonts/timemapfont.woff); // a Lato woff by default
|
||||
}
|
||||
|
||||
$event_default: red;
|
||||
|
||||
$offwhite: #efefef;
|
||||
@@ -24,6 +29,7 @@ $other: yellow;
|
||||
.alpha { background: $alpha; }
|
||||
.beta { background: $beta; }
|
||||
|
||||
$mainfont: 'GT-Zirkon', 'Lato', Helvetica, sans-serif;
|
||||
|
||||
// Font sizes
|
||||
$xsmall: 10px;//0.7em;
|
||||
@@ -54,7 +60,7 @@ $card-width: 386px;
|
||||
$card-right: 9px;
|
||||
$narrative-info-height: 205px;
|
||||
$narrative-info-desc-height: 153px;
|
||||
$timeline-height: 170px;
|
||||
$timeline-height: 250px;
|
||||
$toolbar-width: 110px;
|
||||
|
||||
$panel-width: 1000px;
|
||||
@@ -68,4 +74,5 @@ $header-inset: 10px;
|
||||
// CSS variables (for React access)
|
||||
:root {
|
||||
--toolbar-width: 110px;
|
||||
}
|
||||
--error-red: #eb443e;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,6 @@
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
margin-top: 0;
|
||||
|
||||
.estimated-timestamp {
|
||||
@@ -196,10 +195,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.location {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.summary {
|
||||
overflow: auto;
|
||||
margin-top: 0;
|
||||
|
||||
@@ -15,7 +15,7 @@ body {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Lato', Helvetica, serif;
|
||||
font-family: $mainfont;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@@ -44,7 +44,7 @@ h2 {
|
||||
box-sizing: border-box;
|
||||
padding: 0 5px;
|
||||
outline: none;
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-family: $mainfont;
|
||||
|
||||
&:focus {
|
||||
border: 3px solid $yellow;
|
||||
@@ -74,7 +74,7 @@ h2 {
|
||||
}
|
||||
|
||||
.page {
|
||||
font-family: 'Lato', Helvetica sans-serif;
|
||||
font-family: $mainfont;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@@ -43,17 +43,18 @@
|
||||
}
|
||||
|
||||
&.minimized {
|
||||
top: 0;
|
||||
bottom: 150px;
|
||||
max-width: $toolbar-width;
|
||||
max-height: 30px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
.cover-logo-container {
|
||||
padding: 5px;
|
||||
}
|
||||
.cover-logo {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
.header-title {
|
||||
a {
|
||||
font-family: 'Lato', Helvetica, serif;
|
||||
color: darken($offwhite, 5%);
|
||||
font-size: $xlarge;
|
||||
letter-spacing: 0.1em;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
border-radius: 1px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Lato', 'Helvetica', sans-serif;
|
||||
font-size: $large;
|
||||
transition: opacity 0.5s ease 0.1s, z-index 0.1s ease 0s;
|
||||
opacity: 1;
|
||||
@@ -53,6 +52,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.mobile {
|
||||
border: none;
|
||||
padding: 5vmin;
|
||||
.side-menu-burg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.legend {
|
||||
display: flex;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.loading-overlay {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
font-weight: 300;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -13,3 +13,5 @@
|
||||
@import 'mediaplayer';
|
||||
@import 'cover';
|
||||
@import 'stateoptions';
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
padding: 5px;
|
||||
font-weight: 500;
|
||||
font-size: 11px;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
border: rgba($black,0.6);
|
||||
letter-spacing: 0.05em;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ NARRATIVE INFO
|
||||
box-shadow: 0 19px 38px rgba($black, 0.3), 0 15px 12px rgba($black, 0.22);
|
||||
background: $black;
|
||||
color: $offwhite;
|
||||
font-family: Helvetica, 'Georgia', serif;
|
||||
|
||||
.narrative-info-header {
|
||||
display: flex;
|
||||
@@ -50,7 +49,6 @@ NARRATIVE INFO
|
||||
|
||||
h3 {
|
||||
font-size: $large;
|
||||
font-family: Helvetica, 'Georgia', serif;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
font-weight: 100;
|
||||
@@ -64,7 +62,6 @@ NARRATIVE INFO
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: 'Lato', 'Helvetica', sans-serif;
|
||||
font-size: $normal;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
@@ -76,7 +73,6 @@ NARRATIVE INFO
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
line-height: 40px;
|
||||
font-family: 'Lato', 'Helvetica', sans-serif;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
padding: 20px;
|
||||
margin-bottom: 10px;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Lato', 'Helvetica', sans-serif;
|
||||
font-size: $large;
|
||||
transition: opacity 0.5s ease 0.1s, z-index 0.1s ease 0s;
|
||||
opacity: 1;
|
||||
|
||||
@@ -168,7 +168,6 @@ $overlay-bg: rgba(239,239,239,0.9);
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-height: calc(#{$panel-height} - 100px);
|
||||
font-family: "Lato", Helvetica, sans-serif;
|
||||
|
||||
.media-content {
|
||||
display: flex;
|
||||
@@ -219,7 +218,6 @@ $overlay-bg: rgba(239,239,239,0.9);
|
||||
max-width: $panel-width;
|
||||
padding: $padding 0;
|
||||
border-top: 1px solid rgb(189,189,189);
|
||||
font-family: "Lato", Helvetica, sans-serif;
|
||||
font-size: $normal;
|
||||
|
||||
h4 {
|
||||
@@ -291,7 +289,6 @@ $overlay-bg: rgba(239,239,239,0.9);
|
||||
box-sizing: border-box;
|
||||
padding: 0 calc(50% - 400px);
|
||||
overflow-y: scroll;
|
||||
font-family: Helvetica, Georgia, serif;
|
||||
line-height: 1.5em;
|
||||
min-width: 100%;
|
||||
margin-bottom: 120px;
|
||||
@@ -327,15 +324,10 @@ $overlay-bg: rgba(239,239,239,0.9);
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
display: block;
|
||||
// align-self: center;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
}
|
||||
|
||||
.source-image, .source-video {
|
||||
padding: 1px;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
// max-width: calc(#{$panel-width} - 100px);
|
||||
max-height: 100%;
|
||||
margin: auto;
|
||||
width: auto;
|
||||
|
||||
@@ -48,14 +48,12 @@
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
text-transform: uppercase;
|
||||
font-size: $xlarge;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.location {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
font-size: $normal;
|
||||
color: $offwhite;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
|
||||
[role=tab] {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
font-size: $xlarge;
|
||||
width: 33%;
|
||||
background: none;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
$timeline-height: 170px;
|
||||
|
||||
.timeline-wrapper {
|
||||
position: fixed;
|
||||
box-sizing: border-box;
|
||||
@@ -160,7 +158,6 @@ $timeline-height: 170px;
|
||||
}
|
||||
|
||||
text {
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
fill: $midwhite;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
@@ -181,7 +178,6 @@ $timeline-height: 170px;
|
||||
|
||||
.tick text {
|
||||
font-size: 10px;
|
||||
font-family: 'Lato';
|
||||
text-anchor: end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
transition: 0.2s ease;
|
||||
border-bottom: 2px solid $midwhite;
|
||||
text-transform: uppercase;
|
||||
font-family: Helvetica, serif;
|
||||
cursor: pointer;
|
||||
|
||||
p {
|
||||
@@ -82,7 +81,6 @@
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
outline: none;
|
||||
font-family: 'Lato';
|
||||
font-size: $xsmall;
|
||||
cursor: pointer;
|
||||
transition: 0.2s ease;
|
||||
@@ -250,7 +248,6 @@
|
||||
box-sizing: border-box;
|
||||
padding: 30px 10px 10px 30px;
|
||||
font-size: $normal;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
background: $black;
|
||||
color: $offwhite;
|
||||
position: fixed;
|
||||
@@ -259,7 +256,6 @@
|
||||
box-shadow: 10px -10px 38px rgba(0, 0, 0, 0.3), 10px 15px 12px rgba(0, 0, 0, 0.22);
|
||||
|
||||
h2 {
|
||||
font-family: Helvetica, 'Georgia', 'serif';
|
||||
font-size: $large;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
@@ -267,7 +263,6 @@
|
||||
|
||||
p {
|
||||
font-size: $normal;
|
||||
font-family: Helvetica, 'Georgia', 'serif';
|
||||
line-height: 1.4em;
|
||||
};
|
||||
|
||||
@@ -365,7 +360,6 @@
|
||||
margin: 20px 0;
|
||||
padding: 5px 10px;
|
||||
font-size: 18px;
|
||||
font-family: 'Lato', sans-serif;
|
||||
letter-spacing: 0.1em;
|
||||
transition: 0.2s ease;
|
||||
border-color: $midwhite;
|
||||
@@ -382,7 +376,6 @@
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background: none;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
font-size: $large;
|
||||
|
||||
button {
|
||||
@@ -416,7 +409,6 @@
|
||||
float: left;
|
||||
color: $offwhite;
|
||||
font-size: $normal;
|
||||
font-family: Helvetica, 'Georgia', 'serif';
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -461,7 +453,6 @@
|
||||
color: $offwhite;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 10px;
|
||||
transition: 0.2s ease;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
height: 420px;
|
||||
transition: opacity 500ms;
|
||||
background-color: black;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { mergeDeepLeft } from 'ramda'
|
||||
import global, { colors } from '../common/global'
|
||||
|
||||
const isSmallLaptop = window.innerHeight < 800
|
||||
const initial = {
|
||||
/*
|
||||
* The Domain or 'domain' of this state refers to the tree of data
|
||||
@@ -62,12 +63,12 @@ const initial = {
|
||||
},
|
||||
timeline: {
|
||||
dimensions: {
|
||||
height: 250,
|
||||
height: isSmallLaptop ? 170 : 250,
|
||||
width: 0,
|
||||
marginLeft: 70,
|
||||
marginTop: 10, // the padding used for the day/month labels inside the timeline
|
||||
marginTop: isSmallLaptop ? 5 : 10, // the padding used for the day/month labels inside the timeline
|
||||
marginBottom: 60,
|
||||
contentHeight: 200,
|
||||
contentHeight: isSmallLaptop ? 160 : 200,
|
||||
width_controls: 100
|
||||
},
|
||||
range: [
|
||||
|
||||
Reference in New Issue
Block a user