diff options
Diffstat (limited to 'frontend/site/projects/museum/views')
| -rw-r--r-- | frontend/site/projects/museum/views/credits.css | 13 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/credits.js | 270 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/essay.css | 18 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/essay.js | 33 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/flash.css | 8 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/flash.js | 43 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/home.js | 1 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/jakrawal.links.css | 5 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/jakrawal.links.js | 3 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/nav.overlay.js | 62 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/text.overlay.css | 20 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/text.overlay.js | 5 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/titles.css | 1 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/titles.overlay.js | 23 |
14 files changed, 385 insertions, 120 deletions
diff --git a/frontend/site/projects/museum/views/credits.css b/frontend/site/projects/museum/views/credits.css index d4b6f72..aaf05c7 100644 --- a/frontend/site/projects/museum/views/credits.css +++ b/frontend/site/projects/museum/views/credits.css @@ -72,6 +72,12 @@ font-size: 2vw; } +.icon-rows { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; +} .page-credits .page-subtitle { margin-bottom: 1rem; @@ -111,7 +117,6 @@ justify-content: flex-start; align-items: center; padding: 3vh 0 6vh 0; - width: 100%; } .page-credits .icons img { height: 7vh; @@ -121,6 +126,12 @@ height: 8vh; } +.icons img.kw-logo { + position: relative; + bottom: -0.1vh; + height: 10vh; +} + .page-credits .page-title { padding-top: 1rem; width: 100%; diff --git a/frontend/site/projects/museum/views/credits.js b/frontend/site/projects/museum/views/credits.js index 87da80b..c256dee 100644 --- a/frontend/site/projects/museum/views/credits.js +++ b/frontend/site/projects/museum/views/credits.js @@ -1,4 +1,5 @@ import React, { Component } from 'react' +import { connect } from 'react-redux' import actions from 'site/actions' import { history } from "site/store" @@ -7,13 +8,12 @@ import { LastMuseumLogo } from "../icons" import "./credits.css" -export default class Credits extends Component { +class Credits extends Component { constructor(props) { super(props) this.handleClick = this.handleClick.bind(this) this.goHome = this.goHome.bind(this) - this.state = { - } + this.changeLanguage = this.changeLanguage.bind(this) } componentDidMount() { @@ -28,7 +28,12 @@ export default class Credits extends Component { history.push(`/last-museum/home/`) } + changeLanguage() { + actions.site.changeLanguage(this.props.language === "de" ? "en" : "de") + } + render() { + const { language } = this.props return ( <div className="page page-credits"> <div className="page-title">{LastMuseumLogo}</div> @@ -37,91 +42,21 @@ export default class Credits extends Component { <div className="page-subtitle">CREDITS</div> </div> <div className="page-right"> - <div className="page-subtitle">ARTWORK CREDITS</div> + <div className="page-subtitle">{CREDITS_STRINGS.artwork_credits_head[language]}</div> </div> </div> <div className="page-content"> - <div className="page-left"> - <div className="credits-rows"> - <div> - <div>Curator:</div> <a href="http://nadimsamman.com/">Nadim Samman</a> - </div> - <div> - <div>Developer:</div> <a href="https://asdf.us/">Jules LaPlace</a> - </div> - <div> - <div>Design:</div> <a href="https://sometimes-always.com/">Sometimes Always</a> - </div> - </div> - <div> - Commissioned by:<br/> - <b>KW Institute for Contemporary Art</b><br/> - Auguststraße 69<br/> - 10117 Berlin<br/> - Tel. +49 30 243459-0<br/> - Fax +49 30 243459-99<br/> - <a href="mailto:info@kw-berlin.de?subject=The+Last+Museum">info@kw-berlin.de</a><br/> - <br/> - KW Institute for Contemporary Art is institutionally supported by the Senate Department for Culture and Europe, Berlin.<br/> - <br/> - The Last Museum is produced in collaboration with Polyeco Contemporary Art Initiative (PCAI), Athens<br/> - <br/> - <b>Press Enquiries:</b><br/> - Natanja von Stosch<br/> - Tel. +49 30 243459 41<br/> - <a href="mailto:nvs@kw-berlin.de?subject=The+Last+Museum">nvs@kw-berlin.de</a><br/> - <b>Press Releases and Image Material:</b><br/> - <a href="https://kw-berlin.de/en/press">kw-berlin.de/en/press</a> - </div> - </div> + <div className="page-left" dangerouslySetInnerHTML={{ __html: CREDITS_STRINGS.site_credits[language] }} /> <div className="page-right columns"> - <div className="column"> - <b>Charles Stankievech</b><br/> - <i>The Glass Key</i><br/> - Cinematography, Soundtrack, LIDAR and Ionospheric Recordings, Hypercard Programming: Charles Stankievech<br/> - Fieldwork Recording Assistant: Ala Roushan<br/> - <br/> - VR Capture thanks to Sudbury Neutrino Laboratory (SNO).<br/> - <br/> - <b>Nora Al-Badri</b><br/> - <i>This Is Not A Hacker Space</i><br/> - Location: C-Base, Berlin, Germany<br/> - Videography: Siska<br/> - Soundtrack mix: Shamsa<br/> - Track mixed in: Cadans - No Connection (Broken Mix)<br/> - Melodic Acapella female sound: Lynn Adib<br/> - poem: Nikki Giovanni ‘Ego Tripping’<br/> - <span style={{ lineHeight: 1 }}>الأمل</span> Al-Amal/ Hope Mars Mission (via YouTube)<br/> - Special thanks to the Norberta, Gregor and the spaceship crew in Berlin-Mitte; Andy and CCC.<br/> - <br/> - </div> - <div className="column"> - <b>Juliana Cerqueira Leite</b><br/> - <i>Untitled</i><br/> - Location: Santa Ifigênia, São Paulo, Brasil<br/> - Videography & Sound design: Juliana Cerqueira Leite <br/> - <br/> - <b>Zohra Opoku</b><br/> - <i>The Myths of Eternal Life</i><br/> - Videography & Sound Design: Zohra Opoku<br/> - Location: Unfinished mortuary, Accra, Ghana.<br/> - <br/> - <b>Nicole Foreshew</b><br/> - <i>Dhurany Yanggu</i>
(message song of running water)<br/> - Location: Gumbaynggirr Country, Northern Tablelands and Northern Rivers districts of New South Wales, Australia.<br/> - Videography & Sound Design: Nicole Foreshew<br/> - <br/> - <b>Jakrawal Nilthamrong</b><br/> - <i>Barn Burner</i> <br/> - Location: Chiang Mai, Thailand. <br/> - Videography & Sound Design: Jakrawal Nilthamrong - </div> + <div className="column" dangerouslySetInnerHTML={{ __html: CREDITS_STRINGS.artist_credits_1[language] }} /> + <div className="column" dangerouslySetInnerHTML={{ __html: CREDITS_STRINGS.artist_credits_2[language] }} /> </div> </div> - <div className="page-content"> + <div className="page-content icon-rows"> <div className="icons"> + <img className="kw-logo" src="/last-museum/static/media/last-museum/kw-black.png" /> <img src="/last-museum/static/media/last-museum/arte-logo-black.png" /> <img src="/last-museum/static/media/last-museum/pcai-logo-black.png" className='pcai' /> <img src="/last-museum/static/media/last-museum/berlin-logo-black.png" /> @@ -130,11 +65,188 @@ export default class Credits extends Component { <div className="home-link" onClick={this.goHome}> Home </div> + <div className="home-link language-link black" onClick={this.changeLanguage}> + {this.props.language === "de" ? ( + <span><b>de</b> / en</span> + ) : ( + <span>de / <b>en</b></span> + )} + </div> </div> ) } } +const mapStateToProps = state => ({ + language: state.site.language, +}) + +export default connect(mapStateToProps)(Credits) + + +const CREDITS_STRINGS = { + artwork_credits_head: { + en: "ARTWORK CREDITS", + de: "CREDITS DER KUNSTWERKE", + }, + + site_credits: { + en: ` + <div class="credits-rows"> + <div> + <div>Curator:</div> <a href="http://nadimsamman.com/">Nadim Samman</a> + </div> + <div> + <div>Developer:</div> <a href="https://asdf.us/">Jules LaPlace</a> + </div> + <div> + <div>Design:</div> <a href="https://sometimes-always.com/">Sometimes Always</a> + </div> + </div> + <div> + Commissioned by:<br/> + <b>KW Institute for Contemporary Art</b><br/> + Auguststraße 69<br/> + 10117 Berlin<br/> + Tel. +49 30 243459-0<br/> + Fax +49 30 243459-99<br/> + <a href="mailto:info@kw-berlin.de?subject=The+Last+Museum">info@kw-berlin.de</a><br/> + <br/> + KW Institute for Contemporary Art is institutionally supported by the Senate Department for Culture and Europe, Berlin.<br/> + <br/> + The Last Museum is produced in collaboration with Polyeco Contemporary Art Initiative (PCAI), Athens<br/> + <br/> + Press Enquiries:<br/> + Natanja von Stosch<br/> + Tel. +49 30 243459 41<br/> + <a href="mailto:nvs@kw-berlin.de?subject=The+Last+Museum">nvs@kw-berlin.de</a><br/> + Press Releases and Image Material:<br/> + <a href="https://kw-berlin.de/en/press">kw-berlin.de/en/press</a> + </div> + `, + de: ` + <div class="credits-rows"> + <div> + <div>Kurator:</div> <a href="http://nadimsamman.com/">Nadim Samman</a> + </div> + <div> + <div>Entwickler:</div> <a href="https://asdf.us/">Jules LaPlace</a> + </div> + <div> + <div>Design:</div> <a href="https://sometimes-always.com/">Sometimes Always</a> + </div> + </div> + <div> + Im Auftrag von:<br/> + <b>KW Institute for Contemporary Art</b><br/> + Auguststraße 69<br/> + 10117 Berlin<br/> + Tel. +49 30 243459-0<br/> + Fax +49 30 243459-99<br/> + <a href="mailto:info@kw-berlin.de?subject=The+Last+Museum">info@kw-berlin.de</a><br/> + <br/> + Die KW Institute for Contemporary Art werden institutionell gefördert von der Senatsverwaltung für Kultur und Europa, Berlin. + <br/> + The Last Museum wird in Zusammenarbeit mit der Polyeco Contemporary Art Initiative (PCAI), Athen, produziert. + <br/> + Press Enquiries:<br/> + Natanja von Stosch<br/> + Tel. +49 30 243459 41<br/> + <a href="mailto:nvs@kw-berlin.de?subject=The+Last+Museum">nvs@kw-berlin.de</a><br/> + Press Releases and Image Material:<br/> + <a href="https://kw-berlin.de/en/press">kw-berlin.de/en/press</a> + </div> + ` + }, + + artist_credits_1: { + en: ` + <b>Charles Stankievech</b><br/> + <i>The Glass Key</i><br/> + Cinematography, Soundtrack, LIDAR and Ionospheric Recordings, Hypercard Programming: Charles Stankievech<br/> + Fieldwork Recording Assistant: Ala Roushan<br/> + VR Capture thanks to Sudbury Neutrino Laboratory (SNO).<br/> + <br/> + <b>Nora Al-Badri</b><br/> + <i>This Is Not A Hacker Space</i><br/> + Location: C-Base, Berlin, Germany<br/> + Videography: Siska<br/> + Soundtrack mix: Shamsa<br/> + Track mixed in: Cadans - No Connection (Broken Mix)<br/> + Melodic Acapella female sound: Lynn Adib<br/> + poem: Nikki Giovanni ‘Ego Tripping’<br/> + <span style="lineHeight: 1">الأمل</span> Al-Amal/ Hope Mars Mission (via YouTube)<br/> + Special thanks to the Norberta, Gregor and the spaceship crew in Berlin-Mitte; Andy and CCC.<br/> + <br/> + `, + de: ` + <b>Charles Stankievech</b><br/> + <i>The Glass Key</i><br/> + Location: Cosmic Ray Research Station, kanadische Rocky Mountains (Wintersonnenwende)<br /> + Videografie, Sound Design, LIDAR und Ionosphären-Aufnahmen, Hypercard-Programmierung: Charles Stankievech<br/> + Assistent für Feldaufnahmen: Ala Roushan<br/> + VR-Aufnahme dank des Sudbury Neutrino Laboratory (SNO).<br/> + <br/> + <b>Nora Al-Badri</b><br/> + <i>This Is Not A Hacker Space</i><br/> + Location: C-Base, Berlin, Germany<br/> + Videografie: Siska<br/> + Soundtrack-Mix: Shamsa<br/> + Track gemixt in: Cadans - No Connection (Broken Mix)<br/> + Melodische weibliche Acapella-Stimme: Lynn Adib<br/> + Gedicht: Nikki Giovanni ‘Ego Tripping’<br/> + <span style="lineHeight: 1">الأمل</span> Al-Amal/ Hope Mars Mission (via YouTube)<br/> + Ein besonderer Dank geht an Norberta, Gregor und die Raumschiff-Crew in Berlin-Mitte; Andy und CCC.<br/> + <br/> + `, + }, + + artist_credits_2: { + en: ` + <b>Juliana Cerqueira Leite</b><br/> + <i>Untitled</i><br/> + Location: Santa Ifigênia, São Paulo, Brasil<br/> + Videography & Sound design: Juliana Cerqueira Leite <br/> + <br/> + <b>Zohra Opoku</b><br/> + <i>The Myths of Eternal Life</i><br/> + Videography & Sound Design: Zohra Opoku<br/> + Location: Unfinished mortuary, Accra, Ghana.<br/> + <br/> + <b>Nicole Foreshew</b><br/> + <i>Dhurany Yanggu</i>
(message song of running water)<br/> + Location: Gumbaynggirr Country, Northern Tablelands and Northern Rivers districts of New South Wales, Australia.<br/> + Videography & Sound Design: Nicole Foreshew<br/> + <br/> + <b>Jakrawal Nilthamrong</b><br/> + <i>Barn Burner</i> <br/> + Location: Chiang Mai, Thailand. <br/> + Videography & Sound Design: Jakrawal Nilthamrong + `, + de: ` + <b>Juliana Cerqueira Leite</b><br/> + <i>Untitled</i><br/> + Location: Santa Ifigênia, São Paulo, Brasilien<br/> + Videografie & Sound Design: Juliana Cerqueira Leite <br/> + <br/> + <b>Zohra Opoku</b><br/> + <i>The Myths of Eternal Life</i><br/> + Videografie & Sound Design: Zohra Opoku<br/> + Location: Unvollendete Leichenhalle, Accra, Ghana.<br/> + <br/> + <b>Nicole Foreshew</b><br/> + <i>Dhurany Yanggu</i>
(Botschaftslied des fließenden Wassers)<br/> + Location: Gumbaynggirr Country, Northern Tablelands und Northern Rivers Regionen von New South Wales, Australien.<br/> + Videografie & Sound Design: Nicole Foreshew<br/> + <br/> + <b>Jakrawal Nilthamrong</b><br/> + <i>Barn Burner</i> <br/> + Location: Chiang Mai, Thailand. <br/> + Videografie & Sound Design: Jakrawal Nilthamrong + `, + } +} + /* Sources:<br/> René Magritte, <i>The Glass Key (La clef de verre)</i>, 1959, oil on canvas.<br/> diff --git a/frontend/site/projects/museum/views/essay.css b/frontend/site/projects/museum/views/essay.css index 129c768..a3cae05 100644 --- a/frontend/site/projects/museum/views/essay.css +++ b/frontend/site/projects/museum/views/essay.css @@ -18,8 +18,15 @@ .page .home-link.black { color: #000; } +.page .home-link.language-link { + position: fixed; + top: 2.2rem; + left: 0; +} - +.page-essay.page-artists .artist-list .artists-heading { + margin-bottom: 1rem; +} .page-essay.page-artists .artist-list { justify-content: flex-start; } @@ -35,6 +42,7 @@ padding-bottom: 10vh; } .page-essay .page-title { + text-shadow: 0 0 5px #000; cursor: pointer; font-size: 10vw; } @@ -83,7 +91,8 @@ } .globe path { /*stroke: rgb(255, 121, 13);*/ - stroke: rgb(0, 0, 0); + /*stroke: rgb(0, 0, 0);*/ + stroke: rgb(255, 255, 255); stroke-miterlimit: 10; stroke-linecap: round; stroke-linejoin: round; @@ -97,8 +106,13 @@ font-family: 'Druk Wide', sans-serif; text-transform: uppercase; font-size: 2vw; + color: white; + text-shadow: 0 0 3px #fff; cursor: pointer; } +.globe .globe-image .number:hover { + text-shadow: 0 0 6px #fff; +} .page a.jules-link { font-weight: normal; diff --git a/frontend/site/projects/museum/views/essay.js b/frontend/site/projects/museum/views/essay.js index 5e98822..8a0d2d4 100644 --- a/frontend/site/projects/museum/views/essay.js +++ b/frontend/site/projects/museum/views/essay.js @@ -1,4 +1,5 @@ import React, { Component } from 'react' +import { connect } from 'react-redux' import actions from 'site/actions' import "./artists.css" @@ -9,7 +10,7 @@ import { ArrowLeft, ArrowRight, Globe } from "site/projects/museum/icons" import { history } from "site/store" -export default class Essays extends Component { +class Essays extends Component { state = { currentIndex: 0, detail: false, @@ -23,6 +24,7 @@ export default class Essays extends Component { this.nextEssay = this.nextEssay.bind(this) this.close = this.close.bind(this) this.goHome = this.goHome.bind(this) + this.changeLanguage = this.changeLanguage.bind(this) } componentDidMount() { @@ -52,6 +54,10 @@ export default class Essays extends Component { history.push(`/last-museum/home/`) } + changeLanguage() { + actions.site.changeLanguage(this.props.language === "de" ? "en" : "de") + } + scrollToTop() { setTimeout(() => { Array.from(this.ref.current.querySelectorAll(".artist-detail")).forEach(el => { @@ -65,6 +71,7 @@ export default class Essays extends Component { } render() { + const { language } = this.props const { currentIndex, detail } = this.state return ( <div className="page page-artists page-essay" ref={this.ref}> @@ -85,6 +92,7 @@ export default class Essays extends Component { key={key} essayId={key} index={index} + language={language} isCurrent={detail && currentIndex === index} onClose={this.close} /> @@ -98,11 +106,25 @@ export default class Essays extends Component { <div className={detail ? "home-link black" : "home-link"} onClick={this.goHome}> Home </div> + <div className={detail ? "home-link language-link black" : "home-link language-link"} onClick={this.changeLanguage}> + {this.props.language === "de" ? ( + <span><b>de</b> / en</span> + ) : ( + <span>de / <b>en</b></span> + )} + </div> </div> ) } } +const mapStateToProps = state => ({ + interactive: state.site.interactive, + language: state.site.language, +}) + +export default connect(mapStateToProps)(Essays) + const EssayDetail = props => { switch (props.essayId) { case 'nadim': @@ -112,7 +134,7 @@ const EssayDetail = props => { } } -const ArtistStatements = ({ essayId, index, isCurrent, onClose }) => ( +const ArtistStatements = ({ essayId, index, isCurrent, language, onClose }) => ( <div className={isCurrent ? "artist-detail visible" : "artist-detail"}> <div className="page-title" onClick={onClose}>ARTIST STATEMENTS</div> <br /><br /> @@ -121,7 +143,7 @@ const ArtistStatements = ({ essayId, index, isCurrent, onClose }) => ( return ( <div key={key} className={key}> <div className="page-subtitle">{artist.name}</div> - <div className="page-content artist-statement" dangerouslySetInnerHTML={{ __html: artist.statement }} /> + <div className="page-content artist-statement" dangerouslySetInnerHTML={{ __html: language === 'de' ? artist.statement_de : artist.statement }} /> </div> ) })} @@ -134,7 +156,7 @@ const NadimEssay = ({ essayId, index, isCurrent, onClose }) => ( <div className="page-subtitle">By Nadim Samman</div> <div className="page-content"> <p> - <i>The Last Museum</i> is an exhibition that explores productive tensions between the putative ‘anywhere’ of the digital and its relation to local particulars. Deploying a hybrid offline-online format, the project invites an international group of artists to reimagine site-specificity, through a sequence of interventions that cut across both real and virtual domains. The artists are <b>Nora Al-Badri</b> (Germany/Iraq), <b>Juliana Cerqueira Leite</b> (Brazil), <b>Nicole Foreshew</b> (Wiradjuri Nation/Australia), <b>Jakrawal Nilthamrong</b> (Thailand), <b>Zohra Opoko</b> (Ghana), and <b>Charles Stankievech</b> (Canada). + <i>The Last Museum</i> is an exhibition that explores productive tensions between the putative ‘anywhere’ of the digital and its relation to local particulars. Deploying a hybrid offline-online format, the project invites an international group of artists to reimagine site-specificity, through a sequence of interventions that cut across both real and virtual domains. The artists are <b>Nora Al-Badri</b> (Germany/Iraq), <b>Juliana Cerqueira Leite</b> (Brazil), <b>Nicole Foreshew</b> (Wiradjuri Nation/Australia), <b>Jakrawal Nilthamrong</b> (Thailand), <b>Zohra Opoku</b> (Ghana), and <b>Charles Stankievech</b> (Canada). </p> <ArtistGlobe /> <p> @@ -161,9 +183,6 @@ const NadimEssay = ({ essayId, index, isCurrent, onClose }) => ( <p> At its core, The Last Museum explores how tangibility and distance interact, how things that seem fixed in place might (or do) escape in various forms. In a sense, then, it clear that we are dealing with an issue as old as art itself (albeit, employing contemporary tools). At least one of the exhibition’s artists, Zohra Opoku, explicitly takes up an art-historical precursor for the crossing of spatial and metaphysical thresholds. The Egyptian Book of the Dead is her inspiration for a series of interventions in a half-built mortuary in Accra, Ghana. Draped with screen-printed fabric, the unfinished site is (literally) shrouded in images that stimulate reflection on how stillness and passage come together. In this work and more, the <i>The Last Museum</i> hovers somewhere between life and death, lockdown and escape. </p> - <p> - The Last Museum launches 30 April and runs until 6 June 2021, at <a href="https://www.kw-berlin.de/" target="_blank">www.kw-berlin.de</a>. - </p> </div> </div> ) diff --git a/frontend/site/projects/museum/views/flash.css b/frontend/site/projects/museum/views/flash.css new file mode 100644 index 0000000..d046bab --- /dev/null +++ b/frontend/site/projects/museum/views/flash.css @@ -0,0 +1,8 @@ +.flash { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: #ff790d; +}
\ No newline at end of file diff --git a/frontend/site/projects/museum/views/flash.js b/frontend/site/projects/museum/views/flash.js new file mode 100644 index 0000000..74cb9ec --- /dev/null +++ b/frontend/site/projects/museum/views/flash.js @@ -0,0 +1,43 @@ +import React, { Component } from 'react' + +import "./flash.css" + +import { ARTISTS } from "site/projects/museum/constants" + +export default class Flash extends Component { + constructor(props) { + super(props) + this.state = { + flashing: false, + artist_name: "", + } + } + + componentDidUpdate(prevProps) { + if (this.props.location.pathname !== prevProps.location.pathname) { + this.flash() + } + } + + flash() { + const { page_name } = this.props.match.params + const artist_name = page_name.split('-')[0] + if (!(artist_name in ARTISTS)) { + return + } + if (artist_name !== this.state.artist_name) { + this.setState({ flashing: true, artist_name }) + setTimeout(() => { + this.setState({ flashing: false }) + }, 100) + } + } + + render() { + if (!this.state.flashing) return null + return ( + <div className="flash" /> + ) + } +} + diff --git a/frontend/site/projects/museum/views/home.js b/frontend/site/projects/museum/views/home.js index 7c42ef9..fbd0372 100644 --- a/frontend/site/projects/museum/views/home.js +++ b/frontend/site/projects/museum/views/home.js @@ -104,6 +104,7 @@ class Home extends Component { const mapStateToProps = state => ({ interactive: state.site.interactive, + language: state.site.language, }) export default connect(mapStateToProps)(Home) diff --git a/frontend/site/projects/museum/views/jakrawal.links.css b/frontend/site/projects/museum/views/jakrawal.links.css index 51869e0..02cba49 100644 --- a/frontend/site/projects/museum/views/jakrawal.links.css +++ b/frontend/site/projects/museum/views/jakrawal.links.css @@ -30,10 +30,11 @@ .jakrawal-text { position: absolute; - bottom: 5rem; + bottom: 2rem; left: 0; width: 100%; padding: 0 5rem 0 5rem; + /*color: rgba(255, 121, 13, 1.0);*/ color: rgba(255, 121, 13, 1.0); font-family: "Druk Wide"; font-size: 1.66vw; @@ -48,6 +49,6 @@ .jakrawal-text-icon { position: absolute; top: 1rem; - right: 1.5rem; + right: 3rem; cursor: url(/last-museum/static/uploads/3/cursor/The_Last_Museum_-_Symbols-103.png), pointer; } diff --git a/frontend/site/projects/museum/views/jakrawal.links.js b/frontend/site/projects/museum/views/jakrawal.links.js index 60ed64f..c69673c 100644 --- a/frontend/site/projects/museum/views/jakrawal.links.js +++ b/frontend/site/projects/museum/views/jakrawal.links.js @@ -7,7 +7,8 @@ import { history } from "site/store" const JAKRAWAL_TEXTS = [ "<i>Wildfires</i> occur frequently during the dry season in northern Thailand’s high mountains. The source of fire is not natural but arson.", - "In the past it was hypothesized that local people set the fires to clear land for agricultural use, or for hunting. There were efforts to solve the problem at the community level, but the fires only became more severe.", + "In the past it was hypothesized that local people set the fires to clear land for agricultural use, or for hunting.", + "There were efforts to solve the problem at the community level, but the fires only became more severe.", "Strangely, the blazes often occurred in the national park—an area difficult for villagers to access.", "During the wildfire suppression efforts of May 2020, a group of scholars and volunteers discovered important evidence that would change the original hypothesis.", "They found several instances of improvised devices made of clothes pegs connected to a small battery by a power cable.", diff --git a/frontend/site/projects/museum/views/nav.overlay.js b/frontend/site/projects/museum/views/nav.overlay.js index d3951cf..7a6c7a5 100644 --- a/frontend/site/projects/museum/views/nav.overlay.js +++ b/frontend/site/projects/museum/views/nav.overlay.js @@ -1,4 +1,5 @@ import React, { Component } from 'react' +import { connect } from 'react-redux' import actions from 'site/actions' @@ -7,6 +8,7 @@ import "./nav.css" import TextOverlay from './text.overlay' import JakrawalLinks from './jakrawal.links' import TitlesOverlay from './titles.overlay' +import Flash from './flash' import { ARTISTS, ARTIST_ORDER, PROJECT_PAGE_SET } from "site/projects/museum/constants" import { ArrowLeft, ArrowRight } from "site/projects/museum/icons" import MuteButton from "site/audio/mute.button" @@ -14,13 +16,15 @@ import { history } from "site/store" import Counter from './counter' -export default class NavOverlay extends Component { +class NavOverlay extends Component { state = { showHome: false, + showLanguage: false, showFooter: false, showArtist: false, showCounter: false, showMuteButton: false, + isProjectPage: false, artist: {}, } @@ -30,6 +34,7 @@ export default class NavOverlay extends Component { this.previousArtist = this.previousArtist.bind(this) this.nextArtist = this.nextArtist.bind(this) this.goHome = this.goHome.bind(this) + this.changeLanguage = this.changeLanguage.bind(this) } componentDidMount() { @@ -52,41 +57,49 @@ export default class NavOverlay extends Component { if (pathkey === 'start') { this.setState({ showHome: false, + showLanguage: true, showFooter: false, showArtist: false, showCounter: false, currentArtist: null, showMuteButton: false, + isProjectPage: false, artist: {}, }) } else if (pathkey === 'home') { this.setState({ showHome: false, + showLanguage: true, showFooter: true, showArtist: false, showCounter: false, currentArtist: null, showMuteButton: true, + isProjectPage: false, artist: {}, }) } else if (PROJECT_PAGE_SET.has(pathkey)) { this.setState({ showHome: false, + showLanguage: false, showFooter: false, showArtist: false, showCounter: false, showMuteButton: false, + isProjectPage: true, }) } else if (pathkey in ARTISTS) { const shouldShowFooter = this.state.currentArtist !== pathkey this.setState({ showHome: true, + showLanguage: true, showFooter: true, showArtist: true, showMuteButton: true, + isProjectPage: false, showCounter: pathkey === 'nilthamrong' && path_chapter !== "home", currentArtist: pathkey, artist: ARTISTS[pathkey], @@ -94,10 +107,12 @@ export default class NavOverlay extends Component { } else { this.setState({ showHome: false, + showLanguage: false, showFooter: false, showCounter: false, showArtist: false, showMuteButton: false, + isProjectPage: false, currentArtist: null, artist: {}, }) @@ -109,7 +124,9 @@ export default class NavOverlay extends Component { // this.footerRef.current.classList.add("instant") this.footerRef.current.classList.add("visible") this.footerTimeout = setTimeout(() => { - this.footerRef.current.classList.remove("visible") + if (this.footerRef.current) { + this.footerRef.current.classList.remove("visible") + } }, 5000) } @@ -135,21 +152,15 @@ export default class NavOverlay extends Component { history.push(`/last-museum/home/`) } + changeLanguage() { + actions.site.changeLanguage(this.props.language === "de" ? "en" : "de") + } + render() { - const { showArtist, showHome, showMuteButton, showCounter, showFooter, artist } = this.state + const { showArtist, showHome, showLanguage, showMuteButton, showCounter, showFooter, isProjectPage, artist } = this.state return ( <div className="museum-nav"> <JakrawalLinks location={this.props.location} match={this.props.match} /> - <div className="home-corner"> - {showHome && ( - <div className="home-link" onClick={this.goHome}> - Home - </div> - )} - {showMuteButton && ( - <MuteButton /> - )} - </div> {showCounter && <Counter />} <TextOverlay location={this.props.location} match={this.props.match} /> {showFooter && ( @@ -168,8 +179,33 @@ export default class NavOverlay extends Component { ) )} <TitlesOverlay location={this.props.location} match={this.props.match} /> + <div className="home-corner"> + {showHome && ( + <div className="home-link" onClick={this.goHome} style={{ opacity: isProjectPage ? 0 : 1 }}> + Home + </div> + )} + {showLanguage && ( + <div className="home-link" onClick={this.changeLanguage}> + {this.props.language === "de" ? ( + <span><b>de</b> / en</span> + ) : ( + <span>de / <b>en</b></span> + )} + </div> + )} + {showMuteButton && ( + <MuteButton /> + )} + </div> + <Flash location={this.props.location} match={this.props.match} /> </div> ) } } +const mapStateToProps = state => ({ + language: state.site.language, +}) + +export default connect(mapStateToProps)(NavOverlay) diff --git a/frontend/site/projects/museum/views/text.overlay.css b/frontend/site/projects/museum/views/text.overlay.css index 4c67361..3c4c43b 100644 --- a/frontend/site/projects/museum/views/text.overlay.css +++ b/frontend/site/projects/museum/views/text.overlay.css @@ -4,19 +4,22 @@ top: 1rem; right: 2rem; transform: scale(0.7); - cursor: pointer; + cursor: url(/last-museum/static/uploads/3/cursor/The_Last_Museum_-_Symbols-72.png) 50 50, pointer; } .text-overlay { position: fixed; - top: 0; + top: 50%; left: 0; + transform: translateY(-50%); width: 100vw; - height: 100vh; - color: #FF790D; + max-height: 100vh; + /*color: #FF790D;*/ + color: #fff; + text-align: justify; font-family: "Druk Wide", sans-serif; - font-size: 1.3vw; - padding: 1rem 10vw 1rem 1rem; - cursor: url(/last-museum/static/uploads/3/cursor/The_Last_Museum_-_Symbols-72.png) 50 50, pointer; + font-size: 1.6vw; + padding: 1rem 10vw 1rem 10rem; + cursor: url(/last-museum/static/uploads/3/cursor/The_Last_Museum_-_Symbols-41.png) 50 50, pointer; overflow: auto; } .text-overlay::-webkit-scrollbar { @@ -35,7 +38,8 @@ } .text-overlay h2 { font-family: 'Druk Wide', sans-serif; - font-size: 1.7vw; + font-size: 1.9vw; margin-bottom: 1rem; margin-top: 2rem; + color: #FF790D; } diff --git a/frontend/site/projects/museum/views/text.overlay.js b/frontend/site/projects/museum/views/text.overlay.js index 3584fa3..862e0b2 100644 --- a/frontend/site/projects/museum/views/text.overlay.js +++ b/frontend/site/projects/museum/views/text.overlay.js @@ -62,7 +62,7 @@ class TextOverlay extends Component { render() { const { open, content } = this.state - const { popups, interactive } = this.props + const { popups, interactive, language } = this.props if (!interactive || !content) return null if (content.popup && !popups[content.popup]) return null if (!content.popup && !open) { @@ -84,7 +84,7 @@ class TextOverlay extends Component { ...(content.textStyle || {}), }} onClick={this.toggle} - dangerouslySetInnerHTML={{ __html: content.text }} + dangerouslySetInnerHTML={{ __html: content.text[language] || content.text.en }} /> ) } @@ -92,6 +92,7 @@ class TextOverlay extends Component { const mapStateToProps = state => ({ audio: state.audio, + language: state.site.language, popups: state.site.popups, interactive: state.site.interactive, }) diff --git a/frontend/site/projects/museum/views/titles.css b/frontend/site/projects/museum/views/titles.css index 311fa6f..0b44b48 100644 --- a/frontend/site/projects/museum/views/titles.css +++ b/frontend/site/projects/museum/views/titles.css @@ -8,6 +8,7 @@ font-family: "Druk Wide"; font-size: 1.66vw; transition: opacity 0.5s; + text-align: center; opacity: 0; } diff --git a/frontend/site/projects/museum/views/titles.overlay.js b/frontend/site/projects/museum/views/titles.overlay.js index 169dd85..f82f08a 100644 --- a/frontend/site/projects/museum/views/titles.overlay.js +++ b/frontend/site/projects/museum/views/titles.overlay.js @@ -11,6 +11,8 @@ const HEADPHONES_SHOW_DELAY = 500 const HEADPHONES_HIDE_DELAY = 3000 const TITLE_SHOW_DELAY = 1000 const TITLE_HIDE_DELAY = 6000 +const SUBTITLE_HIDE_DELAY = 1000 + const FIRST_SUBTITLE_DELAY = 3000 const SUBTITLE_DELAY = 3500 const LAST_SUBTITLE_DELAY = 5000 @@ -100,16 +102,27 @@ class TitlesOverlay extends Component { }, HEADPHONES_SHOW_DELAY) } - showTitle() { + showTitle(showSubtitle) { if (!this.titleRef.current) return + let title; + if (showSubtitle) { + title = (this.props.language === 'de' && this.state.content.subtitle_de) || this.state.content.subtitle + } else { + title = (this.props.language === 'en' && this.state.content.subtitle_en) || this.state.content.title + } this.titleRef.current.innerHTML = "" this.titleRef.current.style.color = this.state.content.color || "rgba(255, 121, 13, 1.0)" this.titleRef.current.style.opacity = 0 this.titleTimeout = setTimeout(() => { - this.titleRef.current.innerHTML = this.state.content.title + this.titleRef.current.innerHTML = `<div>${title}</div>` this.titleRef.current.style.opacity = 1 this.titleTimeout = setTimeout(() => { this.titleRef.current.style.opacity = 0 + if (this.state.content.subtitle && !showSubtitle) { + setTimeout(() => { + this.showTitle(true) + }, SUBTITLE_HIDE_DELAY) + } }, TITLE_HIDE_DELAY) }, TITLE_SHOW_DELAY) } @@ -135,6 +148,7 @@ class TitlesOverlay extends Component { const { content, showText } = this.state const { popups, interactive } = this.props if (!interactive || !content) return null + console.log(content) return ( <div> <div @@ -148,9 +162,7 @@ class TitlesOverlay extends Component { <div ref={this.titleRef} className="chapter-title" - > - {this.state.content.title} - </div> + /> <div ref={this.textRef} className={showText ? "charles-text visible" : "charles-text"} @@ -176,6 +188,7 @@ const mapStateToProps = state => ({ audio: state.audio, popups: state.site.popups, interactive: state.site.interactive, + language: state.site.language, }) export default connect(mapStateToProps)(TitlesOverlay) |
