|
1 | 1 | <template> |
2 | | - <div v-if="dataReady && !error"> |
3 | | - <div class="px-small py-xsmall bg-black row between"> |
| 2 | + <div> |
| 3 | + <div class="px-small py-xsmall row between"> |
4 | 4 | <div> |
5 | | - <button class="theme small type-small mr-small" :class="selectedDay === 1 && 'active'" @click="selectedDay = 1">Day 1</button> |
6 | | - <button class="theme small type-small" :class="selectedDay === 2 && 'active'" @click="selectedDay = 2">Day 2</button> |
| 5 | + <button class="theme mr-small" :class="selectedDay === 1 && 'active'" @click="selectedDay = 1">Day 1</button> |
| 6 | + <button class="theme" :class="selectedDay === 2 && 'active'" @click="selectedDay = 2">Day 2</button> |
7 | 7 | </div> |
8 | | - <button @click="chatShown = !chatShown" class="theme small type-small"> |
9 | | - {{ chatShown ? 'Hide Q&A' : 'Show Q&A' }} |
| 8 | + <button @click="showChat = !showChat" class="theme small type-small"> |
| 9 | + {{ showChat ? 'Hide Q&A' : 'Show Q&A' }} |
10 | 10 | </button> |
11 | 11 | </div> |
12 | 12 | <div class="stream-container" :class="isFullScreen && 'fullscreen'"> |
13 | | - <iframe class="stream col-sm-12" :class="chatShown && 'col-md-9'" :src=streamUrl title="Robocon stream" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> |
14 | | - <iframe v-show="chatShown" class="chat col-sm-12 col-md-3" :src=chatUrl frameBorder="0" title="Stream chat"></iframe> |
| 13 | + <iframe class="stream col-sm-12" :class="showChat && 'col-md-9'" :src=streamUrl title="Robocon stream" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> |
| 14 | + <iframe v-show="showChat" class="chat col-sm-12 col-md-3" :src=chatUrl frameBorder="0" title="Stream chat"></iframe> |
15 | 15 | </div> |
16 | 16 | </div> |
17 | 17 | <h1 v-if="dataReady && error" class="color-white mt-2xlarge type-center type-xlarge"> |
|
20 | 20 | <span class="color-theme">AUTH</span> |
21 | 21 | </h1> |
22 | 22 | <div v-if="!isFullScreen" class="container narrow"> |
23 | | - <talks24 :hashKey="token.hashKey" :speakers="[speakers]" /> |
| 23 | + <PretalxSchedule :content="{url: 'https://pretalx.com/api/events/robocon-2025/schedules/latest/'}" /> |
24 | 24 | </div> |
25 | 25 | </template> |
26 | 26 |
|
27 | | -<script> |
28 | | -import { Talks24 } from 'Components' |
29 | | -import CryptoJS from 'crypto-js' |
30 | | -import * as jose from 'jose' |
31 | | -export default { |
32 | | - components: { |
33 | | - Talks24 |
34 | | - }, |
35 | | - data: () => ({ |
36 | | - selectedDay: 2, |
37 | | - day1: 'U2FsdGVkX1+iO3u49D3q6rlcds7ZJOz4N8+vuQz+VYo=', |
38 | | - day2: 'U2FsdGVkX19TiGQLj7xCUJBO02Zg78fjU1zyOE64GsQ=', |
39 | | - chat: 'U2FsdGVkX1/BKQP6AzzQFrb28NyI/BbFuQvgO4Ipq6RMnvdrRMI/qd0Lwxi4grBNerT48tEJF/IKMcxZYMzdrA==', |
40 | | - token: {}, |
41 | | - public: `-----BEGIN PUBLIC KEY----- |
42 | | -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1RHu1qgXJ81+2tlBy4UF |
43 | | -B8OdRsBjWhswMQaS/NhA2yWBaQiQ1YG4Tzen2aNmlTIkTBhSR3hqOnkzPQq77nMs |
44 | | -KP9HD1WHz/UNici/a/2UwXFy9bOyX+GKnPCtdcvZrIougvW5K7EBeUWcgY68xNQk |
45 | | -V9vFq4GSczOud7juk62eqqV26esV5tE2c4/J714SYwUl6NqLc7XeQNZMrsRHabIL |
46 | | -Bzg+A+2kw1jiJpJsJliPCT9T/NiAMrbZk1KR/NQ7uHARclAk13LwLwm5JfOhyKSs |
47 | | -Qkdfr8rVYuj3DDQCitea269Xy5RsFW/Cqyh3gHzt7bB9auU3UFaAXWPvnPURhTO4 |
48 | | -Yf3c7YrizmpTfDGPIG/7zkegx9nPiBPNIGPq/LpmCC9iawNH7ixOH8ZC5Ijrti0b |
49 | | -8rMnuJBKysZxIowJAFvd7Zh+soekUei90qQnYwhFO49h7fwXXSq2sGeRfpg99Nu/ |
50 | | -RdqqxM2zCMPpVMWHjxAVIubgNW5ZA33PW1wS075npC3oK+YUh2xt/9A6Ll4AcAOt |
51 | | -oaCmENEyeZEnHlaEWeXhNPQv1/nZN5Z3Fq3uKWCQRry1HMoOGKrdATfUUIXc6vvk |
52 | | -nRPuT57RDafiyxjektPLx0z2LvRZZb7lU5G9/+rO2yJ1f65Sd5k0drIb48YZ+OBj |
53 | | -6IrJDlqg3BaMV5Hr8LdQtY8CAwEAAQ== |
54 | | ------END PUBLIC KEY-----`, |
55 | | - dataReady: false, |
56 | | - error: false, |
57 | | - chatShown: true, |
58 | | - speakers: [] |
59 | | - }), |
60 | | - computed: { |
61 | | - streamUrl() { |
62 | | - const url = this.selectedDay === 1 ? this.day1 : this.day2 |
63 | | - const code = CryptoJS.AES.decrypt(url, this.token.liveHash).toString(CryptoJS.enc.Utf8) |
64 | | - return `https://www.youtube.com/embed/${code}?rel=0&autoplay=1&mute=0&controls=1&origin=https%3A%2F%2Frobocon.io&playsinline=0&showinfo=0&modestbranding=1` |
65 | | - }, |
66 | | - chatUrl() { |
67 | | - return CryptoJS.AES.decrypt(this.chat, this.token.liveHash).toString(CryptoJS.enc.Utf8) |
68 | | - }, |
69 | | - isFullScreen() { |
70 | | - return this.token.name === 'gather' |
71 | | - } |
72 | | - }, |
73 | | - async created() { |
74 | | - const today = new Date() |
75 | | - if (today.getDate() === 29 && today.getMonth() === 2) { |
76 | | - this.selectedDay = 2 |
77 | | - } |
78 | | - const params = new URLSearchParams(window.location.search) |
79 | | - const auth = Object.fromEntries(params.entries()).auth || window.localStorage.getItem('auth') |
80 | | - const attendee = Object.fromEntries(params.entries()).attendee || window.localStorage.getItem('attendee') |
81 | | - if (typeof auth !== 'undefined' && typeof attendee !== 'undefined') { |
82 | | - window.history.replaceState({}, document.title, '/stream' + window.location.hash) |
83 | | - if (attendee !== 'gather') { |
84 | | - window.localStorage.setItem('auth', auth) |
85 | | - window.localStorage.setItem('attendee', attendee) |
86 | | - } |
87 | | - try { |
88 | | - const { payload } = await jose.jwtVerify(auth, await jose.importSPKI(this.public, 'RS256'), { |
89 | | - issuer: 'pretix' |
90 | | - }) |
91 | | - this.token = payload |
92 | | - if (payload.name !== attendee) { |
93 | | - console.log('invalid Attendee') |
94 | | - this.error = true |
95 | | - } |
96 | | - } catch (error) { |
97 | | - this.error = true |
98 | | - console.error(error) |
99 | | - } |
100 | | - } |
101 | | - this.dataReady = true |
102 | | - Promise.all([ |
103 | | - fetch('https://cfp.robocon.io/api/events/robocon-2024/submissions/'), |
104 | | - fetch('https://cfp.robocon.io/api/events/robocon-2024/submissions/?offset=25'), |
105 | | - fetch('https://cfp.robocon.io/api/events/robocon-2024/submissions/?offset=50') |
106 | | - ]) |
107 | | - .then(async([first, second, third]) => { |
108 | | - const f = await first.json() |
109 | | - const s = await second.json() |
110 | | - const t = await third.json() |
111 | | - const arr = [...f.results, ...s.results, ...t.results] |
112 | | - this.speakers = arr.flatMap(({ speakers }) => speakers) |
113 | | - }) |
114 | | - } |
115 | | -} |
| 27 | +<script setup lang="ts"> |
| 28 | +import PretalxSchedule from 'Components/PretalxSchedule.vue'; |
| 29 | +import { useStore } from 'Store'; |
| 30 | +import { decrypt, getVideoUrl } from 'Utils/ticket'; |
| 31 | +import { computed, ref } from 'vue'; |
| 32 | +
|
| 33 | +const day1 = 'U2FsdGVkX1+iO3u49D3q6rlcds7ZJOz4N8+vuQz+VYo=' |
| 34 | +const day2 = 'U2FsdGVkX19TiGQLj7xCUJBO02Zg78fjU1zyOE64GsQ=' |
| 35 | +const chat = 'U2FsdGVkX1/BKQP6AzzQFrb28NyI/BbFuQvgO4Ipq6RMnvdrRMI/qd0Lwxi4grBNerT48tEJF/IKMcxZYMzdrA==' |
| 36 | +
|
| 37 | +const selectedDay = ref(1) |
| 38 | +const showChat = ref(true) |
| 39 | +const selectedStream = ref<string>(null!) |
| 40 | +
|
| 41 | +selectedStream.value = day1 |
| 42 | +
|
| 43 | +const streamUrl = computed(() => getVideoUrl(selectedStream.value)) |
| 44 | +const chatUrl = computed(() => decrypt(chat)) |
| 45 | +
|
| 46 | +const store = useStore() |
| 47 | +const isFullScreen = store.name === 'gather' |
| 48 | +
|
116 | 49 | </script> |
117 | 50 |
|
118 | 51 | <style scoped> |
|
0 commit comments