Commit 938f37de authored by stahl's avatar stahl
Browse files

update

parent 8978f08f
<template>
<header>
<header
v-if="files"
>
<h1>Stereometrie</h1>
<div class="actions top">
<div>
Index: <text-reader once @load="load"></text-reader>
</div>
<div>
Öffnen: <text-reader @load="importData"></text-reader>
</div>
<button @click="save">Speichern ...</button>&nbsp;&nbsp;
<div>
Grafik
<select
......@@ -22,6 +17,17 @@
{{ ~~(page/2) + 1 }}-{{ mod(page,2) + 1}}
</option>
</select>
<button
@click="page -= 1"
>
-
</button>
<button
@click="page += 1"
>
+
</button>
</div>
<div>
Zoom
......@@ -37,29 +43,30 @@
</option>
</select>
</div>
</div>
<div class="actions options">
<label style="color: magenta;">
Bilder-Lücken anzeigen
<input type=checkbox v-model=showGaps />
</label>
<label style="color: red;">
Fehler anzeigen
<input type=checkbox v-model=showLeftRightMarker />
</label>
<label>
Vorschau
<input type=checkbox v-model=showPreview />
</label>
</div>
<div class="actions editor">
<!--<button @click="replaceWithPlaceholder()">Mit Platzhalter ersetzen [r]</button>-->
<input type="number" min="1" v-model="numPlaceholderToInsert">
<button @click="addPlaceholder(numPlaceholderToInsert)">Platzhalter einfügen [p]</button>
<button @click="toggleAddThumbsDialogue()">Bild einfügen [a]</button>
<button @click="removeThumb()">Löschen [delete/backspace]</button>
</div>
<div class="actions info">
<div>
grafik
</div>
<div>
position
</div>
<div>
index
</div>
<div>
datum
</div>
<div>
zeit
</div>
<div>
file
</div>
<div>
{{ ~~(page/2) + 1 }}-{{ mod(page,2) + 1}}
</div>
......@@ -67,7 +74,7 @@
{{ x+1 }} / {{ y+1 }}
</div>
<div>
{{ filenameIndexAtIndex(index) }}
{{ index + 1 }}
</div>
<div>
{{ filenameDateAtIndex(index) }}
......@@ -80,7 +87,9 @@
</div>
</div>
</header>
<div class="thumb-preview">
<div
v-if="files"
class="thumb-preview">
<img
v-lazy="imgUrl(files[index])"
/>
......@@ -90,9 +99,8 @@
class="thumbs"
>
<div
v-if="files && files.length && originalFiles && originalFiles.length"
v-if="files"
>
<select-thumb-dialogue v-if="isAddThumbsDialogueActive" @cancel="cancelSelect" @submit="insertFile" :files="files" :originalFiles="originalFiles" :index="index" :placeholder="placeholder"></select-thumb-dialogue>
<div
:style="pageStyle"
>
......@@ -100,19 +108,23 @@
v-for="(item, index) in filesForPage"
:key=index
>
<img
v-lazy="imgUrl(item)"
<div
v-lazy-container="{ error: imgUrl(this.placeholder), attempt: 1 }"
>
<img
:data-src="imgUrl(item)"
@click="thumbClicked(index)"
:title="item"
:style="[thumbStyle(item, index), checkLeftRight(item, index), cursorStyle(index)]"
:style="[thumbStyle(item, index), cursorStyle(index)]"
/>
</div>
</div>
</div>
</div>
<div
v-else
>
Keine Daten vorhanden.
Die Daten werden geladen...
</div>
</div>
</template>
......@@ -124,71 +136,60 @@ import {
ref,
inject,
} from "vue";
import TextReader from "./TextReader";
import SelectThumbDialogue from "./SelectThumbDialogue";
export default {
name: 'StereometrieEditor',
components: {
TextReader,
SelectThumbDialogue,
},
setup: function() {
const Lazyload = inject('Lazyload');
const keyboardIsActive = ref(true);
//const LazyLoad = inject('Lazyload');
inject('Lazyload');
Lazyload.$on('error', function ({el, src}) {
//console.table(Lazyload.performance())
console.log(el, src);
});
const keyboardIsActive = ref(true);
const placeholder = 'placeholder.jpg';
const originalFiles = ref([]);
const files = ref([]);
/*
const files = ref(
Array(
'2019/0207906-20191130-12-31-54.58-L.jpg',
placeholder,
'2019/0207908-20191130-13-01-46.25-R.jpg',
'2019/0207909-20191130-13-31-52.48-L.jpg',
'2019/0207910-20191130-13-31-52.73-R.jpg',
'2019/0207911-20191130-14-02-18.33-L.jpg',
'2019/0207912-20191130-14-02-18.59-R.jpg',
'2019/0207913-20191130-14-31-34.88-L.jpg',
'2019/0207914-20191130-14-31-35.15-R.jpg',
'2019/0207915-20191130-15-01-50.00-L.jpg',
'2019/0207916-20191130-15-01-50.27-R.jpg',
'2019/0207917-20191130-15-31-43.16-L.jpg',
'2019/0207918-20191130-15-31-43.44-R.jpg',
'2019/0207919-20191130-16-01-31.35-L.jpg',
'2019/0207920-20191130-16-01-31.64-R.jpg',
'2019/0207921-20191130-16-31-37.58-L.jpg',
'2019/0207922-20191130-16-31-37.87-R.jpg',
'2019/0207923-20191130-17-01-45.27-L.jpg',
'2019/0207924-20191130-17-01-45.57-R.jpg',
'2019/0207925-20191130-17-31-53.68-L.jpg',
'2019/0207926-20191130-18-01-33.63-L.jpg',
'2019/0207927-20191130-18-01-33.94-R.jpg',
'2019/0207928-20191130-18-31-31.46-L.jpg',
'2019/0207929-20191130-18-31-31.78-R.jpg',
'2019/0207930-20191130-19-01-38.28-L.jpg',
'2019/0207931-20191130-19-01-38.60-R.jpg',
)
);
*/
const filesToInsert = ref(null);
const isAddThumbsDialogueActive = ref(false);
Lazyload.$on('error', function ({el, src}) {
//console.table(Lazyload.performance())
console.warn(el, src);
});
*/
const files = ref(null);
const loadIndexFile = (file = "index.txt") => {
// read text from URL location
let request = new XMLHttpRequest();
request.open('GET', `${document.settings.MEDIA_URL}/${file}`, true);
request.send(null);
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
const type = request.getResponseHeader('Content-Type');
if (type.indexOf("text") !== 1) {
console.log("loaded index file.");
const text = request.responseText;
files.value = text.split("\r\n");
}
} else {
console.warn("could not load index file", request.status);
}
}
else if(request.readyState === 3) {
console.log("loading ...");
}
}
}
loadIndexFile();
const page = ref(0);
const zoomLevel = ref(8);
const numPages = 352;
const zoomLevel = ref(20);
const numPages = 88*2;
const rows = 48;
const cols = 32;
const pageSize = rows * cols;
......@@ -202,49 +203,20 @@ export default {
const pageIndex = computed(() => {
return x.value + y.value * cols;
});
const index = computed(() => {
return page.value * pageSize + pageIndex.value;
});
const removeThumb = () => {
files.value.splice(index.value, 1);
};
const replaceWithPlaceholder = () => {
console.warn('disabled for now..');
return;
//files.value[index.value] = placeholder;
};
const addPlaceholder = (count) => {
let placeholders = Array(count).fill(placeholder);
console.log(placeholders);
files.value.splice(index.value+1, 0, ...placeholders);
};
const toggleAddThumbsDialogue = () => {
if (isAddThumbsDialogueActive.value == true) {
isAddThumbsDialogueActive.value = false;
//keyboardIsActive.value = true;
} else {
isAddThumbsDialogueActive.value = true;
//keyboardIsActive.value = false;
}
}
const insertFile = (file) => {
console.log('insert', file);
files.value.splice(index.value+1, 0, file);
toggleAddThumbsDialogue();
};
const cancelSelect = () => {
toggleAddThumbsDialogue();
};
const filesForPage = computed(() => {
return files.value.slice(page.value*pageSize, page.value*pageSize+pageSize);
});
const imgUrl = (item) => {
if (item == placeholder) {
return `${document.settings.MEDIA_URL}/${placeholder}`;
}
return `${document.settings.MEDIA_URL}/${item}`;
return `${document.settings.MEDIA_URL}${placeholder}`;
}
return `${document.settings.MEDIA_URL}${item}`;
}
const mod = (a, n) => {
......@@ -269,27 +241,9 @@ export default {
case 74: // j
y.value = mod(y.value+1, rows);
break;
case 46: // delete
removeThumb()
break;
case 8: // backspace
removeThumb()
x.value = mod(x.value-1, cols);
break;
case 82: // r
replaceWithPlaceholder()
break;
case 80: //p
addPlaceholder(1)
x.value = mod(x.value+1, cols);
break;
case 65: // a
toggleAddThumbsDialogue()
break;
}
}
useKeypress({
keyEvent: "keydown",
onAnyKey: onKeyDown,
......@@ -298,10 +252,7 @@ export default {
})
return {
originalFiles,
files,
filesToInsert,
textFileToSave: null,
x,
y,
rows,
......@@ -318,14 +269,7 @@ export default {
placeholder,
imgUrl,
keyboardIsActive,
cancelSelect,
insertFile,
removeThumb,
replaceWithPlaceholder,
addPlaceholder,
numPlaceholderToInsert,
toggleAddThumbsDialogue,
isAddThumbsDialogueActive,
showGaps,
showLeftRightMarker,
showPreview,
......@@ -375,7 +319,7 @@ export default {
},
filenameDateAtIndex(i) {
if (this.files && this.files[i]) {
const d = this.files[i].slice(-26, -26+8);
const d = this.files[i].slice(13, 13+8);
if (!d) {
return 'no valid date';
}
......@@ -387,7 +331,7 @@ export default {
},
filenameTimeAtIndex(i) {
if (this.files && this.files[i]) {
const d = this.files[i].slice(-17, -17+8);
const d = this.files[i].slice(13+8+1, 13+8+1+8);
if (!d) {
return 'no valid date';
}
......@@ -414,58 +358,11 @@ export default {
const height = this.thumbHeight / this.zoomLevel;
style.width = `${width}px`;
style.height = `${height}px`;
if (!this.showPreview && this.showGaps) {
if (this.itemsWithGaps.includes(item)) {
style['border'] = '2px solid magenta';
}
}
style.background = "#777";
return style;
},
checkLeftRight(item, index) {
let style = {};
const even = index % 2 == 0;
const right = item.slice(-5,-4) === 'R';
if (!this.showPreview && this.showLeftRightMarker && even && right) {
style.border = '2px solid red';
}
return style;
},
load(data) {
console.log('loaded');
this.originalFiles = data;
},
importData(data) {
console.log('imported data');
this.files = data;
},
save() {
const data = this.files.join("\r\n");
const blob = new Blob([data], {type: 'text/plain'});
// If we are replacing a previously generated file we need to
// manually revoke the object URL to avoid memory leaks.
if (this.textFileToSave !== null) {
window.URL.revokeObjectURL(this.textFile);
}
this.textFileToSave = window.URL.createObjectURL(blob);
let link = document.createElement('a');
const date = new Date().toISOString().replaceAll(':','-');
link.setAttribute('download', `thumbs-${date}.txt`);
link.href = this.textFileToSave;
document.body.appendChild(link);
// wait for the link to be added to the document
window.requestAnimationFrame(function () {
let event = new MouseEvent('click');
link.dispatchEvent(event);
document.body.removeChild(link);
});
},
},
}
</script>
......@@ -488,13 +385,9 @@ header {
.actions.top {
grid-template-columns: 300px 400px 100px 50px 150px 150px;
}
.actions.options {
grid-template-columns: repeat(10, 200px);
.actions.info {
grid-template-columns: repeat(5, 100px) 500px;
}
.actions.editor {
grid-template-columns: 100px 200px 200px 200px;
}
.thumb-preview {
position: fixed;
top: 10px;
......@@ -507,7 +400,6 @@ header {
padding: 20px;
}
.info {
display: flex;
padding: 20px;
}
.info > div {
......
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
transpileDependencies: true,
configureWebpack: {
devServer: {
proxy: "http://127.0.0.1:9000",
webSocketServer: false,
headers: { 'Access-Control-Allow-Origin': '*' }
}
}
})
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment