lipre

Stream text files for live (coding) representations
Log | Files | Refs

App.vue (4031B)


      1 <template>
      2     <v-app>
      3         <v-app-bar app>
      4             <v-tabs v-model="tab">
      5                 <v-tab v-for="filename in filenames" 
      6                        :key="filename"
      7                        style="text-transform: none !important">
      8                     {{filename}}
      9                 </v-tab>
     10             </v-tabs>
     11             <v-spacer/>
     12             <v-icon title="Download ZIP"
     13                     @click="download">mdi-zip-box</v-icon>
     14         </v-app-bar>
     15         <v-main>
     16             <v-alert dense 
     17                      v-if="!connected" 
     18                      :type="connected === null ? 'info' : 'error'"
     19                      :style="connected ? '' : 'cursor: pointer;'"
     20                      @click="connect">
     21                 {{connected === null ? 'Connecting...' : 'No connection - click to retry'}}
     22             </v-alert>
     23             <v-tabs-items v-model="tab">
     24                 <v-tab-item v-for="filename in filenames"
     25                     :transition="false" :reverse-transition="false"
     26                     style="font-family: monospace; margin: 1em; line-height: 1.2" :key="filename">
     27                         <pre><code style="background-color: white; padding: 0">{{files[filename]}}</code></pre>
     28                 </v-tab-item>
     29             </v-tabs-items>
     30         </v-main>
     31     </v-app>
     32 </template>
     33 
     34 <script>
     35 import JSZip from "jszip"
     36 import { saveAs } from "file-saver"
     37 export default {
     38     name: "App",
     39     data() {
     40         return {
     41             tab: null,
     42             files: {},
     43             filenames: [],
     44             connected: null,
     45             ws: null,
     46             follow: true,
     47             zip: new JSZip()
     48         }
     49     },
     50     methods: {
     51         connect() {
     52             this.connected = null
     53             if (!this.roomCode) {
     54                 //this.status = "No room specified" // TODO: Use?
     55                 this.connected = false
     56                 return
     57             }
     58             // Quick fix to determine whether to use WSS or not
     59             let proto = window.location.href.startsWith("https://") ? "wss" : "ws"
     60             let url = `${proto}://${document.location.host}/ws/view/${this.roomCode}`
     61             this.ws = new WebSocket(url)
     62             this.ws.onclose = () => {
     63                 this.connected = false
     64             }
     65             this.ws.onopen = () => {
     66                 this.files = {}
     67                 this.filenames = []
     68                 this.connected = true
     69             }
     70             this.ws.onmessage = (msg) => {
     71                 let fileReceived = JSON.parse(msg.data)
     72                 if (!fileReceived.contents || !fileReceived.contents.length) {
     73                     // null file contents: Remove existing file
     74                     if (this.filenames.includes(fileReceived.name)) {
     75                         this.filenames = this.filenames.filter(fn => fn !== fileReceived.name)
     76                         delete this.files[fileReceived.name]
     77                     }
     78                 } else {
     79                     this.$set(this.files, fileReceived.name, fileReceived.contents)
     80                     if (!this.filenames.includes(fileReceived.name)) {
     81                         this.filenames.push(fileReceived.name)
     82                         hljs.initHighlightingOnLoad()
     83                     }
     84                     if (this.tab === null || this.follow) {
     85                         this.tab = this.filenames.findIndex(fn => fn === fileReceived.name)
     86                     }
     87                 }
     88                 //hljs.highlightBlock(document.getElementById("viewer"))
     89             }
     90         },
     91         download() {
     92             for (let fn in this.files) {
     93                 this.zip.file(fn, this.files[fn])
     94             }
     95             this.zip.generateAsync({type:"blob"}).then(content => {
     96                 saveAs(content, this.roomCode + ".zip")
     97             })
     98         }
     99     },
    100     computed: {
    101         roomCode() {
    102             let qParams = new URLSearchParams(window.location.search)
    103             return qParams.get("r")
    104         }
    105     },
    106     mounted() {
    107         this.connect()
    108     }
    109 }
    110 </script>
    111 
    112 <style>
    113 
    114 </style>