about page added

main
mwinter 2 years ago
parent e823d99bcd
commit a822753cb3

@ -22,7 +22,7 @@
<Icon name="fluent:video-48-filled" color="white" />
</button>
<button @click="modalStore.setModalProps('image', 'aspect-auto', true, 'images', work.image_ids, '')" v-else="type === 'image'" class="inline-flex p-1">
<button @click="modalStore.setModalProps('image', 'aspect-auto', true, 'images', work.gallery, '')" v-else="type === 'image'" class="inline-flex p-1">
<Icon name="mdi:camera" color="white" />
</button>

@ -14,8 +14,8 @@
:modules="[SwiperAutoplay, SwiperPagination, SwiperNavigation]"
>
<SwiperSlide v-for="image_id in image_ids">
<nuxt-img :src="'https://unboundedpress.org/api/' + bucket + '.files/' + image_id + '/binary'"
<SwiperSlide v-for="image in gallery">
<nuxt-img :src="'https://unboundedpress.org/api/' + bucket + '.files/' + image.image_id + '/binary'"
quality="50"/>
</SwiperSlide>
</Swiper>
@ -23,6 +23,6 @@
<script>
export default {
props: ['image_ids', 'bucket']
props: ['gallery', 'bucket']
}
</script>

@ -1,11 +1,11 @@
<template>
<div class="font-thin sticky top-0 bg-white p-2">
<div class="text-5xl p-2"> <NuxtLink to='/'>michael winter</NuxtLink></div>
<div class="text-2xl px-8">
works
events
about
code
<div class="inline-flex text-2xl">
<NuxtLink class="px-8" to='/'>works</NuxtLink>
<NuxtLink class="px-8" to='/events'>events</NuxtLink>
<NuxtLink class="px-8" to='/about'>about</NuxtLink>
<NuxtLink class="px-8" to='https://unboundedpress.org/code'>code</NuxtLink>
</div>
</div>
<slot /> <!-- required here only -->
@ -16,7 +16,7 @@
<Modal v-model="modalStore.isOpen">
<ModalBody :class="modalStore.aspect">
<ImageSlider v-if="modalStore.type === 'image'" :bucket="modalStore.bucket" :image_ids="modalStore.image_ids"></ImageSlider>
<ImageSlider v-if="modalStore.type === 'image'" :bucket="modalStore.bucket" :gallery="modalStore.gallery"></ImageSlider>
<iframe v-if="modalStore.type === 'video'" :src="'https://player.vimeo.com/video/' + modalStore.vimeo_trackid" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</ModalBody>
</Modal>

@ -0,0 +1,72 @@
<template>
<div class="bg-zinc-100 rounded-lg m-5 grid grid-cols-[60%,40%] gap-10 bg-white divide-x divide-solid divide-black p-4">
<div class="px-5 h-[76vh]">
<p class="text-lg">about</p>
<div class="leading-tight py-2 ml-3 text-sm">
<div class="leading-tight py-2">
My work often explores simple processes where dynamic systems, situations, and settings are realized in a variety of ways from performances to installations. To me, everything we experience is computable. Given this digital philosophy, I acknowledge even my most open works as algorithmic; and, while not always apparent on the surface of any given piece, the considerations of computability and epistemology are integral to my practice. I often reconcile epistemological limits with artistic practicality by considering and addressing the limits of computation from an artistic and experiential vantage point and by collaborating with other artists, mathematicians, and scientists in order to integrate objects, ideas, and texts from various domains as structural elements in my pieces.
</div>
<div class="leading-tight py-2">
My work has been presented at venues and festivals throughout the world such as REDCAT, in Los Angeles; the Ostrava Festival of New Music in the Czech Republic; Tsonami Arte Sonoro Festival in Valparaiso, Chile; the Huddersfield New Music Festival in the United Kingdom; and Umbral Sesiones at the Museo de Arte Contemporáneo in Oaxaca, Mexico. Recordings of my music have been released by Another Timbre, New World Records, Edition Wandelweiser, Bahn Mi Verlag, Tsonami Records, and Pogus Productions. From 2018 to 2019, I was a fellow / artist-in-residence at the Akademie Schloss Solitude in Stuttgart, Germany. In 2008, I co-founded <em>the wulf.</em>, a Los Angeles-based organization dedicated to experimental performance and art. As a laboratory and hub for exploring new ideas, <em>the wulf.</em> has become an experiment in alternative communities and economies. Similarly, my work subverts discriminatory conventions and hierarchies by exploring alternative forms of presentation and interaction.
</div>
<br>
<div id="mc_embed_signup">
<form action="https://unboundedpress.us12.list-manage.com/subscribe/post?u=bdadd25738fedf704641f3a80&amp;id=01c5761ebb&amp;f_id=00f143e0f0" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_self">
<label for="mce-EMAIL">subscribe to my mailing list to know about upcoming events</label>
<input id="mce-EMAIL" type="email" value="" name="EMAIL" placeholder="email address" required="" class="email">
<div style="position: absolute; left: -5000px;" aria-hidden="true">
<input type="text" name="b_bdadd25738fedf704641f3a80_01c5761ebb" tabindex="-1" value="">
</div>
<div id="mce-responses" class="clear foot">
<div class="response" id="mce-error-response" style="display:none"></div>
<div class="response" id="mce-success-response" style="display:none"></div>
</div> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div class="clear">
<input id="mc-embedded-subscribe" type="submit" value="subscribe" name="subscribe" class="button">
</div>
</form>
</div>
</div>
</div>
<div>
<ImageSlider bucket="images" :gallery="gallery" class="max-w-[70%]"></ImageSlider>
</div>
</div>
</template>
<script setup>
const { data: images } = await useFetch('https://unboundedpress.org/api/images.files?pagesize=200')
const { data: gallery } = await useFetch('https://unboundedpress.org/api/my_image_gallery?pagesize=200', {
transform: (gallery) => {
for (const item of gallery) {
item.image_id = images.value.find(obj => {return obj.filename === item.image})._id.$oid
}
console.log(gallery)
return gallery //.sort((a,b) => a.priority - b.priority)
}
})
</script>
<style>
#mc_embed_signup form {text-align:left; padding:2px 0 2px 0;}
.mc-field-group { display: inline-block; } /* positions input field horizontally */
#mc_embed_signup input.email {border: 1px solid #ABB0B2; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; color: #343434; background-color: #fff; box-sizing:border-box; height:32px; padding: 0px 0.4em; display: inline-block; margin: 0; width:350px; vertical-align:top;}
#mc_embed_signup label {display:block; padding-bottom:10px;}
#mc_embed_signup .clear {display: inline-block;} /* positions button horizontally in line with input */
#mc_embed_signup .button {font-size: 13px; border: none; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; letter-spacing: .03em; color: #fff; background-color: #aaa; box-sizing:border-box; height:32px; line-height:32px; padding:0 18px; display: inline-block; margin: 0; transition: all 0.23s ease-in-out 0s;}
#mc_embed_signup .button:hover {background-color:#777; cursor:pointer;}
#mc_embed_signup div#mce-responses {float:left; top:-1.4em; padding:0em .5em 0em .5em; overflow:hidden; width:90%;margin: 0 5%; clear: both;}
#mc_embed_signup div.response {margin:1em 0; padding:1em .5em .5em 0; font-weight:bold; float:left; top:-1.5em; z-index:1; width:80%;}
#mc_embed_signup #mce-error-response {display:none;}
#mc_embed_signup #mce-success-response {color:#529214; display:none;}
#mc_embed_signup label.error {display:block; float:none; width:auto; margin-left:1.05em; text-align:left; padding:.5em 0;}
@media (max-width: 768px) {
#mc_embed_signup input.email {width:100%; margin-bottom:5px;}
#mc_embed_signup .clear {display: block; width: 100% }
#mc_embed_signup .button {width: 100%; margin:0; }
}
#mc_embed_signup{clear:left; width:100%;}
</style>

@ -17,7 +17,7 @@
<IconButton :visible="work.vimeo_trackid" type="video" :work="work"></IconButton>
<IconButton :visible="work.image_ids" type="image" :work="work"></IconButton>
<IconButton :visible="work.gallery" type="image" :work="work"></IconButton>
</div>
</div>
@ -53,13 +53,13 @@
<p class="text-lg">releases</p>
<div class="leading-tight py-4 ml-3 text-sm" v-for="item in releases">
<p class="text-center leading-tight py-2">{{ item.title }}</p>
<button @click="modalStore.setModalProps('image', 'aspect-auto', true, 'album_art', [item.album_art_id], '')">
<button @click="modalStore.setModalProps('image', 'aspect-auto', true, 'album_art', [{image_id: item.album_art_id}], '')">
<nuxt-img :src="'https://unboundedpress.org/api/album_art.files/' + item.album_art_id + '/binary'"
quality="50"/>
</button>
<div class="flex place-content-center place-items-center">
<IconButton :visible="item.discogs_id" type="discogs" :work="work" :link="'https://www.discogs.com/release/' + item.discogs_id"></IconButton>
<IconButton :visible="item.buy_link" type="buy" :work="work" :link="item.buy_link"></IconButton>
<IconButton :visible="item.discogs_id" type="discogs" :link="'https://www.discogs.com/release/' + item.discogs_id"></IconButton>
<IconButton :visible="item.buy_link" type="buy" :link="item.buy_link"></IconButton>
</div>
</div>
</div>
@ -75,6 +75,7 @@
const groupBy = (x,f)=>x.reduce((a,b,i)=>((a[f(b,i,x)]||=[]).push(b),a),{});
const isValidUrl = urlString => {
/*
var urlPattern = new RegExp('^(https?:\\/\\/)?'+ // validate protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // validate domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // validate OR ip (v4) address
@ -82,6 +83,10 @@
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // validate query string
'(\\#[-a-z\\d_]*)?$','i'); // validate fragment locator
return !!urlPattern.test(urlString);
*/
var pattern = /^((http|https|ftp):\/\/)/;
return pattern.test(urlString)
}
@ -93,6 +98,7 @@
if(work.score){
work.score = "/scores/" + work.score
}
/*
if(work.images){
let image_ids = [];
for (const image of work.images){
@ -100,6 +106,16 @@
}
work.image_ids = image_ids
}
*/
if(work.images){
let gallery = [];
for (const image of work.images){
gallery.push({
image_id: images.value.find(obj => {return obj.filename === image.filename})._id.$oid,
})
}
work.gallery = gallery
}
}
let res = groupBy(works, work => new Date(work.date.$date).getFullYear())
res = Object.keys(res).map((year) => {

@ -1,14 +1,14 @@
import {defineStore} from "pinia";
export const useModalStore = defineStore("ModalStore", {
state: () => ({"type": "", "aspect":"", "isOpen":false, "bucket":"", "image_ids":"", "vimeo_trackid":""}),
state: () => ({"type": "", "aspect":"", "isOpen":false, "bucket":"", "gallery":"", "vimeo_trackid":""}),
actions: {
setModalProps(type, aspect, isOpen, bucket, image_ids, vimeo_trackid) {
setModalProps(type, aspect, isOpen, bucket, gallery, vimeo_trackid) {
this.type = type
this.aspect = aspect
this.isOpen = isOpen
this.bucket = bucket
this.image_ids = image_ids
this.gallery = gallery
this.vimeo_trackid = vimeo_trackid
}
}

Loading…
Cancel
Save