Skip to content

Commit 2c306aa

Browse files
committed
Merge branch 'stage' of https://github.com/vvvv/vvvv.org into stage
2 parents dc857c8 + a59114e commit 2c306aa

63 files changed

Lines changed: 1996 additions & 1383 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,30 @@
1-
# vvvv.org
2-
3-
The new website for vvvv.
4-
5-
Local build:
6-
* [Download Hugo Extended](https://gohugo.io/installation/windows/#prebuilt-binaries), unzip and place that into your programs folder,
7-
* Add it to your path (environment variables),
1+
Source of [vvvv.org](http://vvvv.org)
2+
3+
## Adding a Blog post
4+
5+
- Fork this repository
6+
- Browse [the blog folder](https://github.com/vvvv/vvvv.org/tree/main/content/blog/) to see how existing posts are written
7+
- Create a new folder in the `\{currentYear]\News` or `\{currentYear]\Dates` folder (depending on the type of your post) with a short name describing the post (that folder name is just for the folder structure, no other relevance)
8+
- The only file that is mandatory in your folder is the `index.md` file. Best copy one over from another blogpost and modify it
9+
- For posts of type `date` you need to enter from- and to- dates in unix time, which can be converted to from date using e.g. this [date -> timestamp converter](https://dqydj.com/unix-time-to-date-converter/)
10+
- To preview your post locally, see the section "Local Build" below
11+
- Finally make a pull-request from your fork to this repo
12+
13+
### Shortcodes
14+
For embedding external media use these short codes:
15+
16+
* Mastodon: `{{< mastodon "mastodon.xyz/@vvvv/109598445063555699" 550 >}}` Parameters: Link [Height (default=550)]
17+
* Pixelfed: `{{< pixelfed "pixelfed.social/p/madewithvvvv/509678388578111219" 550 >}}` Parameters: Link [Height (default=550)]
18+
* Vimeo: `{{< vimeo 761078720 >}}` Parameters: Vimeo ID
19+
* Youtube `{{< youtube 761078720 >}}` Parameters: Youtube ID
20+
21+
## Local build:
22+
* [Download Hugo Extended](https://github.com/gohugoio/hugo/releases/tag/v0.145.0), **Version 0.145**, unzip and place that into your programs folder,
23+
* Add it to your path (environment variables)
824
* Powershell:
9-
* cd C:\dev\vvvv.org
10-
* hugo server
25+
* `cd C:\dev\vvvv.org`
26+
* `hugo server`
1127
* Open http://localhost:1313/ in your browser
1228

1329
To run in the browser and to be able to access the site from the same local wifi (eg. checking on mobile), run hugo with:
1430
`hugo serve --bind 0.0.0.0 --baseURL http://IP:1313` where IP is your IP from `ipconfig`
15-
16-
### Blog timecodes
17-
A date blogs from- and to- dates are specified in unix time, which can be converted to from date using e.g. this [date -> timestamp converter](https://dqydj.com/unix-time-to-date-converter/)
18-
19-
### Shortcodes:
20-
21-
__Mastodon:__
22-
{{< mastodon "mastodon.xyz/@vvvv/109598445063555699" 550 >}}
23-
Parameters: Link [Height (default=550)]
24-
25-
__Pixelfed:__
26-
{{< pixelfed "pixelfed.social/p/madewithvvvv/509678388578111219" 550 >}}
27-
Parameters: Link [Height (default=550)]
28-
29-
__Vimeo:__
30-
{{< vimeo 761078720 >}}
31-
Parameters: Vimeo ID
32-
33-
__Youtube:__
34-
{{< youtube 761078720 >}}
35-
Parameters: Youtube ID

community-app/frontend/index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@
5656
</div>
5757
</div>
5858
<div id="community">
59-
<div id="Community-app" class="container"></div>
59+
<div id="Community-app" class="container">
60+
<div class="spinner-border m-4" role="status">
61+
<span class="sr-only">Loading...</span>
62+
</div>
63+
</div>
6064
</div>
6165
<script type="module" src="/src/main.js"></script>
6266
</body>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<script setup>
2+
import { logos } from './logos/logos.js'
3+
import { NIcon, NButton, NDropdown } from 'naive-ui';
4+
import { ChevronDown } from '@vicons/ionicons5';
5+
import { showBusinessProfile, showEduProfile } from "../utils.js"
6+
7+
const props = defineProps(['list', 'options', 'connection', 'type'])
8+
const emit = defineEmits(['change'])
9+
10+
function handleClick(item)
11+
{
12+
if (item.key == 'business')
13+
{
14+
showBusinessProfile(item.slug);
15+
}
16+
else if (item.key == 'edu')
17+
{
18+
showEduProfile(item.slug);
19+
}
20+
}
21+
22+
</script>
23+
24+
<template>
25+
<div>
26+
<table class="table table-borderless">
27+
<thead class="border-bottom">
28+
<tr>
29+
<th scope="col" class="col-4">{{ type}}</th>
30+
<th scope="col" class="col">
31+
<NDropdown trigger="click" :options="options" @select="(key) => emit('change', key)">
32+
<NButton secondary>{{ connection.label }}<NIcon class="ml-4"><ChevronDown/></NIcon></NButton>
33+
</NDropdown></th>
34+
</tr>
35+
</thead>
36+
<tbody v-if="list">
37+
<tr v-for="item in list.items" class="border-bottom">
38+
<td>
39+
<a :href="item.profileLink" @click.prevent="handleClick(item)">{{ item.name }}</a>
40+
</td>
41+
<td>
42+
<a :href="item.connectionLink" target="_blank">
43+
<NIcon class="mr-3"><component :is="logos[connection.key]"/></NIcon>{{ item.label }}
44+
</a>
45+
</td>
46+
</tr>
47+
</tbody>
48+
</table>
49+
</div>
50+
</template>
51+

community-app/frontend/src/components/InstitutionBasics.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const socialKeys = ["website", "github", "nuget", "mastodon", "pixelfed"];
2424

2525
<Internships :data="data" text="Accepting internship applications" :isLink="true"/>
2626

27-
<SocialView class="mt-4 mb-4 pt-3 border-top" v-if="Object.keys(data.social).length>0" :social="data.social" />
27+
<SocialView class="mt-4 py-2 border-top" v-if="Object.keys(data.social).length>0" :social="data.social" />
2828

2929
<Links class="links" :data="data"/>
3030

community-app/frontend/src/components/Links.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ const exists = computed(()=>{
2525
2626
</script>
2727
<template>
28-
<div class="my-3 pt-2 border-top" v-if="exists">
29-
<p class="text-muted mb-2">Direct links:</p>
28+
<div class="mb-3 pt-2 border-top" v-if="exists">
29+
<p class="text-muted mb-2 smallTitle">Direct links</p>
3030
<template v-for="link in links" :key="link.name">
3131
<p v-if="link.url" class="mb-1">
3232
<a :href="link.url" target="_blank">{{ link.name }}</a>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script setup>
2+
import defaultLogo from '../assets/defaultLogo.png'
3+
import Location from "../components/Location.vue"
4+
import { showBusinessProfile } from "../utils.js"
5+
import Internships from '../components/Internships.vue';
6+
7+
const props = defineProps(['list'])
8+
9+
</script>
10+
11+
<template>
12+
<div class="logoListView" v-if="list && list.total > 0">
13+
<p>{{ list.total }} Businesses that use vvvv:</p>
14+
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-4">
15+
<div v-for="item in list.items" track-by="item.name" class="col mb-4">
16+
<div class="companyCard p-3 h-100" @click="(event)=> showBusinessProfile(item.slug, event)">
17+
<div class="company">
18+
<div class="logo">
19+
<img :src="item.logo || defaultLogo"/>
20+
</div>
21+
<p class="name">{{ item.name }}</p>
22+
23+
<Internships :data="item" text="Accepting internship" class="mb-1"/>
24+
<Location :location="{city: item.location_city, country: item.location_country}"/>
25+
</div>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
</template>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script setup>
2+
import { ref, onMounted } from 'vue'
3+
import { useRouter } from 'vue-router'
4+
import { NTooltip, NSkeleton, NBadge, NButton } from "naive-ui"
5+
import { showBusinessProfile } from "../../utils.js"
6+
import { useLastMonthStore } from './LastMonthStore.js'
7+
import defaultLogo from '../../assets/defaultLogo.png'
8+
import SectionTitle from './SectionTitle.vue'
9+
10+
const loading = ref(false);
11+
const router = useRouter();
12+
const isNew = ref(false);
13+
14+
const store = useLastMonthStore();
15+
16+
const oneWeek = 7 * 24 * 60 * 60 * 1000;
17+
18+
onMounted(async ()=>{
19+
20+
try
21+
{
22+
loading.value = true;
23+
await store.fetch();
24+
}
25+
catch (error)
26+
{
27+
console.log (error);
28+
}
29+
finally{
30+
loading.value = false;
31+
}
32+
33+
console.log (Date.now());
34+
console.log (store.date + oneWeek);
35+
36+
isNew.value = store.date ? Date.now() < store.date + oneWeek : false;
37+
38+
})
39+
40+
</script>
41+
42+
<template>
43+
<div v-if="store.link" class="section pr-4 lastMonth">
44+
<div class="row border-bottom pb-3 align-items-start">
45+
<div class="col-1 px-0 py-1">
46+
<NBadge value="new" type="success" :show="isNew">
47+
<img :src="store.thumb" class="img-fluid"/>
48+
</NBadge>
49+
</div>
50+
<div class="col-11 py-0 pl-4 no-gutter">
51+
<strong><a :href="store.link">{{ store.title }}</a></strong>
52+
<div class="text-muted second">{{ store.description }}</div>
53+
</div>
54+
</div>
55+
</div>
56+
</template>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import Constants from "../../constants.js"
2+
import { defineStore } from 'pinia'
3+
4+
const latestMonthThumb = 'https://vvvv.org/img/blog/review-thumb.png';
5+
6+
export const useLastMonthStore = defineStore ('lastMonth',{
7+
state: ()=>{
8+
return {
9+
title: "",
10+
link:"",
11+
thumb:"",
12+
date: null,
13+
description:"",
14+
fetched: false
15+
}
16+
},
17+
actions: {
18+
async fetch(force = false){
19+
20+
if (this.fetched && !force) return;
21+
22+
try{
23+
const rss = await fetchRSS();
24+
this.title = rss.title;
25+
this.link = rss.link;
26+
this.thumb = rss.thumb;
27+
this.fetched = true;
28+
this.description = rss.description;
29+
this.date = new Date(rss.pubDate).getTime()
30+
}
31+
catch (error){
32+
this.fetched = false;
33+
}
34+
35+
}
36+
}
37+
})
38+
39+
async function fetchRSS(){
40+
41+
const url = Constants.OVERVIEW_RSS;
42+
43+
const response = await fetch(url);
44+
45+
if (response.ok)
46+
{
47+
const items = [];
48+
49+
try{
50+
const text = await response.text();
51+
52+
const parser = new DOMParser();
53+
const xmlDoc = parser.parseFromString(text, 'text/xml');
54+
const data = xmlDoc.querySelectorAll('item');
55+
56+
57+
data.forEach(item => (
58+
items.push(
59+
{
60+
title: getItem(item, 'title'),
61+
link: getItem(item, 'link'),
62+
category: getItem(item, 'category'),
63+
thumb: getItem(item, 'thumb'),
64+
description: getItem(item, 'description'),
65+
pubDate: getItem(item, 'pubDate')
66+
}
67+
)
68+
));
69+
}
70+
catch (error)
71+
{
72+
console.log (error);
73+
}
74+
75+
const lastMonth = items.find(i=>i.category=="Monthly Reviews")
76+
77+
return {
78+
title: lastMonth.title,
79+
link: lastMonth.link,
80+
thumb: latestMonthThumb,
81+
description: lastMonth.description,
82+
pubDate: lastMonth.pubDate
83+
}
84+
}
85+
else {
86+
throw Error ("Connection Error");
87+
}
88+
}
89+
90+
function getItem(item, tag)
91+
{
92+
return item.querySelector(tag)?.textContent
93+
}

community-app/frontend/src/components/overview/LatestTopics.vue

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,18 @@ async function sync(force)
4040
<NSkeleton text :repeat="5" class="mb-4 mx-3"></NSkeleton>
4141
</template>
4242
<template v-else>
43-
<ul v-if="store.topics.length > 0" class="list-group list-group-flush list">
44-
<li v-for="(topic, index) in store.topics" :key="index" class="list-group-item d-flex flex-nowrap link">
45-
<NEllipsis :line-clamp="1" :tooltip=false>
46-
<a :href="topic.link" target="_blank">{{ topic.title }}</a>
47-
</NEllipsis>
48-
<NBadge v-if="topic.count>0" :value="topic.count" color="DarkGray" class="ml-2"/>
49-
</li>
50-
</ul>
43+
<table v-if="store.topics.length > 0" class="table table-sm list">
44+
<tr v-for="(topic, index) in store.topics" :key="index" class="link">
45+
<td>
46+
<NEllipsis :line-clamp="1" :tooltip=false>
47+
<a :href="topic.link" target="_blank">{{ topic.title }}</a>
48+
</NEllipsis>
49+
</td>
50+
<td class="pl-3">
51+
<span v-if="topic.count" class="count">{{ topic.count }}</span>
52+
</td>
53+
</tr>
54+
</table>
5155
<div v-else class="m-3">Okay, Houston... we've had a problem here.<br/>Try again later.</div>
5256
</template>
5357
</div>

community-app/frontend/src/components/overview/LatestTopicsStore.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const useLatestTopicsStore = defineStore ('latestTopics',{
2727

2828
async function fetchLatestTopics(){
2929

30-
const count = 7;
30+
const count = 9;
3131
const response = await fetch(Constants.FORUM_TOPICS+`?count=${count}`);
3232

3333
if (response.ok)

0 commit comments

Comments
 (0)