Browse Source

openai in circles

develop
dskvr 2 years ago
parent
commit
3b5bab3ed8
  1. 1
      css.loaderOptions.sass
  2. 4
      package.json
  3. 12
      postcss.config.js
  4. 0
      src/components/TaskManager.vue
  5. 43
      src/components/relays/ListClearnet.vue
  6. 9
      src/components/relays/RefreshComponent.vue
  7. 6
      src/components/relays/SingleClearnet.vue
  8. 0
      src/components/relays/TaskQueue.vue
  9. 69
      src/components/relays/ToolFilter.vue
  10. 13
      src/store/index.js
  11. 47
      src/store/tasks.js
  12. 621
      src/styles/main.scss
  13. 3
      tailwind.config.js
  14. 75
      vue.config.js
  15. 63
      webpack.config.js

1
css.loaderOptions.sass

@ -0,0 +1 @@
css.loaderOptions.sass

4
package.json

@ -38,6 +38,8 @@
"onion-regex": "2.0.8", "onion-regex": "2.0.8",
"pinia": "2.0.28", "pinia": "2.0.28",
"pinia-plugin-persistedstate-2": "2.0.8", "pinia-plugin-persistedstate-2": "2.0.8",
"pinia-shared-state": "0.2.10",
"postcss-apply": "0.12.0",
"requests": "0.3.0", "requests": "0.3.0",
"socks-proxy-agent": "7.0.0", "socks-proxy-agent": "7.0.0",
"stream-browserify": "3.0.0", "stream-browserify": "3.0.0",
@ -70,7 +72,9 @@
"json-server": "0.17.1", "json-server": "0.17.1",
"mini-css-extract-plugin": "2.7.2", "mini-css-extract-plugin": "2.7.2",
"node-polyfill-webpack-plugin": "2.0.1", "node-polyfill-webpack-plugin": "2.0.1",
"node-sass": "8.0.0",
"postcss": "8.4.20", "postcss": "8.4.20",
"postcss-loader": "7.0.2",
"postcss-preset-env": "7.8.3", "postcss-preset-env": "7.8.3",
"sass": "1.56.1", "sass": "1.56.1",
"sass-loader": "13.2.0", "sass-loader": "13.2.0",

12
postcss.config.js

@ -1,6 +1,8 @@
module.exports = { module.exports = {
plugins: { plugins: [
tailwindcss: {}, require('postcss-import'),
autoprefixer: {}, require('tailwindcss'),
} require('autoprefixer'),
require('postcss-apply')
]
} }

0
src/components/TaskManager.vue

43
src/components/relays/ListClearnet.vue

@ -41,7 +41,7 @@
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200 bg-white"> <tbody class="divide-y divide-gray-200 bg-white">
<tr v-for="(relay, index) in subsectionRelays" :key="relay" class="bg-gray-50 hover:bg-slate-200" :class="getResultClass(relay, index)"> <tr v-for="(relay, index) in subsectionRelays" :key="relay" :class="getResultClass(relay, index)">
<td class="status-indicator" :key="generateKey(relay, 'aggregate')"> <td class="status-indicator" :key="generateKey(relay, 'aggregate')">
<span :class="results[relay]?.aggregate" class="aggregate indicator"> <span :class="results[relay]?.aggregate" class="aggregate indicator">
<span></span> <span></span>
@ -64,17 +64,26 @@
<td class="latency text-center"> <td class="latency text-center">
<span>{{ results[relay]?.latency?.final }}<span v-if="results[relay]?.check?.latency">ms</span></span> <span>{{ results[relay]?.latency?.final }}<span v-if="results[relay]?.check?.latency">ms</span></span>
</td> </td>
<!-- .indicator {
display:block;
margin: 0 auto;
height: 14px;
width: 14px;
border-radius: 7px;
border-width:0px;
} -->
<td class="connect text-center" :key="generateKey(relay, 'check.connect')"> <td class="connect text-center" :key="generateKey(relay, 'check.connect')">
<span :class="getIndicatorClass(relay, 'connect')"></span> <span :class="getIndicatorClass(relay, 'connect')" class="indicator"></span>
</td> </td>
<td class="read text-center" :key="generateKey(relay, 'check.read')"> <td class="read text-center" :key="generateKey(relay, 'check.read')">
<span :class="getIndicatorClass(relay, 'read')"></span> <span :class="getIndicatorClass(relay, 'read')" class="indicator"></span>
</td> </td>
<td class="write text-center" :key="generateKey(relay, 'check.write')"> <td class="write text-center" :key="generateKey(relay, 'check.write')">
<span :class="getIndicatorClass(relay, 'write')"></span> <span :class="getIndicatorClass(relay, 'write')" class="indicator"></span>
</td> </td>
<td class="fav text-center" :key="generateKey(relay, 'check.write')"> <td class="fav text-center" :key="generateKey(relay, 'check.write')">
@ -186,6 +195,8 @@
return { return {
loaded: this.results[relay]?.state == 'complete', loaded: this.results[relay]?.state == 'complete',
'bg-slate-100': index % 2, 'bg-slate-100': index % 2,
'bg-red-50 hover:bg-red-100': this.store.relays.isFavorite(relay),
'bg-gray-50 hover:bg-slate-200': !this.store.relays.isFavorite(relay),
} }
} }
}, },
@ -194,13 +205,15 @@
}, },
getIndicatorClass(){ getIndicatorClass(){
return (relay, key) => { return (relay, key) => {
let cl = this.results[relay]?.check?.[key] === true return {
? 'success' // 'bg-green-500': this.results[relay]?.check?.[key] !== false,
: this.results[relay]?.check?.[key] === false // 'bg-red-500': this.results[relay]?.check?.[key] === false,
? 'failure' // 'bg-gray-500': 'undefined' === typeof this.results[relay]?.check?.[key]
: 'pending' 'success': this.results[relay]?.check?.[key] !== false,
return `indicator ${cl}` 'failure': this.results[relay]?.check?.[key] === false,
} 'pending': 'undefined' === typeof this.results[relay]?.check?.[key]
}
}
}, },
generateKey(){ generateKey(){
return (url, key) => crypto.createHash('md5').update(`${url}_${key}`).digest('hex') return (url, key) => crypto.createHash('md5').update(`${url}_${key}`).digest('hex')
@ -243,8 +256,16 @@
methods: Object.assign(RelaysLib, localMethods), methods: Object.assign(RelaysLib, localMethods),
}) })
</script> </script>
<style lang=postcss>
.indicator {
@apply h-4 w-4 block rounded-lg
}
</style>
<style lang='css' scoped> <style lang='css' scoped>
table { table {
border-collapse: collapse !important; border-collapse: collapse !important;
} }

9
src/components/relays/RefreshComponent.vue

@ -40,7 +40,7 @@ const localMethods = {
setRefreshInterval: function(){ setRefreshInterval: function(){
clearInterval(this.interval) clearInterval(this.interval)
this.interval = setInterval(() => { this.interval = setInterval(() => {
if(!this.store.prefs.refresh || !this.windowActive ) if(!this.store.prefs.refresh )
return return
this.untilNext = this.timeUntilRefresh() this.untilNext = this.timeUntilRefresh()
@ -51,7 +51,6 @@ const localMethods = {
}, 1000) }, 1000)
}, },
refreshNow(){ refreshNow(){
this.disabled = true
this.invalidate(true) this.invalidate(true)
}, },
handleVisibility(){ handleVisibility(){
@ -181,15 +180,13 @@ export default defineComponent({
}, },
unmounted(){ unmounted(){
clearInterval(this.interval) clearInterval(this.interval)
// document.removeEventListener("visibilitychange", this.handleVisibility, false);
}, },
beforeMount(){ beforeMount(){
this.untilNext = this.timeUntilRefresh() this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh() this.sinceLast = this.timeSinceRefresh()
}, },
mounted(){ mounted(){
if(!this.windowActive)
return
this.relays = this.store.relays.getAll this.relays = this.store.relays.getAll
this.lastUpdate = this.store.relays.lastUpdate this.lastUpdate = this.store.relays.lastUpdate
@ -202,7 +199,6 @@ export default defineComponent({
}, },
updated(){}, updated(){},
computed: Object.assign(SharedComputed, { computed: Object.assign(SharedComputed, {
getDynamicTimeout: function(){ getDynamicTimeout: function(){
return this.averageLatency*this.relays.length return this.averageLatency*this.relays.length
}, },
@ -225,7 +221,6 @@ export default defineComponent({
lastUpdate: null, lastUpdate: null,
sinceLast: null, sinceLast: null,
interval: null, interval: null,
disabled: true,
windowActive: true, windowActive: true,
averageLatency: 200 averageLatency: 200
} }

6
src/components/relays/SingleClearnet.vue

@ -24,15 +24,15 @@
</td> </td>
<td class="connect text-center" :key="generateKey(relay, 'check.connect')"> <td class="connect text-center" :key="generateKey(relay, 'check.connect')">
<span :class="getIndicatorClass(relay, 'connect')"></span> <span :class="getIndicatorClass(relay, 'connect')">Connect</span>
</td> </td>
<td class="read text-center" :key="generateKey(relay, 'check.read')"> <td class="read text-center" :key="generateKey(relay, 'check.read')">
<span :class="getIndicatorClass(relay, 'read')"></span> <span :class="getIndicatorClass(relay, 'read')">Read</span>
</td> </td>
<td class="write text-center" :key="generateKey(relay, 'check.write')"> <td class="write text-center" :key="generateKey(relay, 'check.write')">
<span :class="getIndicatorClass(relay, 'write')"></span> <span :class="getIndicatorClass(relay, 'write')">write</span>
</td> </td>
<td class="fav text-center" :key="generateKey(relay, 'check.write')"> <td class="fav text-center" :key="generateKey(relay, 'check.write')">

0
src/components/relays/TaskQueue.vue

69
src/components/relays/ToolFilter.vue

@ -0,0 +1,69 @@
<template>
<div class="w-full max-w-lg lg:max-w-xs">
<label for="relay-filter" class="sr-only">Filter Relays</label>
<div class="relative">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<MagnifyingGlassIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
<input
id="relay-filter"
name="relay-filter"
placeholder="Filter Relays" type="search"
class="block w-full rounded-md border border-gray-300 bg-white py-2 pl-10 pr-3 leading-5 placeholder-gray-500 focus:border-indigo-500 focus:placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm"
/>
</div>
</div>
</template>
<script>
//vue
import { defineComponent } from 'vue'
//pinia
import { setupStore } from '@/store'
//shared methods
import RelaysLib from '@/shared/relays-lib.js'
//theme
import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid'
const localMethods = {
toggle() {
this.isActive = !this.isActive;
},
clearData(){
this.store.relays.clearResults()
}
}
export default defineComponent({
name: 'ToolFilter',
components: {
MagnifyingGlassIcon
},
setup(){
return {
store : setupStore()
}
},
mounted(){
// this.preferences = this
},
updated(){
// this.setCache('preferences')
},
computed: {},
methods: Object.assign(localMethods, RelaysLib),
props: {},
data() {
return {
storage: null,
refresh: true,
preferences: {
refresh: true,
cacheExpiration: 30*60*1000
},
isActive: false,
}
},
})
</script>

13
src/store/index.js

@ -1,5 +1,6 @@
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import { createPersistedStatePlugin } from 'pinia-plugin-persistedstate-2' import { createPersistedStatePlugin } from 'pinia-plugin-persistedstate-2'
import { PiniaSharedState } from 'pinia-shared-state';
import { useRelaysStore } from './relays.js' import { useRelaysStore } from './relays.js'
import { usePrefsStore } from './prefs.js' import { usePrefsStore } from './prefs.js'
@ -14,6 +15,18 @@ export const plugin = (app) => {
const installPersistedStatePlugin = createPersistedStatePlugin() const installPersistedStatePlugin = createPersistedStatePlugin()
pinia.use((context) => installPersistedStatePlugin(context)) pinia.use((context) => installPersistedStatePlugin(context))
// Pass the plugin to your application's pinia plugin
pinia.use(
PiniaSharedState({
// Enables the plugin for all stores. Defaults to true.
enable: true,
// If set to true this tab tries to immediately recover the shared state from another tab. Defaults to true.
initialize: false,
// Enforce a type. One of native, idb, localstorage or node. Defaults to native.
type: 'localstorage',
}),
);
app.use(pinia) app.use(pinia)
} }

47
src/store/tasks.js

@ -2,16 +2,61 @@ import { defineStore } from 'pinia'
export const useTaskStore = defineStore('tasks', { export const useTaskStore = defineStore('tasks', {
state: () => ({ state: () => ({
//queue
pending: new Array(),
completed: new Array(),
active: new Object(),
//legacy
processing: false, processing: false,
processedRelays: new Array(), processedRelays: new Array(),
currentTask: null currentTask: null
}), }),
getters: { getters: {
//legacy
getProcessedRelays: (state) => Array.from(state.processedRelays), getProcessedRelays: (state) => Array.from(state.processedRelays),
isProcessing: (state) => state.processing, isProcessing: (state) => state.processing,
isRelayProcessed: (state) => (relay) => state.processedRelays.includes(relay) isRelayProcessed: (state) => (relay) => state.processedRelays.includes(relay),
//queue/lists
getPending: (state) => state.pending,
getActive: (state) => state.active,
getCompleted: (state) => state.completed,
//queue/states
isActive: (state) => Object.keys( state.active ).length > 0,
isIdle: (state) => Object.keys( state.active ).length == 0,
arePending: (state) => state.pending.length > 0,
}, },
actions: { actions: {
//queue
addJob(job){
this.pending.push(job)
if( this.isIdle )
this.startNextJob()
},
startNextJob(){
if( this.isActive )
this.completed.push(this.active)
if( this.arePending ) {
this.active = this.pending[0]
this.pending.shift()
}
else {
this.active = {}
}
},
clearJobs(type){
this[type] = new Array()
},
cancelJob( id ){
const index = this.pending.findIndex( job => job.id === id )
this.removeJob( index )
},
removeJob( index ){
this.pending.splice( index, 1 )
},
//legacy
addProcessedRelay(relay){ addProcessedRelay(relay){
if(!this.processedRelays.includes(relay)) if(!this.processedRelays.includes(relay))
this.processedRelays.push(relay) this.processedRelays.push(relay)

621
src/styles/main.scss

@ -4,332 +4,329 @@
@tailwind utilities; @tailwind utilities;
td ul { padding:0; margin:0; list-style: none; } // td ul { padding:0; margin:0; list-style: none; }
td ul li { list-style: none; } // td ul li { list-style: none; }
.q-tabs { // .q-tabs {
border-bottom: 1px solid var(--q-accent) // border-bottom: 1px solid var(--q-accent)
} // }
table { // table {
width:100%; // width:100%;
} // }
.left-align { // .left-align {
text-align:left; // text-align:left;
} // }
tr.relay td { // tr.relay td {
font-style: italic; // font-style: italic;
opacity: 0.5; // opacity: 0.5;
} // }
tr.relay.loaded td { // tr.relay.loaded td {
font-style: normal; // font-style: normal;
opacity: 1; // opacity: 1;
} // }
.indicator { // // .indicator {
display:block; // // display:block;
margin: 0 auto; // // margin: 0 auto;
height: 14px; // // height: 14px;
width: 14px; // // width: 14px;
border-radius: 7px; // // border-radius: 7px;
border-width:0px; // // border-width:0px;
} // // }
.badge { // .badge {
height:auto; // height:auto;
width: auto; // width: auto;
display:inline-block; // display:inline-block;
padding: 2px 5px; // padding: 2px 5px;
font-size: 15px; // font-size: 15px;
position: relative; // position: relative;
top: -3px; // top: -3px;
min-width: 15px; // min-width: 15px;
margin-right:5px; // margin-right:5px;
} // }
.public .badge, // .public .badge,
.offline .badge { // .offline .badge {
color: white; // color: white;
} // }
.public.online .badge { // .public.online .badge {
background:green // background:green
} // }
.restricted.online .badge { // .restricted.online .badge {
background:orange // background:orange
} // }
.offline .badge { // .offline .badge {
background:red // background:red
} // }
tr.online .indicator.failure { // tr.online .indicator.failure {
background-color:orange !important; // background-color:orange !important;
} // }
.aggregate.indicator { // .aggregate.indicator {
background-color: transparent; // background-color: transparent;
border-radius: 0px; // border-radius: 0px;
border-style: solid; // border-style: solid;
} // }
.indicator.pending { // .indicator.pending {
background-color: #c0c0c0; // background-color: #c0c0c0;
border-color: rgba(55,55,55,0.5); // border-color: rgba(55,55,55,0.5);
} // }
.indicator.success { // .indicator.success {
background-color: green; // background-color: green;
border-color: rgba(0,255,0,0.5); // border-color: rgba(0,255,0,0.5);
} // }
.indicator.failure { // .indicator.failure {
background-color: red; // background-color: red;
border-color: rgba(255,0,0,0.5); // border-color: rgba(255,0,0,0.5);
} // }
.indicator.caution { // .indicator.caution {
background-color: orange; // background-color: orange;
border-color: rgba(255, 191, 0,0.5); // border-color: rgba(255, 191, 0,0.5);
} // }
.indicator.public { // .indicator.public {
background-color: green; // background-color: green;
border-color: rgba(0,255,0,0.5); // border-color: rgba(0,255,0,0.5);
} // }
.indicator.restricted {
position:relative;
border-color: transparent;
background-color: transparent
}
.indicator.restricted span:first-child {
position:absolute;
width: 0;
height: 0;
border-top: 14px solid green;
border-right: 14px solid transparent;
}
.indicator.restricted span:last-child {
position:absolute;
width: 0;
height: 0;
border-bottom: 14px solid orange;
border-left: 14px solid transparent;
}
//
// .indicator.restricted { // .indicator.restricted {
// position:relative; // position:relative;
// border-color: transparent; // border-color: transparent;
// background-color: transparent // background-color: transparent
// } // }
//
// .indicator.restricted span:first-child { // .indicator.restricted span:first-child {
// position:absolute; // position:absolute;
// width: 0; // width: 0;
// height: 0; // height: 0;
// border-bottom: 14px solid orange; // border-top: 14px solid green;
// border-left: 14px solid transparent; // border-right: 14px solid transparent;
// } // }
//
// .indicator.restricted span:last-child { // .indicator.restricted span:last-child {
// position:absolute; // position:absolute;
// width: 0; // width: 0;
// height: 0; // height: 0;
// border-top: 14px solid green; // border-bottom: 14px solid orange;
// border-right: 14px solid transparent; // border-left: 14px solid transparent;
// } // }
.indicator.offline { // //
background-color: red; // // .indicator.restricted {
border-color: rgba(255,0,0,0.5); // // position:relative;
} // // border-color: transparent;
// // background-color: transparent
tr.online .relay-url { // // }
cursor: pointer; // //
} // // .indicator.restricted span:first-child {
// // position:absolute;
// // width: 0;
// // height: 0;
// // border-bottom: 14px solid orange;
.verified-shape-wrapper { // // border-left: 14px solid transparent;
display:inline-block; // // }
width: 16px; // //
height: 16px; // // .indicator.restricted span:last-child {
} // // position:absolute;
// // width: 0;
.shape.verified { // // height: 0;
background: #777; // // border-top: 14px solid green;
width: 16px; // // border-right: 14px solid transparent;
height: 16px; // // }
position: relative;
top: 5px; // .indicator.offline {
left:-5px; // background-color: red;
text-align: center; // border-color: rgba(255,0,0,0.5);
} // }
th .shape.verified:before, // tr.online .relay-url {
th .shape.verified:after { // cursor: pointer;
background:#c0c0c0 !important; // }
}
.shape.verified:before, // .verified-shape-wrapper {
.shape.verified:after { // display:inline-block;
content: ""; // width: 16px;
position: absolute; // height: 16px;
top: 0; // }
left: 0;
height: 13px; // .shape.verified {
width: 13px; // background: #777;
background: #777; // width: 16px;
} // height: 16px;
.shape.verified:before { // position: relative;
transform: rotate(30deg); // top: 5px;
} // left:-5px;
.shape.verified:after { // text-align: center;
transform: rotate(75deg); // }
}
// th .shape.verified:before,
.credit { // th .shape.verified:after {
display:inline-block; // background:#c0c0c0 !important;
// }
color:#333; // .shape.verified:before,
text-transform: lowercase; // .shape.verified:after {
font-size:12px; // content: "";
margin-top:25px; // position: absolute;
} // top: 0;
// left: 0;
.credit a { // height: 13px;
text-decoration:none; // width: 13px;
} // background: #777;
// }
// #wrapper { // .shape.verified:before {
// max-width:1400px; // transform: rotate(30deg);
// margin:0 auto; // }
// } // .shape.verified:after {
// transform: rotate(75deg);
div.block { // }
display:block;
margin:40px 0; // .credit {
} // display:inline-block;
h1 { // color:#333;
position:relative; // text-transform: lowercase;
display:inline-block; // font-size:12px;
margin: 0 auto // margin-top:25px;
} // }
h1 sup { // .credit a {
color: #c0c0c0; // text-decoration:none;
font-size:15px; // }
position:absolute;
right: -45px; // // #wrapper {
top:15px; // // max-width:1400px;
} // // margin:0 auto;
// // }
.title-card {
text-align:center; // div.block {
} // display:block;
// margin:40px 0;
.title-card h1 { // }
font-size:4.5em;
text-align:center; // h1 {
} // position:relative;
// display:inline-block;
.row { // margin: 0 auto
-webkit-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16); // }
-moz-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16); // h1 sup {
} // color: #c0c0c0;
// font-size:15px;
.title-info-card { // position:absolute;
border-radius: 20px; // right: -45px;
text-align:center; // top:15px;
} // }
.title-info-card span { // .title-card {
display:inline-block; // text-align:center;
margin-top:0.80em; // }
font-size: 4em;
letter-spacing: -0.1em; // .title-card h1 {
text-align:right; // font-size:4.5em;
} // text-align:center;
// }
.processing-card {
margin: 0.8em 0; // .row {
display:block; // -webkit-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
margin:1.5em 0; // -moz-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
font-size: 4em; // box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
letter-spacing: -0.1em; // }
text-align:center;
} // .title-info-card {
// border-radius: 20px;
// text-align:center;
.loading { // }
animation-duration: 1.8s;
animation-fill-mode: forwards; // .title-info-card span {
animation-iteration-count: infinite; // display:inline-block;
animation-name: placeHolderShimmer; // margin-top:0.80em;
animation-timing-function: linear; // font-size: 4em;
background: #f6f7f8; // letter-spacing: -0.1em;
background: linear-gradient(to right, #fafafa 8%, #f4f4f4 38%, #fafafa 54%); // text-align:right;
background-size: 1000px 640px; // }
position: relative
} // .processing-card {
// margin: 0.8em 0;
.loaded .loading { // display:block;
animation: none; // margin:1.5em 0;
bakground:none; // font-size: 4em;
display:none; // letter-spacing: -0.1em;
} // text-align:center;
// }
@keyframes placeHolderShimmer{
0%{
background-position: -468px 0 // .loading {
} // animation-duration: 1.8s;
100%{ // animation-fill-mode: forwards;
background-position: 468px 0 // animation-iteration-count: infinite;
} // animation-name: placeHolderShimmer;
} // animation-timing-function: linear;
// background: #f6f7f8;
li.observation { // background: linear-gradient(to right, #fafafa 8%, #f4f4f4 38%, #fafafa 54%);
display: inline; // background-size: 1000px 640px;
cursor: pointer; // position: relative
} // }
tr.offline .verified, tr.offline .verified *, // .loaded .loading {
tr.offline .latency, // animation: none;
tr.offline .nip, // bakground:none;
tr.offline .location { // display:none;
visibility: hidden; // }
}
// @keyframes placeHolderShimmer{
// 0%{
@media only screen and (min-device-width: 640px) // background-position: -468px 0
and (max-device-width: 480px) // }
and (orientation: portrait) { // 100%{
// background-position: 468px 0
table .latency, // }
table .verified, // }
table .nip {
display: none; // li.observation {
} // display: inline;
// cursor: pointer;
} // }
@media only screen and (min-device-width: 640px) // tr.offline .verified, tr.offline .verified *,
and (max-device-width: 480px) // tr.offline .latency,
and (orientation: landscape) { // tr.offline .nip,
// tr.offline .location {
table .nip { // visibility: hidden;
display: none; // }
}
} // @media only screen and (min-device-width: 640px)
// and (max-device-width: 480px)
// and (orientation: portrait) {
// table .latency,
// table .verified,
// table .nip {
// display: none;
// }
// }
// @media only screen and (min-device-width: 640px)
// and (max-device-width: 480px)
// and (orientation: landscape) {
// table .nip {
// display: none;
// }
// }

3
tailwind.config.js

@ -16,7 +16,8 @@ module.exports = {
extend: {}, extend: {},
}, },
plugins: [ plugins: [
require('@tailwindcss/forms'), require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer'),
], ],
} }

75
vue.config.js

@ -1,34 +1,81 @@
const { defineConfig } = require('@vue/cli-service') const { defineConfig } = require('@vue/cli-service')
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin"); const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
const autoprefixer = require('autoprefixer');
const tailwindcss = require('tailwindcss');
const path = require('path');
module.exports = defineConfig({ module.exports = defineConfig({
transpileDependencies: true, transpileDependencies: true,
devServer: { devServer: {
port: 8080 port: 8080
}, },
// css: {
// loaderOptions: {
// // sass: {
// // data: '@import "./src/styles/main.scss";'
// // },
// postcss: {
// config: () => ({
// path: __dirname
// })
// }
// }
// },
configureWebpack: { configureWebpack: {
plugins: [new NodePolyfillPlugin()],
optimization: {
splitChunks: {
chunks: "all",
},
},
resolve: { resolve: {
fallback: { fallback: {
"fs": false, "zlib": require.resolve("browserify-zlib"),
"tls": false, "stream": require.resolve("stream-browserify"),
"net": false,
"utf-8-validate": false,
"bufferutil": false
} }
}, },
experiments: { module: {
topLevelAwait: true rules: [
}, {
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
config: path.resolve(__dirname, './postcss.config.js')
}
}
},
// 'sass-loader'
]
}
]
}
}, },
chainWebpack: config => { chainWebpack: config => {
config.plugins.delete('prefetch') config.plugins.delete('prefetch')
config.plugins.delete('preload') config.plugins.delete('preload')
config.module
.rule('scss')
.test(/\.scss$/)
.use('vue-style-loader')
.loader('vue-style-loader')
.end()
.use('css-loader')
.loader('css-loader')
.end()
.use('postcss-loader')
.loader('postcss-loader')
.options({
postcssOptions: {
config: {
path: __dirname
}
}
})
.end()
.use('sass-loader')
.loader('sass-loader')
.end()
config.module config.module
.rule('yaml') .rule('yaml')

63
webpack.config.js

@ -0,0 +1,63 @@
// const { VueLoaderPlugin } = require("vue-loader");
// const HtmlWebpackPlugin = require("html-webpack-plugin");
// const path = require("path");
// const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// module.exports = {
// entry: path.join(__dirname, "src/main.js"),
// devtool: "source-map",
// module: {
// rules: [
// {
// test: /\.vue$/,
// loader: "vue-loader",
// },
// {
// test: /\.css$/,
// use: [
// "style-loader",
// {
// loader: MiniCssExtractPlugin.loader,
// options: {
// esModule: false,
// },
// },
// {
// loader: "css-loader",
// options: {
// // 0 => no loaders (default);
// // 1 => postcss-loader;
// // 2 => postcss-loader, sass-loader
// importLoaders: 1,
// },
// },
// "postcss-loader",
// ],
// },
// ],
// },
// plugins: [
// new VueLoaderPlugin(),
// new HtmlWebpackPlugin({
// template: path.resolve(__dirname, "public/index.html"),
// }),
// new MiniCssExtractPlugin(),
// ],
// devServer: {
// open: true,
// devMiddleware: {
// writeToDisk: true,
// },
// static: {
// watch: true,
// },
// },
// optimization: {
// minimizer: [
// // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// "...",
// new CssMinimizerPlugin(),
// ],
// },
// };
Loading…
Cancel
Save