Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:fumiX/fuBlog into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
thooyork committed Jun 21, 2024
2 parents f3287b8 + d6a3bd7 commit b9111c0
Show file tree
Hide file tree
Showing 15 changed files with 1,079 additions and 328 deletions.
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@fortawesome/vue-fontawesome": "^3.0.3",
"@fumix/fu-blog-common": "*",
"@sipec/vue3-tags-input": "^3.0.4",
"bootstrap": "^5.3.0",
"bootstrap": "5.3.3",
"buffer": "^6.0.3",
"luxon": "^3.3.0",
"stream-browserify": "^3.0.0",
Expand Down
11 changes: 11 additions & 0 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ const appData: AppSettingsDto = (JSON.parse(document.getElementById("app-data")?
runMode: "production",
};
console.log(
`%c ███████
█ ███ █
██ █ ██ fuBlog
███████
██ █ ██ ${(appData.isProduction ? appData.appVersion ?? "‹unknown›" : "development version") + " "}
█ ███ █
███████`,
`color:#ff9c00;background:rgb(48, 48, 48);display:inline-block`,
);
const setOperator = (operator: string) => {
router.replace({ query: { ...route.query, operator: operator } });
};
Expand Down
7 changes: 6 additions & 1 deletion client/src/components/DisplayTags.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<template>
<div class="badge-container">
<div v-for="tag in tags" :key="tag.id" class="badge me-1" @click="searchWord(tag.name)">
<div
v-for="tag in [...tags].sort((a, b) => a.name.localeCompare(b.name))"
:key="tag.id"
class="badge me-1"
@click="searchWord(tag.name)"
>
{{ tag.name }}
</div>
</div>
Expand Down
181 changes: 155 additions & 26 deletions client/src/components/ImagePreview.vue
Original file line number Diff line number Diff line change
@@ -1,58 +1,184 @@
<template>
<div class="img-container">
<img :src="dataUrl" class="img-thumbnail" v-on:dragstart="onDragStart($event)" :draggable="showPaste" />
<div>
<code>{{ hash.substring(0, Math.min(10, hash.length)) }}</code>
<strong :title="value.name">{{ value.name }}</strong
><span>{{ convertToHumanReadableFileSize(value.size) }}</span
><br class="mb-1" />
<button class="btn btn-primary mx-1" v-if="showPaste" @click="$emit('paste', getMarkdownString())">
<fa-icon :icon="faPaste"></fa-icon>
</button>
<button class="btn btn-outline-danger mx-1" v-if="showDelete" @click="$emit('delete')"><fa-icon :icon="faTrash"></fa-icon></button>
<div class="preview-container">
<div class="erase" @click="$emit('delete')" :title="t('app.base.delete_image')"></div>
<div class="img-container">
<img :src="dataUrl" v-on:dragstart="onDragStart($event)" :draggable="showPaste" />
</div>
<div class="info-container">
<div class="code">{{ hash.substring(0, Math.min(7, hash.length)) }} / {{ convertToHumanReadableFileSize(value.size) }}</div>
<strong :title="value.name">{{ value.name }}</strong>
<div class="button-container">
<button
class="btn btn-paste mx-1"
type="button"
v-if="showPaste"
@click="$emit('paste', getMarkdownString())"
:title="t('app.base.insert_image')"
>
<fa-icon :icon="faFileImport"></fa-icon>
</button>
<button class="btn btn-softdelete mx-1" type="button" v-if="showDelete" @click="$emit('softdelete')" :title="t('app.base.remove')">
<fa-icon :icon="faEraser"></fa-icon>
</button>
<!-- <button class="btn btn-delete mx-1" type="button" v-if="showDelete" @click="$emit('delete')"
:title="t('app.base.delete_image')">
<fa-icon :icon="faTrash"></fa-icon>
</button> -->
</div>
</div>
</div>
</template>
<style scoped lang="scss">
div.img-container {
width: 12rem;
margin: 0.25rem;
.erase {
width: 16px;
height: 16px;
right: -7px;
top: -7px;
display: block;
position: absolute;
z-index: 999;
background-color: #333;
border: 1px solid #555;
border-radius: 50%;
cursor: pointer;
transition-duration: 0.4s;
&:hover {
transition-duration: 0.4s;
background-color: #a00;
}
&:before {
position: absolute;
top: 0;
left: calc(50% - 3px);
z-index: 1000;
content: "\d7";
line-height: 12px;
font-size: 12px;
padding: 0;
margin: 0;
transform: scale(1.25);
color: #fff;
text-align: center;
}
}
.preview-container {
width: 150px;
margin: 0;
position: relative;
display: inline-block;
text-align: center;
vertical-align: bottom;
background-color: #f8f9fa55;
border-radius: 0.375rem;
border: 1px solid #ccc;
.btn-paste {
color: #222;
&:hover {
color: #22222255;
}
}
.btn-softdelete {
color: #f18901;
&:hover {
color: #ffa836;
}
}
.btn-delete {
color: #a00;
&:hover {
color: #e00;
}
}
&:hover {
img {
transition-duration: 0.3s;
opacity: 1;
}
}
&:not(:last-child) {
margin-right: 15px;
}
.img-container {
display: flex;
width: 148px;
height: auto;
aspect-ratio: 1/1;
align-items: center;
justify-content: center;
padding: 0;
margin: 0;
}
img {
transition-duration: 0.3s;
display: flex;
border: 1px solid #999;
&[draggable="true"] {
cursor: move;
/* fallback if grab cursor is unsupported */
cursor: grab;
cursor: -moz-grab;
cursor: -webkit-grab;
&:active {
cursor: grabbing;
cursor: -moz-grabbing;
cursor: -webkit-grabbing;
}
}
min-width: 2rem;
min-height: 2rem;
max-width: 12rem;
max-height: 12rem;
max-width: 134px;
max-height: 134px;
opacity: 0.75;
margin: 0;
padding: 0;
}
div {
.info-container {
font-size: 0.75em;
margin-bottom: 7px;
padding-top: 5px;
strong {
font-weight: bold;
text-overflow: ellipsis;
white-space: nowrap;
overflow: clip;
display: block;
padding: 0 5px 7px 5px;
}
.code {
font-family: monospace;
font-size: 10px;
margin-bottom: 5px;
}
display: block;
padding-bottom: 0.5rem;
margin-bottom: 0.5rem;
.button-container {
display: flex;
justify-content: center;
align-items: space-between;
}
}
}
</style>

<script setup lang="ts">
import { faPaste, faTrash } from "@fortawesome/free-solid-svg-icons";
import { t } from "@client/plugins/i18n.js";
import { faFileImport, faTrash, faEraser } from "@fortawesome/free-solid-svg-icons";
import { blobToArray, bytesToDataUrl, convertToHumanReadableFileSize, escapeMarkdownAltText } from "@fumix/fu-blog-common";
import type { PropType } from "vue";
Expand All @@ -62,7 +188,10 @@ const getMarkdownString = () => {
const onDragStart = (event: DragEvent) => {
if (props.showPaste) {
event.dataTransfer?.setData("text/markdown", getMarkdownString());
const ghostImage = event.target as HTMLImageElement;
ghostImage.style.zIndex = "9999";
event.dataTransfer?.setDragImage(ghostImage, -10, -10);
event.dataTransfer?.setData("text/plain", getMarkdownString());
}
};
Expand All @@ -85,6 +214,6 @@ const props = defineProps({
},
});
const emits = defineEmits(["paste", "delete"]);
const emits = defineEmits(["paste", "delete", "softdelete"]);
const dataUrl = await blobToArray(props.value).then((it) => bytesToDataUrl(props.value.type, it));
</script>
2 changes: 1 addition & 1 deletion client/src/components/LightDarkToggler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const emit = defineEmits(["themeChanged"]);
const setTheme = (theme: UserTheme) => {
saveCssPreference(theme);
userTheme.value = theme;
document.querySelector("html")!.dataset.bsTheme = theme;
document.documentElement.dataset.bsTheme = theme;
emit("themeChanged", userTheme.value);
};
Expand Down
6 changes: 5 additions & 1 deletion client/src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
"save": "Speichern",
"cancel": "Abbrechen",
"edit": "Bearbeiten",
"insert_image": "Bild einfügen",
"delete": "Löschen",
"delete_image": "Bild löschen",
"remove": "Bildrefernz aus Text entfernen",
"read": "Lesen",
"create_post": "Post erstellen",
"roles": "Rollen",
Expand Down Expand Up @@ -59,7 +62,8 @@
"tags": "Schlagworte",
"enter": "Geben Sie Schlagworte ein..."
},
"imageupload": "keine angehängten Bilder | ein angehängtes Bild | {count} angehängte Bilder"
"imageupload": "keine angehängten Bilder | ein angehängtes Bild | {count} angehängte Bilder",
"imageupload_hint": "(Bild per Drag & Drop in den Text ziehen)"
},
"confirm": {
"title": "Löschen bestätigen",
Expand Down
9 changes: 6 additions & 3 deletions client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"save": "Save",
"cancel": "Cancel",
"edit": "Edit",
"delete": "Delete",
"insert_image": "Insert image",
"delete_image": "Delete image",
"remove": "Remove image reference from text",
"read": "Read",
"create_post": "Create Post",
"roles": "Roles",
Expand Down Expand Up @@ -56,6 +58,7 @@
"title": "Preview"
},
"imageupload": "Upload image",
"imageupload_hint": "(drag onto textarea to insert)",
"tags": "Tags"
},
"confirm": {
Expand All @@ -66,7 +69,7 @@
"not-available": {
"title": "Post not available",
"message": "This post is not available or has been deleted. You can find all posts in the overview, or use the search function to find a specific post."
}
}
}
},
"admin": {
Expand Down Expand Up @@ -102,4 +105,4 @@
},
"user_not_found": "User not found."
}
}
}
Loading

0 comments on commit b9111c0

Please sign in to comment.