Compare commits
40
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08821ea8a8 | ||
|
|
e9a466fa31 | ||
|
|
de9f686480 | ||
|
|
d08e9650ba | ||
|
|
0434a96c3a | ||
|
|
2b9b77bef2 | ||
|
|
f5040ad2f4 | ||
|
|
7bc77ae8c0 | ||
|
|
715269a5d0 | ||
|
|
53605c24f0 | ||
|
|
da0b741b69 | ||
|
|
73f923bc47 | ||
|
|
25a8c7ea80 | ||
|
|
950de7c954 | ||
|
|
42ba9240b0 | ||
|
|
3da6299021 | ||
|
|
1ac0f412b9 | ||
|
|
e7fbdc2727 | ||
|
|
7117303d57 | ||
|
|
0ca43dc147 | ||
|
|
c47ea2716c | ||
|
|
cbdcc61414 | ||
|
|
194a7d4cf8 | ||
|
|
9695785a0c | ||
|
|
d9f555554e | ||
|
|
6e38bcf349 | ||
|
|
fc780a90ae | ||
|
|
d586f691b7 | ||
|
|
9e8e43bd12 | ||
|
|
c554a96b4b | ||
|
|
3ecc81094f | ||
|
|
811ccc1baa | ||
|
|
d7c5451729 | ||
|
|
96884372b4 | ||
|
|
dddba4d64a | ||
|
|
a0e3efe2d1 | ||
|
|
d707e1576a | ||
|
|
3aaf363413 | ||
|
|
28fff10fec | ||
|
|
8729c24e1d |
+2
-2
@@ -139,7 +139,7 @@ steps:
|
||||
event: [ push, tag, pull_request ]
|
||||
|
||||
- name: api-lint
|
||||
image: golangci/golangci-lint:v1.60.3
|
||||
image: golangci/golangci-lint:v1.59.1
|
||||
pull: always
|
||||
environment:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
@@ -1352,6 +1352,6 @@ steps:
|
||||
- failure
|
||||
---
|
||||
kind: signature
|
||||
hmac: 715c2bd948ee16e3a109e5dbf1377a3b3c1f61fae20d7ab299b6b47fbc5e9c6a
|
||||
hmac: dc96a5f8aaa332b35fc02f1b8566493e494452d62bed52973d804f5347ae47ae
|
||||
|
||||
...
|
||||
|
||||
@@ -109,7 +109,3 @@ issues:
|
||||
text: 'structtag: struct field Position repeats json tag "position" also at'
|
||||
linters:
|
||||
- govet
|
||||
- path: pkg/cmd/user.go
|
||||
text: 'G115: integer overflow conversion uintptr -> int'
|
||||
linters:
|
||||
- gosec
|
||||
|
||||
+12
-12
@@ -3,11 +3,11 @@
|
||||
"devenv": {
|
||||
"locked": {
|
||||
"dir": "src/modules",
|
||||
"lastModified": 1724504184,
|
||||
"lastModified": 1723409744,
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "51338b58fd666f448db7486ec145dbe52db9b829",
|
||||
"treeHash": "cedf6d41b00189dfd5132772cb5f35fcb10a7f7b",
|
||||
"rev": "116159a4bfeaa79662f4c39dbfaf2fce6a5737f7",
|
||||
"treeHash": "ccbae63055f83e669996a88a3cbb4ef69febd002",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -72,11 +72,11 @@
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1724316499,
|
||||
"lastModified": 1723282977,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "797f7dc49e0bc7fab4b57c021cdf68f595e47841",
|
||||
"treeHash": "fe60fe6585f3b84f2ee7fcbf10f02f02fc5c54ca",
|
||||
"rev": "a781ff33ae258bbcfd4ed6e673860c3e923bf2cc",
|
||||
"treeHash": "75cf71293251c603e56d6076098346b4128b2ec8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -88,11 +88,11 @@
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1724224976,
|
||||
"lastModified": 1723175592,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c374d94f1536013ca8e92341b540eba4c22f9c62",
|
||||
"treeHash": "1b707e2dd1830bf99c662e1a1694c5c463d8026b",
|
||||
"rev": "5e0ca22929f3342b19569b21b2f3462f053e497b",
|
||||
"treeHash": "a6b38d5232ae0ae0c666c37f5ec9620c14f30369",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -112,11 +112,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1724440431,
|
||||
"lastModified": 1723202784,
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "c8a54057aae480c56e28ef3e14e4960628ac495b",
|
||||
"treeHash": "40ee1da550348c789ed9503eea365533a618506c",
|
||||
"rev": "c7012d0c18567c889b948781bc74a501e92275d1",
|
||||
"treeHash": "0016d5d748d61d3bfaa69d3c02abff74740a46b7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</span>
|
||||
<div
|
||||
v-for="c in comments"
|
||||
:id="`comment-${c.id}`"
|
||||
:key="c.id"
|
||||
class="media comment"
|
||||
>
|
||||
@@ -57,13 +56,6 @@
|
||||
>
|
||||
· {{ $t('task.comment.edited', {date: formatDateSince(c.updated)}) }}
|
||||
</span>
|
||||
<a
|
||||
v-tooltip="$t('task.comment.permalink')"
|
||||
:href="`#comment-${c.id}`"
|
||||
class="comment-permalink"
|
||||
:title="$t('task.comment.permalink')"
|
||||
@click.prevent.stop="copy(getCommentUrl(`${c.id}`))"
|
||||
><Icon icon="link" /></a>
|
||||
<CustomTransition name="fade">
|
||||
<span
|
||||
v-if="
|
||||
@@ -207,7 +199,6 @@ import {getAvatarUrl, getDisplayName} from '@/models/user'
|
||||
import {useConfigStore} from '@/stores/config'
|
||||
import {useAuthStore} from '@/stores/auth'
|
||||
import Reactions from '@/components/input/Reactions.vue'
|
||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
taskId: number,
|
||||
@@ -216,8 +207,6 @@ const props = withDefaults(defineProps<{
|
||||
canWrite: true,
|
||||
})
|
||||
|
||||
const copy = useCopyToClipboard()
|
||||
|
||||
const {t} = useI18n({useScope: 'global'})
|
||||
const configStore = useConfigStore()
|
||||
const authStore = useAuthStore()
|
||||
@@ -253,8 +242,6 @@ const actions = computed(() => {
|
||||
])))
|
||||
})
|
||||
|
||||
const frontendUrl = computed(() => configStore.frontendUrl)
|
||||
|
||||
async function attachmentUpload(files: File[] | FileList): (Promise<string[]>) {
|
||||
|
||||
const uploadPromises: Promise<string>[] = []
|
||||
@@ -377,10 +364,6 @@ async function deleteComment(commentToDelete: ITaskComment) {
|
||||
showDeleteModal.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function getCommentUrl(commentId: string) {
|
||||
return `${frontendUrl.value}${location.pathname}${location.search}#comment-${commentId}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -408,23 +391,10 @@ function getCommentUrl(commentId: string) {
|
||||
}
|
||||
|
||||
|
||||
span,
|
||||
.comment-permalink {
|
||||
span {
|
||||
font-size: .75rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.comment-permalink {
|
||||
font-size: 1rem;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.25rem;
|
||||
border-radius: 1rem;
|
||||
color: var(--grey, hsl(0, 0%, 48%));
|
||||
}
|
||||
.comment-permalink:hover {
|
||||
color: var(--grey-dark, hsl(0, 0%, 29%));
|
||||
border-color: var(--grey-dark, hsl(0, 0%, 29%));
|
||||
}
|
||||
}
|
||||
|
||||
.image.is-avatar {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, shallowReactive, watchEffect} from 'vue'
|
||||
import AttachmentService, {PREVIEW_SIZE} from '@/services/attachment'
|
||||
import AttachmentService from '@/services/attachment'
|
||||
import type {IAttachment} from '@/modelTypes/IAttachment'
|
||||
import {SUPPORTED_IMAGE_SUFFIX} from '@/models/attachment'
|
||||
|
||||
@@ -33,7 +33,7 @@ const blobUrl = ref<string | undefined>(undefined)
|
||||
|
||||
watchEffect(async () => {
|
||||
if (props.modelValue && canPreview(props.modelValue)) {
|
||||
blobUrl.value = await attachmentService.getBlobUrl(props.modelValue, PREVIEW_SIZE.SM)
|
||||
blobUrl.value = await attachmentService.getBlobUrl(props.modelValue)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref, watch} from 'vue'
|
||||
import {ref, computed, watch} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
import PriorityLabel from '@/components/tasks/partials/PriorityLabel.vue'
|
||||
@@ -105,9 +105,9 @@ import ChecklistSummary from './ChecklistSummary.vue'
|
||||
import {getHexColor} from '@/models/task'
|
||||
import type {ITask} from '@/modelTypes/ITask'
|
||||
import {SUPPORTED_IMAGE_SUFFIX} from '@/models/attachment'
|
||||
import AttachmentService, {PREVIEW_SIZE} from '@/services/attachment'
|
||||
import AttachmentService from '@/services/attachment'
|
||||
|
||||
import {formatDateLong, formatDateSince, formatISO} from '@/helpers/time/formatDate'
|
||||
import {formatDateLong, formatISO, formatDateSince} from '@/helpers/time/formatDate'
|
||||
import {colorIsDark} from '@/helpers/color/colorIsDark'
|
||||
import {useTaskStore} from '@/stores/tasks'
|
||||
import AssigneeList from '@/components/tasks/partials/AssigneeList.vue'
|
||||
@@ -165,7 +165,7 @@ async function maybeDownloadCoverImage() {
|
||||
}
|
||||
|
||||
const attachmentService = new AttachmentService()
|
||||
coverImageBlobUrl.value = await attachmentService.getBlobUrl(attachment, PREVIEW_SIZE.MD)
|
||||
coverImageBlobUrl.value = await attachmentService.getBlobUrl(attachment)
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@@ -848,8 +848,7 @@
|
||||
"delete": "Delete this comment",
|
||||
"deleteText1": "Are you sure you want to delete this comment?",
|
||||
"deleteSuccess": "The comment was deleted successfully.",
|
||||
"addedSuccess": "The comment was added successfully.",
|
||||
"permalink": "Copy permalink to this comment"
|
||||
"addedSuccess": "The comment was added successfully."
|
||||
},
|
||||
"deferDueDate": {
|
||||
"title": "Defer due date",
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
"more": "More information about CalDAV in Vikunja",
|
||||
"tokens": "CalDAV Tokens",
|
||||
"tokensHowTo": "You can use a CalDAV token to use instead of a password to log in the above endpoint.",
|
||||
"createToken": "Sukurti prieigos raktą",
|
||||
"createToken": "Create a token",
|
||||
"tokenCreated": "Here is your token: {token}",
|
||||
"wontSeeItAgain": "Write it down, you won't be able to see it again.",
|
||||
"mustUseToken": "You need to create a CalDAV token if you want to use CalDAV with a third party client. Use the token as the password.",
|
||||
@@ -167,14 +167,14 @@
|
||||
"expired": "This token has expired {ago}.",
|
||||
"tokenCreatedSuccess": "Here is your new api token: {token}",
|
||||
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
|
||||
"selectAll": "Pažymėti viską",
|
||||
"selectAll": "Select all",
|
||||
"delete": {
|
||||
"header": "Delete this token",
|
||||
"text1": "Are you sure you want to delete the token \"{token}\"?",
|
||||
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
|
||||
},
|
||||
"attributes": {
|
||||
"title": "Pavadinimas",
|
||||
"title": "Title",
|
||||
"titlePlaceholder": "Enter a title you will recognize later",
|
||||
"expiresAt": "Expires at",
|
||||
"permissions": "Permissions"
|
||||
@@ -184,22 +184,22 @@
|
||||
"deletion": {
|
||||
"title": "Delete your Vikunja Account",
|
||||
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
|
||||
"text2": "Norėdama -s tęsti, įvesk savo slaptažodį. Gausi email'ą su tolimesnėmis instrukcijomis.",
|
||||
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
|
||||
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
|
||||
"confirm": "Delete my account",
|
||||
"requestSuccess": "Tavo užklausa sėkminga. Gausi email'ą su tolimesnėmis instrukcijomis.",
|
||||
"passwordRequired": "Prašome įvesti savo slaptažodį.",
|
||||
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
|
||||
"passwordRequired": "Please enter your password.",
|
||||
"confirmSuccess": "You've successfully confirmed the deletion of your account. We will delete your account in three days.",
|
||||
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
|
||||
"scheduledCancel": "Norėdama -s nutraukti paskyros ištrynimą, spausk čia.",
|
||||
"scheduledCancelText": "Norėdama -s nutraukti paskyros ištrynimą, įveskite slaptažodį žemiau:",
|
||||
"scheduledCancel": "To cancel the deletion of your account, click here.",
|
||||
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
|
||||
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
|
||||
"scheduledCancelConfirm": "Atšaukti mano paskyros ištrynimą",
|
||||
"scheduledCancelConfirm": "Cancel the deletion of my account",
|
||||
"scheduledCancelSuccess": "We will not delete your account."
|
||||
},
|
||||
"export": {
|
||||
"title": "Export your Vikunja data",
|
||||
"description": "Tu gali prašyti gauti visus Vikunja duomenis. Į tai įeina, Projektai, Užduotys ir viskas, kas su jais susiję. Tu gali savo duomenis vėliau įkelti į bet kurią Vikunja aplinką naudojantis migracijos funkcija.",
|
||||
"description": "You can request a copy of all your Vikunja data. This includes Projects, Tasks and everything associated to them. You can import this data in any Vikunja instance through the migration function.",
|
||||
"descriptionPasswordRequired": "Please enter your password to proceed:",
|
||||
"request": "Request a copy of my Vikunja Data",
|
||||
"success": "You've successfully requested your Vikunja Data! We will send you an email once it's ready to download.",
|
||||
@@ -265,9 +265,9 @@
|
||||
"title": "Edit \"{project}\"",
|
||||
"titlePlaceholder": "The project title goes here…",
|
||||
"identifierTooltip": "The project identifier can be used to uniquely identify a task across projects. You can set it to empty to disable it.",
|
||||
"identifier": "Projekto identifikatorius",
|
||||
"identifier": "Project Identifier",
|
||||
"identifierPlaceholder": "The project identifier goes here…",
|
||||
"description": "Aprašymas",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
|
||||
"color": "Color",
|
||||
"success": "The project was successfully updated."
|
||||
@@ -283,21 +283,21 @@
|
||||
"create": "Create a link share",
|
||||
"name": "Name (optional)",
|
||||
"namePlaceholder": "e.g. Lorem Ipsum",
|
||||
"nameExplanation": "Visi veiksmai atlikti po pasidalinta nuoroda matysis šiuo pavadinimu.",
|
||||
"password": "Slaptažodis (pasirinktinai)",
|
||||
"passwordExplanation": "Prisijungiant, vartotojas privalės įvesti savo slaptažodį.",
|
||||
"noName": "Vardas nenustatytas",
|
||||
"remove": "Pašalinti pasidalinimo nuorodą",
|
||||
"nameExplanation": "All actions done by this link share will show up with the name.",
|
||||
"password": "Password (optional)",
|
||||
"passwordExplanation": "When signing in, the user will be required to enter this password.",
|
||||
"noName": "No name set",
|
||||
"remove": "Remove a link share",
|
||||
"removeText": "Are you sure you want to remove this link share? It will no longer be possible to access this project with this link share. This cannot be undone!",
|
||||
"createSuccess": "The link share was successfully created.",
|
||||
"deleteSuccess": "The link share was successfully deleted",
|
||||
"view": "Peržiūra",
|
||||
"sharedBy": "Pasidalino {0}"
|
||||
"view": "View",
|
||||
"sharedBy": "Shared by {0}"
|
||||
},
|
||||
"userTeam": {
|
||||
"typeUser": "vartotojas | vartotojai",
|
||||
"typeTeam": "komanda | komandos",
|
||||
"shared": "Pasidalinta su šiais {type}",
|
||||
"typeUser": "user | users",
|
||||
"typeTeam": "team | teams",
|
||||
"shared": "Shared with these {type}",
|
||||
"you": "You",
|
||||
"notShared": "Not shared with any {type} yet.",
|
||||
"removeHeader": "Remove a {type} from the {sharable}",
|
||||
@@ -332,11 +332,11 @@
|
||||
"title": "Gantt",
|
||||
"size": "Size",
|
||||
"default": "Default",
|
||||
"month": "Mėnuo",
|
||||
"day": "Diena",
|
||||
"hour": "Valanda",
|
||||
"month": "Month",
|
||||
"day": "Day",
|
||||
"hour": "Hour",
|
||||
"range": "Date Range",
|
||||
"noDates": "Ši užduotis dar neturi nurodytos datos."
|
||||
"noDates": "This task has no dates set."
|
||||
},
|
||||
"table": {
|
||||
"title": "Table",
|
||||
@@ -373,17 +373,17 @@
|
||||
}
|
||||
},
|
||||
"webhooks": {
|
||||
"title": "„Webhook“'ai",
|
||||
"targetUrl": "Tikslinė nuoroda",
|
||||
"targetUrlInvalid": "Prašome nurodyti veikiančia nuorodą.",
|
||||
"events": "Įvykiai",
|
||||
"title": "Webhooks",
|
||||
"targetUrl": "Target URL",
|
||||
"targetUrlInvalid": "Please provide a valid URL.",
|
||||
"events": "Events",
|
||||
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
|
||||
"mustSelectEvents": "You must select at least one event.",
|
||||
"delete": "Ištrinti šį webhook'ą",
|
||||
"delete": "Delete this webhook",
|
||||
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
|
||||
"deleteSuccess": "The webhook was successfully deleted.",
|
||||
"create": "Sukurti ryšį",
|
||||
"secret": "Paslaptis",
|
||||
"create": "Create webhook",
|
||||
"secret": "Secret",
|
||||
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
|
||||
"secretDocs": "Check out the docs for more details about how to use secrets."
|
||||
},
|
||||
@@ -393,13 +393,13 @@
|
||||
"actions": "Actions",
|
||||
"kind": "Kind",
|
||||
"bucketConfigMode": "Bucket configuration mode",
|
||||
"bucketConfig": "Telkinio konfigūracija",
|
||||
"bucketConfig": "Bucket configuration",
|
||||
"bucketConfigManual": "Manual",
|
||||
"filter": "Filtras",
|
||||
"create": "Sukurti atvaizdavimą",
|
||||
"filter": "Filter",
|
||||
"create": "Create view",
|
||||
"createSuccess": "The view was created successfully.",
|
||||
"titleRequired": "Please provide a title.",
|
||||
"delete": "Ištrinti šį atvaizdavimą",
|
||||
"delete": "Delete this view",
|
||||
"deleteText": "Are you sure you want to remove this view? It will no longer be possible to use it to view tasks in this project. This action won't delete any tasks. This cannot be undone!",
|
||||
"deleteSuccess": "The view was deleted successfully.",
|
||||
"onlyAdminsCanEdit": "Only project admins can edit views.",
|
||||
@@ -408,13 +408,13 @@
|
||||
},
|
||||
"filters": {
|
||||
"title": "Filters",
|
||||
"clear": "Anuliuoti filtrus",
|
||||
"showResults": "Rodyti rezultatus",
|
||||
"clear": "Clear Filters",
|
||||
"showResults": "Show results",
|
||||
"attributes": {
|
||||
"title": "Pavadinimas",
|
||||
"titlePlaceholder": "Išsaugoto filtro pavadinimas rašomas čia…",
|
||||
"description": "Aprašymas",
|
||||
"descriptionPlaceholder": "Įvesti filtro aprašymą, spausti '/' norint gauti daugiau pasirinkčių…",
|
||||
"title": "Title",
|
||||
"titlePlaceholder": "The saved filter title goes here…",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
|
||||
"includeNulls": "Include Tasks which don't have a value set",
|
||||
"requireAll": "Require all filters to be true for a task to show up",
|
||||
"showDoneTasks": "Show Done Tasks",
|
||||
@@ -490,17 +490,17 @@
|
||||
},
|
||||
"migrate": {
|
||||
"title": "Import from other services",
|
||||
"titleService": "Importuoti duomenis iš {name} į Vikunja",
|
||||
"titleService": "Import your data from {name} into Vikunja",
|
||||
"import": "Import your data into Vikunja",
|
||||
"description": "Paspauskite ant trečiosios šalies logotipo norint pradėti.",
|
||||
"descriptionDo": "Vikunja importuos visus sąrašus, užduotis, užrašus, priminimus ir dokumentus prie kurių tu turi prieigą.",
|
||||
"authorize": "Autorizuoti Vikunja prieigą prie tavo {name} paskyros, spauskite mygtuką žemiau.",
|
||||
"description": "Click on the logo of one of the third-party services below to get started.",
|
||||
"descriptionDo": "Vikunja will import all lists, tasks, notes, reminders and files you have access to.",
|
||||
"authorize": "To authorize Vikunja to access your {name} Account, click the button below.",
|
||||
"getStarted": "Get Started",
|
||||
"inProgress": "Importing in progress…",
|
||||
"alreadyMigrated1": "Atrodo, kad jau importavai savo info is {name} {date}.",
|
||||
"alreadyMigrated1": "It looks like you've already imported your stuff from {name} at {date}.",
|
||||
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
|
||||
"confirm": "I am sure, please start migrating now!",
|
||||
"importUpload": "Importuoti duomenis iš {name} į Vikunja, spausk mygtuką žemiau, norėdamas pasirinkti failą.",
|
||||
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
|
||||
"upload": "Upload file",
|
||||
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
|
||||
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
|
||||
@@ -508,7 +508,7 @@
|
||||
"label": {
|
||||
"title": "Labels",
|
||||
"manage": "Manage labels",
|
||||
"description": "Paspausk ant etiketės norėdamas ją redaguoti. Tu gali keisti etiketes, kurias pats sukūrei, tu gali naudoti visas etiketes, kurios yra susietos su užduotimis, projektų, prie kurių tu turi prieigą.",
|
||||
"description": "Click on a label to edit it. You can edit all labels you created, you can use all labels which are associated with a task to whose project you have access.",
|
||||
"newCTA": "You currently do not have any labels.",
|
||||
"search": "Type to search for a label…",
|
||||
"create": {
|
||||
@@ -526,16 +526,16 @@
|
||||
"attributes": {
|
||||
"title": "Title",
|
||||
"titlePlaceholder": "The label title goes here…",
|
||||
"description": "Aprašymas",
|
||||
"descriptionPlaceholder": "Etiketės aprašas",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "Label description",
|
||||
"color": "Color"
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"authenticating": "Authenticating…",
|
||||
"passwordRequired": "Šis pasidalintas projektas reikalauja slaptažodžio. Įveskite jį žemiau:",
|
||||
"passwordRequired": "This shared project requires a password. Please enter it below:",
|
||||
"error": "An error occurred.",
|
||||
"invalidPassword": "Slaptažodis neteisingas."
|
||||
"invalidPassword": "The password is invalid."
|
||||
},
|
||||
"navigation": {
|
||||
"overview": "Overview",
|
||||
@@ -772,9 +772,9 @@
|
||||
},
|
||||
"actions": {
|
||||
"assign": "Assign to User",
|
||||
"label": "Pridėti etiketes",
|
||||
"priority": "Nustatyti prioritetą",
|
||||
"dueDate": "Nustatyto termino datą",
|
||||
"label": "Add Labels",
|
||||
"priority": "Set Priority",
|
||||
"dueDate": "Set Due Date",
|
||||
"startDate": "Set Start Date",
|
||||
"endDate": "Set End Date",
|
||||
"reminders": "Set Reminders",
|
||||
@@ -783,9 +783,9 @@
|
||||
"attachments": "Add Attachments",
|
||||
"relatedTasks": "Add Relation",
|
||||
"moveProject": "Move",
|
||||
"color": "Nustatyto spalvą",
|
||||
"delete": "Ištrinti",
|
||||
"favorite": "Pridėti prie mėgstamiausių",
|
||||
"color": "Set Color",
|
||||
"delete": "Delete",
|
||||
"favorite": "Add to Favorites",
|
||||
"unfavorite": "Remove from Favorites"
|
||||
}
|
||||
},
|
||||
@@ -798,7 +798,7 @@
|
||||
"done": "Done",
|
||||
"dueDate": "Due Date",
|
||||
"endDate": "End Date",
|
||||
"labels": "Etiketės",
|
||||
"labels": "Labels",
|
||||
"percentDone": "Progress",
|
||||
"priority": "Priority",
|
||||
"relatedTasks": "Related Tasks",
|
||||
@@ -820,7 +820,7 @@
|
||||
"subscribeSuccessProject": "You are now subscribed to this project",
|
||||
"unsubscribeSuccessProject": "You are now unsubscribed to this project",
|
||||
"subscribeSuccessTask": "You are now subscribed to this task",
|
||||
"unsubscribeSuccessTask": "Užsiprenumeravai užduoties naujienas"
|
||||
"unsubscribeSuccessTask": "You are now unsubscribed to this task"
|
||||
},
|
||||
"attachment": {
|
||||
"title": "Attachments",
|
||||
@@ -830,7 +830,7 @@
|
||||
"drop": "Drop files here to upload",
|
||||
"delete": "Delete attachment",
|
||||
"deleteTooltip": "Delete this attachment",
|
||||
"deleteText1": "Ar esi tikra -s, kad nori ištrinti šį prisegtuką {filename}?",
|
||||
"deleteText1": "Are you sure you want to delete the attachment {filename}?",
|
||||
"copyUrl": "Copy URL",
|
||||
"copyUrlTooltip": "Copy the url of this attachment for usage in text",
|
||||
"setAsCover": "Make cover",
|
||||
@@ -858,8 +858,8 @@
|
||||
"1week": "1 week"
|
||||
},
|
||||
"description": {
|
||||
"placeholder": "Įvesti aprašą, spausti '/' norint gauti daugiau pasirinkčių…",
|
||||
"empty": "Aprašo kol kas nėra."
|
||||
"placeholder": "Enter a description, hit '/' for more options…",
|
||||
"empty": "No description available yet."
|
||||
},
|
||||
"assignee": {
|
||||
"placeholder": "Type to assign a user…",
|
||||
@@ -945,16 +945,16 @@
|
||||
"title": "Quick Add Magic",
|
||||
"intro": "When creating a task, you can use special keywords to directly add attributes to the newly created task. This allows to add commonly used attributes to tasks much faster.",
|
||||
"multiple": "You can use this multiple times.",
|
||||
"label1": "Norėdama -s pridėti etiketę, paprasčiausiai naudoti etiketės prefikso pavadinimą su {prefix}.",
|
||||
"label1": "To add a label, simply prefix the name of the label with {prefix}.",
|
||||
"label2": "Vikunja will first check if the label already exist and create it if not.",
|
||||
"label3": "Norint naudoti tarpus, paprasčiausiai pridėkite \" ar ' prieš etiketės pavadinimą.",
|
||||
"label3": "To use spaces, simply add a \" or ' around the label name.",
|
||||
"label4": "For example: {prefix}\"Label with spaces\".",
|
||||
"priority1": "To set a task's priority, add a number 1-5, prefixed with a {prefix}.",
|
||||
"priority2": "The higher the number, the higher the priority.",
|
||||
"assignees": "Norint tiesiogiai priskirti užduotį vartotojui, pridėkite vartotojo vardą kaip prefiksą su {prefix} prie užduoties.",
|
||||
"assignees": "To directly assign the task to a user, add their username prefixed with {prefix} to the task.",
|
||||
"project1": "To set a project for the task to appear in, enter its name prefixed with {prefix}.",
|
||||
"project2": "This will return an error if the project does not exist.",
|
||||
"project3": "Norint naudoti tarpus, paprasčiausiai pridėkite \" ar ' apie projekto pavadinimą.",
|
||||
"project3": "To use spaces, simply add a \" or ' around the project name.",
|
||||
"project4": "For example: {prefix}\"Project with spaces\".",
|
||||
"dateAndTime": "Date and time",
|
||||
"date": "Any date will be used as the due date of the new task. You can use dates in any of these formats:",
|
||||
@@ -963,7 +963,7 @@
|
||||
"dateNth": "will use the {day}th of the current month",
|
||||
"dateTime": "Combine any of the date formats with \"{time}\" (or {timePM}) to set a time.",
|
||||
"repeats": "Repeating tasks",
|
||||
"repeatsDescription": "Norėdama -s nustatyti, kad užduotis kartotųsi tam tikru intervalu, paprasčiausiai pridėk '{suffix}' prie užduoties teksto. Kiekis turi būti išreikštas skaičiumi, tačiau gali būti ir praleistas (žr. pavyzdžius)."
|
||||
"repeatsDescription": "To set a task as repeating in an interval, simply add '{suffix}' to the task text. The amount needs to be a number and can be omitted to use just the type (see examples)."
|
||||
}
|
||||
},
|
||||
"team": {
|
||||
@@ -1006,14 +1006,14 @@
|
||||
},
|
||||
"attributes": {
|
||||
"name": "Team Name",
|
||||
"namePlaceholder": "Komandos pavadinimas rašomas čia…",
|
||||
"namePlaceholder": "The team's name goes here…",
|
||||
"nameRequired": "Please specify a name.",
|
||||
"description": "Aprašymas",
|
||||
"descriptionPlaceholder": "Aprašykite komandą čia, spauskite '/' dėl daugiau opcijų…",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
|
||||
"admin": "Admin",
|
||||
"member": "Member",
|
||||
"isPublic": "Public Team",
|
||||
"isPublicDescription": "Padaryk komandą viešai randamą. Kai įgalinta, bet kas gali pasidalinti projektu su komanda, net nebūdama -s tiesioginiu komandos nariu."
|
||||
"isPublicDescription": "Make the team publicly discoverable. When enabled, anyone can share projects with this team even when not being a direct member."
|
||||
}
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
@@ -1036,7 +1036,7 @@
|
||||
"color": "Change the color of this task",
|
||||
"move": "Move this task to another project",
|
||||
"reminder": "Manage reminders of this task",
|
||||
"description": "Praskleisti redagavimą užduoties apraše",
|
||||
"description": "Toggle editing of the task description",
|
||||
"delete": "Delete this task",
|
||||
"priority": "Change the priority of this task",
|
||||
"favorite": "Mark this task as favorite / unfavorite",
|
||||
@@ -1174,7 +1174,7 @@
|
||||
"4017": "Invalid task filter comparator.",
|
||||
"4018": "Invalid task filter concatenator.",
|
||||
"4019": "Invalid task filter value.",
|
||||
"6001": "Komandos pavadinimas negali būti tuščias.",
|
||||
"6001": "The team name cannot be empty.",
|
||||
"6002": "The team does not exist.",
|
||||
"6004": "The team already has access to that project.",
|
||||
"6005": "The user is already a member of that team.",
|
||||
@@ -1186,7 +1186,7 @@
|
||||
"8002": "The label does not exist.",
|
||||
"8003": "You do not have access to this label.",
|
||||
"9001": "The right is invalid.",
|
||||
"10001": "Šaltinis neegzistuoja.",
|
||||
"10001": "The bucket does not exist.",
|
||||
"10002": "The bucket does not belong to that project.",
|
||||
"10003": "You cannot remove the last bucket on a project.",
|
||||
"10004": "You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold.",
|
||||
@@ -1195,22 +1195,22 @@
|
||||
"11002": "Saved filters are not available for link shares.",
|
||||
"12001": "The subscription entity type is invalid.",
|
||||
"12002": "You are already subscribed to the entity itself or a parent entity.",
|
||||
"13001": "Šis dalinimasis nuoroda reikalauja slaptažodžio identifikavimuisi, bet jis nebuvo pateiktas.",
|
||||
"13002": "Pateikta slaptažodžio dalinimosi nuoroda negalioja."
|
||||
"13001": "This link share requires a password for authentication, but none was provided.",
|
||||
"13002": "The provided link share password was invalid."
|
||||
},
|
||||
"about": {
|
||||
"title": "Apie",
|
||||
"version": "Versija: {version}"
|
||||
"title": "About",
|
||||
"version": "Version: {version}"
|
||||
},
|
||||
"time": {
|
||||
"units": {
|
||||
"seconds": "sekundė|sekundės",
|
||||
"minutes": "minutė|minutės",
|
||||
"hours": "valanda|valandos",
|
||||
"days": "diena|dienos",
|
||||
"weeks": "savaitė|savaitės",
|
||||
"months": "mėnesis|mėnesiai",
|
||||
"years": "metai|metai"
|
||||
"seconds": "second|seconds",
|
||||
"minutes": "minute|minutes",
|
||||
"hours": "hour|hours",
|
||||
"days": "day|days",
|
||||
"weeks": "week|weeks",
|
||||
"months": "month|months",
|
||||
"years": "year|years"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@
|
||||
"newPasswordTitle": "Uppdatera ditt lösenord",
|
||||
"newPassword": "Nytt lösenord",
|
||||
"newPasswordConfirm": "New password confirmation",
|
||||
"currentPassword": "Nuvarande lösenord",
|
||||
"currentPassword": "Current password",
|
||||
"currentPasswordPlaceholder": "Ditt nuvarande lösenord",
|
||||
"passwordsDontMatch": "The new password and its confirmation don't match.",
|
||||
"passwordUpdateSuccess": "The password was successfully updated.",
|
||||
@@ -83,7 +83,7 @@
|
||||
"updateEmailSuccess": "Your email address was successfully updated. We've sent you a link to confirm it.",
|
||||
"general": {
|
||||
"title": "General Settings",
|
||||
"name": "Mitt namn",
|
||||
"name": "My Name",
|
||||
"newName": "The new name",
|
||||
"savedSuccess": "The settings were successfully updated.",
|
||||
"emailReminders": "Send me reminders for tasks via email",
|
||||
@@ -396,7 +396,7 @@
|
||||
"bucketConfig": "Bucket configuration",
|
||||
"bucketConfigManual": "Manual",
|
||||
"filter": "Filter",
|
||||
"create": "Skapa vy",
|
||||
"create": "Create view",
|
||||
"createSuccess": "The view was created successfully.",
|
||||
"titleRequired": "Please provide a title.",
|
||||
"delete": "Delete this view",
|
||||
@@ -575,7 +575,7 @@
|
||||
"id": "ID",
|
||||
"created": "Created at",
|
||||
"createdBy": "Created by {0}",
|
||||
"actions": "Åtgärder",
|
||||
"actions": "Actions",
|
||||
"cannotBeUndone": "This cannot be undone!"
|
||||
},
|
||||
"input": {
|
||||
|
||||
@@ -5,13 +5,6 @@ import type { IAttachment } from '@/modelTypes/IAttachment'
|
||||
|
||||
import {downloadBlob} from '@/helpers/downloadBlob'
|
||||
|
||||
export enum PREVIEW_SIZE {
|
||||
SM = 'sm',
|
||||
MD = 'md',
|
||||
LG = 'lg',
|
||||
XL = 'xl',
|
||||
}
|
||||
|
||||
export default class AttachmentService extends AbstractService<IAttachment> {
|
||||
constructor() {
|
||||
super({
|
||||
@@ -44,13 +37,8 @@ export default class AttachmentService extends AbstractService<IAttachment> {
|
||||
return data
|
||||
}
|
||||
|
||||
getBlobUrl(model: IAttachment, size?: PREVIEW_SIZE) {
|
||||
let mainUrl = '/tasks/' + model.taskId + '/attachments/' + model.id
|
||||
if (size !== undefined) {
|
||||
mainUrl += `?preview=true&size=${size}`
|
||||
}
|
||||
|
||||
return AbstractService.prototype.getBlobUrl.call(this, mainUrl)
|
||||
getBlobUrl(model: IAttachment) {
|
||||
return AbstractService.prototype.getBlobUrl.call(this, '/tasks/' + model.taskId + '/attachments/' + model.id)
|
||||
}
|
||||
|
||||
async download(model: IAttachment) {
|
||||
|
||||
+2
-2
@@ -24,13 +24,13 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/initialize"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/term"
|
||||
|
||||
+8
-8
@@ -94,16 +94,16 @@ func AssertExists(t *testing.T, table string, values map[string]interface{}, cus
|
||||
} else {
|
||||
exists, err = x.Table(table).Where(values).Get(&v)
|
||||
}
|
||||
require.NoError(t, err, "Failed to assert entries exist in db")
|
||||
require.NoError(t, err, fmt.Sprintf("Failed to assert entries exist in db, error was: %s", err))
|
||||
if !exists {
|
||||
|
||||
all := []map[string]interface{}{}
|
||||
err = x.Table(table).Find(&all)
|
||||
require.NoErrorf(t, err, "Failed to assert entries exist in db, error was: %s", err)
|
||||
require.NoError(t, err, fmt.Sprintf("Failed to assert entries exist in db, error was: %s", err))
|
||||
pretty, err := json.MarshalIndent(all, "", " ")
|
||||
require.NoErrorf(t, err, "Failed to assert entries exist in db, error was: %s", err)
|
||||
require.NoError(t, err, fmt.Sprintf("Failed to assert entries exist in db, error was: %s", err))
|
||||
|
||||
t.Errorf("Entries %v do not exist in table %s\n\nFound entries instead: %v", values, table, string(pretty))
|
||||
t.Errorf(fmt.Sprintf("Entries %v do not exist in table %s\n\nFound entries instead: %v", values, table, string(pretty)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,13 +111,13 @@ func AssertExists(t *testing.T, table string, values map[string]interface{}, cus
|
||||
func AssertMissing(t *testing.T, table string, values map[string]interface{}) {
|
||||
v := make(map[string]interface{})
|
||||
exists, err := x.Table(table).Where(values).Exist(&v)
|
||||
require.NoErrorf(t, err, "Failed to assert entries don't exist in db, error was: %s", err)
|
||||
assert.Falsef(t, exists, "Entries %v exist in table %s", values, table)
|
||||
require.NoError(t, err, fmt.Sprintf("Failed to assert entries don't exist in db, error was: %s", err))
|
||||
assert.False(t, exists, fmt.Sprintf("Entries %v exist in table %s", values, table))
|
||||
}
|
||||
|
||||
// AssertCount checks if a number of entries exists in the database
|
||||
func AssertCount(t *testing.T, table string, where builder.Cond, count int64) {
|
||||
dbCount, err := x.Table(table).Where(where).Count()
|
||||
require.NoErrorf(t, err, "Failed to assert count in db, error was: %s", err)
|
||||
assert.Equalf(t, count, dbCount, "Found %d entries instead of expected %d in table %s", dbCount, count, table)
|
||||
require.NoError(t, err, fmt.Sprintf("Failed to assert count in db, error was: %s", err))
|
||||
assert.Equal(t, count, dbCount, fmt.Sprintf("Found %d entries instead of expected %d in table %s", dbCount, count, table))
|
||||
}
|
||||
|
||||
@@ -17,21 +17,14 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/png"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.vikunja.io/api/pkg/events"
|
||||
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/modules/keyvalue"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
@@ -192,94 +185,6 @@ func (ta *TaskAttachment) ReadAll(s *xorm.Session, _ web.Auth, _ string, page in
|
||||
return attachments, len(attachments), numberOfTotalItems, err
|
||||
}
|
||||
|
||||
func cacheKeyForTaskAttachmentPreview(id int64, size PreviewSize) string {
|
||||
return "task_attachment_preview_" + strconv.FormatInt(id, 10) + "_size_" + string(size)
|
||||
}
|
||||
|
||||
func (ta *TaskAttachment) GetPreviewFromCache(previewSize PreviewSize) []byte {
|
||||
cacheKey := cacheKeyForTaskAttachmentPreview(ta.ID, previewSize)
|
||||
|
||||
var cached []byte
|
||||
exists, err := keyvalue.GetWithValue(cacheKey, &cached)
|
||||
|
||||
// If the preview is not cached, return nil
|
||||
if err != nil || !exists || cached == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return cached
|
||||
}
|
||||
|
||||
type PreviewSize string
|
||||
|
||||
const (
|
||||
PreviewSmall PreviewSize = "sm"
|
||||
PreviewMedium PreviewSize = "md"
|
||||
PreviewLarge PreviewSize = "lg"
|
||||
PreviewExtraLarge PreviewSize = "xl"
|
||||
)
|
||||
|
||||
func (previewSize PreviewSize) GetSize() int {
|
||||
switch previewSize {
|
||||
case PreviewSmall:
|
||||
return 100
|
||||
case PreviewMedium:
|
||||
return 200
|
||||
case PreviewLarge:
|
||||
return 400
|
||||
case PreviewExtraLarge:
|
||||
return 800
|
||||
default:
|
||||
return 200
|
||||
}
|
||||
}
|
||||
|
||||
func resize(img image.Image, size int) *image.NRGBA {
|
||||
x := img.Bounds().Size().X
|
||||
y := img.Bounds().Size().Y
|
||||
heightSmaller := x > y
|
||||
var resizedImg *image.NRGBA
|
||||
if heightSmaller {
|
||||
resizedImg = imaging.Resize(img, 0, size, imaging.Lanczos)
|
||||
} else {
|
||||
resizedImg = imaging.Resize(img, size, 0, imaging.Lanczos)
|
||||
}
|
||||
log.Debugf("Resized attachment image from %vx%v to %vx%v for a preview", x, y, resizedImg.Bounds().Size().X, resizedImg.Bounds().Size().Y)
|
||||
|
||||
return resizedImg
|
||||
}
|
||||
|
||||
func (ta *TaskAttachment) GenerateAndSavePreviewToCache(previewSize PreviewSize) []byte {
|
||||
img, _, err := image.Decode(ta.File.File)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scale down the image to a minimum size
|
||||
resizedImg := resize(img, previewSize.GetSize())
|
||||
|
||||
// Get the raw bytes of the resized image
|
||||
buf := &bytes.Buffer{}
|
||||
if err := png.Encode(buf, resizedImg); err != nil {
|
||||
return nil
|
||||
}
|
||||
previewImage, err := io.ReadAll(buf)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Store the preview image in the cache
|
||||
cacheKey := cacheKeyForTaskAttachmentPreview(ta.ID, previewSize)
|
||||
err = keyvalue.Put(cacheKey, previewImage)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Infof("Attachment image preview for task attachment %v of size %v created and cached", ta.ID, previewSize)
|
||||
|
||||
return previewImage
|
||||
}
|
||||
|
||||
// Delete removes an attachment
|
||||
// @Summary Delete an attachment
|
||||
// @Description Delete an attachment.
|
||||
|
||||
@@ -18,14 +18,12 @@ package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
auth2 "code.vikunja.io/api/pkg/modules/auth"
|
||||
"code.vikunja.io/web/handler"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
@@ -117,8 +115,6 @@ func UploadTaskAttachment(c echo.Context) error {
|
||||
// @Produce octet-stream
|
||||
// @Param id path int true "Task ID"
|
||||
// @Param attachmentID path int true "Attachment ID"
|
||||
// @Param preview query string false "If set to true, a preview image will be returned if the attachment is an image."
|
||||
// @Param size query string false "The size of the preview image. Can be sm = 100px, md = 200px, lg = 400px or xl = 800px."
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {file} blob "The attachment file."
|
||||
// @Failure 403 {object} models.Message "No access to this task."
|
||||
@@ -157,23 +153,6 @@ func GetTaskAttachment(c echo.Context) error {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// Reading the 'preview' query parameter
|
||||
preview := c.QueryParam("preview") == "true"
|
||||
previewSize := models.PreviewSize(c.QueryParam("size"))
|
||||
if previewSize == "" {
|
||||
previewSize = models.PreviewMedium
|
||||
}
|
||||
|
||||
// If the preview query parameter is set and the preview was already generated and cached, return the cached preview image
|
||||
if preview && strings.HasPrefix(taskAttachment.File.Mime, "image") {
|
||||
previewFileBytes := taskAttachment.GetPreviewFromCache(previewSize)
|
||||
if previewFileBytes != nil {
|
||||
log.Debugf("Cached attachment image preview found for task attachment %v", taskAttachment.ID)
|
||||
|
||||
return c.Blob(http.StatusOK, "image/png", previewFileBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// Open an send the file to the client
|
||||
err = taskAttachment.File.LoadFileByID()
|
||||
if err != nil {
|
||||
@@ -186,14 +165,6 @@ func GetTaskAttachment(c echo.Context) error {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// If a preview is requested and the preview was not cached, we create the preview and cache it
|
||||
if preview {
|
||||
previewFileBytes := taskAttachment.GenerateAndSavePreviewToCache(previewSize)
|
||||
if previewFileBytes != nil {
|
||||
return c.Blob(http.StatusOK, "image/png", previewFileBytes)
|
||||
}
|
||||
}
|
||||
|
||||
http.ServeContent(c.Response(), c.Request(), taskAttachment.File.Name, taskAttachment.File.Created, taskAttachment.File.File)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ func TestListUsers(t *testing.T) {
|
||||
|
||||
all, err := ListUsers(s, "uSEr1", nil)
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, all)
|
||||
assert.NotEmpty(t, len(all))
|
||||
assert.Equal(t, "user1", all[0].Username)
|
||||
})
|
||||
t.Run("all users", func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user