580 lines
46 KiB
Plaintext
580 lines
46 KiB
Plaintext
package fileView
|
|
|
|
import (
|
|
"github.com/fossyy/filekeeper/types"
|
|
"github.com/fossyy/filekeeper/view/client/layout"
|
|
"github.com/fossyy/filekeeper/utils"
|
|
"strconv"
|
|
)
|
|
|
|
templ component(title string, files []types.FileData, user types.User, allowance *types.Allowance) {
|
|
@layout.BaseAuth(title) {
|
|
@MainContent(title, files, user, allowance)
|
|
}
|
|
}
|
|
|
|
templ MainContent(title string, files []types.FileData, user types.User, allowance *types.Allowance) {
|
|
<title>{ title }</title>
|
|
@layout.Navbar(user)
|
|
<main class="flex-grow h-full bg-gray-100">
|
|
<div class="bg-gray-50 min-h-screen px-4 py-8 sm:px-6 lg:px-8">
|
|
<a
|
|
class="inline-flex items-center space-x-2 rounded-md bg-muted px-4 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
|
|
href="/user"
|
|
hx-get="/user"
|
|
hx-swap="innerHTML"
|
|
hx-push-url="true"
|
|
hx-target="#content"
|
|
rel="ugc"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
class="h-4 w-4"
|
|
>
|
|
<path d="m12 19-7-7 7-7"></path>
|
|
<path d="M19 12H5"></path>
|
|
</svg>
|
|
<span>Back</span>
|
|
</a>
|
|
<div class="mx-auto max-w-7xl">
|
|
<div id="dropzone-file" class="border-2 border-dashed border-gray-300 rounded-lg p-8 mb-8 text-center hover:bg-gray-200 transition-colors duration-200 ease-in-out cursor-pointer">
|
|
<label for="file-upload" class="flex flex-col items-center justify-center pt-5 pb-6 cursor-pointer">
|
|
<svg class="w-12 h-12 mb-4 text-gray-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
|
|
</svg>
|
|
<p class="mb-2 text-lg text-gray-500 font-semibold">
|
|
Click to upload or drag and drop
|
|
</p>
|
|
</label>
|
|
<input id="file-upload" name="file-upload" type="file" class="hidden"/>
|
|
</div>
|
|
<div id="deleteModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden opacity-0 transition-opacity duration-300 z-50">
|
|
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white transform transition-all duration-300 -translate-y-full scale-95 opacity-0 z-50">
|
|
<div class="mt-3 text-center">
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900">Confirm Deletion</h3>
|
|
<div class="mt-2 px-7 py-3">
|
|
<p class="text-sm text-gray-500">
|
|
Are you sure you want to delete the file "<span class="font-medium break-all" id="fileNameToDelete"></span>"? This action cannot be undone.
|
|
</p>
|
|
</div>
|
|
<div class="items-center px-4 py-3">
|
|
<button onClick={ hideDeletionModal() } id="confirmDelete" class="px-4 py-2 bg-red-500 text-white text-base font-medium rounded-md w-full shadow-sm hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-300 transition duration-300">
|
|
Yes, delete file
|
|
</button>
|
|
<button onClick={ hideDeletionModal() } id="cancelDelete" class="mt-3 px-4 py-2 bg-white text-gray-700 text-base font-medium rounded-md w-full shadow-sm border border-gray-300 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-300 transition duration-300">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="renameModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden opacity-0 transition-opacity duration-300 z-50">
|
|
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
|
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
|
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
|
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
|
|
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
|
<div class="sm:flex sm:items-start">
|
|
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full">
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
|
|
Rename File
|
|
</h3>
|
|
<div class="mt-2">
|
|
<input id="newFileName" required type="text" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value=""/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
|
<button type="button" hx-swap="outerHTML" onClick={ hideRenameModal() } id="confirmRenameFile" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
|
Rename
|
|
</button>
|
|
<button type="button" onClick={ hideRenameModal() } class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mb-4 flex gap-4">
|
|
<div class="relative flex-grow">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
|
</svg>
|
|
<input type="text" hx-get="/file/query" hx-trigger="keyup changed delay:500ms, focus" hx-include="[name='status']" hx-target="#file-table" name="q" placeholder="Search files..." class="w-full pl-10 pr-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"/>
|
|
</div>
|
|
<select hx-get="/file/query" hx-trigger="change" hx-include="[name='q']" hx-target="#file-table" name="status" class="w-48 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<option value="">All</option>
|
|
<option value="private">Private</option>
|
|
<option value="public">Public</option>
|
|
</select>
|
|
</div>
|
|
<div id="shareModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden opacity-0 transition-opacity duration-300 z-50">
|
|
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
|
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
|
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
|
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
|
|
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
|
<div class="sm:flex sm:items-start">
|
|
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
|
|
Share link
|
|
</h3>
|
|
<button onClick={ hideShareModal() } type="button" class="text-gray-400 hover:text-gray-500 focus:outline-none focus:text-gray-500 transition ease-in-out duration-150">
|
|
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<p class="text-sm text-gray-500 mt-2">
|
|
Share this link with others to grant access to your file.
|
|
</p>
|
|
<div id="lockDiv">
|
|
<div id="privateWarning" class="mt-2 bg-red-50 border border-red-200 text-red-600 px-4 py-3 rounded-lg">
|
|
<div class="flex">
|
|
<i class="fas fa-exclamation-triangle mr-2 mt-1"></i>
|
|
<div>
|
|
<p class="font-semibold">File is private</p>
|
|
<p class="text-sm">Others cannot access or download your file even if you share the link. Make the file public first.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4 flex items-center bg-gray-100 rounded-lg">
|
|
<input id="shareLink" type="text" readonly class="bg-transparent flex-grow px-4 py-2 text-gray-700 focus:outline-none" value="https://example.com/share-link" aria-label="Share link"/>
|
|
<button id="copyButton" class="bg-gray-200 text-gray-600 px-4 py-2 rounded-r-lg hover:bg-gray-300 focus:outline-none">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>
|
|
</button>
|
|
</div>
|
|
<div class="mt-4">
|
|
<p class="text-sm font-medium text-gray-700 mb-2">Share on social media</p>
|
|
<div class="flex space-x-2">
|
|
<a id="twitterShare" href="" class="flex-1 bg-[#1DA1F2] hover:bg-[#1a8cd8] text-white font-medium py-2 px-4 rounded">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-twitter w-5 h-5 inline-block mr-1"><path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z"></path></svg>
|
|
Twitter
|
|
</a>
|
|
<a id="facebookShare" href="" class="flex-1 bg-[#4267B2] hover:bg-[#365899] text-white font-medium py-2 px-4 rounded">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-facebook w-5 h-5 inline-block mr-1"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg>
|
|
Facebook
|
|
</a>
|
|
<a id="linkedInShare" href="" class="flex-1 bg-[#0077B5] hover:bg-[#006699] text-white font-medium py-2 px-4 rounded">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-linkedin w-5 h-5 inline-block mr-1"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect width="4" height="12" x="2" y="9"></rect><circle cx="4" cy="4" r="2"></circle></svg>
|
|
LinkedIn
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="max-w-full overflow-hidden rounded-lg shadow-md bg-white">
|
|
<div class="overflow-x-auto">
|
|
<div class="inline-block min-w-full align-middle">
|
|
<div class="overflow-hidden">
|
|
<table id="file-table" class="w-full text-sm text-left text-gray-500">
|
|
<thead class="text-xs text-gray-700 uppercase bg-gray-50">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3 w-[40%]">File Name</th>
|
|
<th scope="col" class="px-6 py-3 w-[10%]">File Size</th>
|
|
<th scope="col" class="px-6 py-3 w-[10%]">Downloads</th>
|
|
<th scope="col" class="px-6 py-3 w-[20%]">Status</th>
|
|
<th scope="col" class="px-6 py-3 w-[20%]">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
for _, file := range files {
|
|
@JustFile(file)
|
|
}
|
|
</tbody>
|
|
</table>
|
|
<div class="bg-gray-50 px-10 py-10 border-t border-gray-200">
|
|
<div class="flex flex-col sm:flex-row justify-between items-center space-y-6 sm:space-y-0">
|
|
<div class="flex flex-col items-center sm:items-start space-y-2">
|
|
<span class="text-lg font-semibold text-gray-700">File Information</span>
|
|
<span class="text-base text-gray-600">Total Files: { strconv.Itoa(len(files)) }</span>
|
|
<span class="text-base text-gray-600">Total Usage: { allowance.AllowanceUsedByte }</span>
|
|
<span class="text-base text-gray-600">Total Allowance: { allowance.AllowanceByte }</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
<script type="text/javascript">
|
|
document.addEventListener("dragover", function (event) {
|
|
event.preventDefault();
|
|
document.getElementById('dropzone-file').classList.add('bg-gray-100', 'border-blue-500');
|
|
});
|
|
|
|
['dragenter', 'dragover'].forEach(eventName => {
|
|
document.getElementById('dropzone-file').addEventListener(eventName, highlight, false);
|
|
});
|
|
|
|
['dragleave', 'drop'].forEach(eventName => {
|
|
document.getElementById('dropzone-file').addEventListener(eventName, unhighlight, false);
|
|
});
|
|
|
|
function highlight(e) {
|
|
document.getElementById('dropzone-file').classList.add('bg-gray-100', 'border-blue-500');
|
|
}
|
|
|
|
function unhighlight(e) {
|
|
document.getElementById('dropzone-file').classList.remove('bg-gray-100', 'border-blue-500');
|
|
}
|
|
document.addEventListener("drop", async function (event) {
|
|
event.preventDefault();
|
|
const file = event.dataTransfer.files[0]
|
|
await handleFile(file)
|
|
});
|
|
|
|
document.getElementById('dropzone-file').addEventListener('change', async function(event) {
|
|
event.preventDefault();
|
|
const file = event.target.files[0]
|
|
await handleFile(file)
|
|
});
|
|
</script>
|
|
}
|
|
|
|
script toggleDropDown() {
|
|
const dropdowns = document.querySelectorAll('.dropdown');
|
|
|
|
dropdowns.forEach(dropdown => {
|
|
const button = dropdown.querySelector('.dropdown-button');
|
|
const menu = dropdown.querySelector('.dropdown-menu');
|
|
|
|
if (button.contains(event.target)) {
|
|
dropdowns.forEach(otherDropdown => {
|
|
if (otherDropdown !== dropdown) {
|
|
otherDropdown.querySelector('.dropdown-menu').classList.add('hidden');
|
|
}
|
|
});
|
|
menu.classList.toggle('hidden');
|
|
} else if (!menu.contains(event.target)) {
|
|
menu.classList.add('hidden');
|
|
}
|
|
});
|
|
}
|
|
|
|
templ FileTable(files []types.FileData) {
|
|
<table id="file-table" class="w-full text-sm text-left text-gray-500">
|
|
<thead class="text-xs text-gray-700 uppercase bg-gray-50">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3 w-[40%]">File Name</th>
|
|
<th scope="col" class="px-6 py-3 w-[10%]">File Size</th>
|
|
<th scope="col" class="px-6 py-3 w-[10%]">Downloads</th>
|
|
<th scope="col" class="px-6 py-3 w-[20%]">Status</th>
|
|
<th scope="col" class="px-6 py-3 w-[20%]">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
for _, file := range files {
|
|
@JustFile(file)
|
|
}
|
|
</tbody>
|
|
</table>
|
|
}
|
|
|
|
templ JustFile(file types.FileData) {
|
|
<tr id={ "file-" + file.ID.String() } class="bg-white border-b">
|
|
if !file.Done {
|
|
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap flex items-center">
|
|
@FileIcon(file.Type)
|
|
<div class="rounded-md p-3 flex items-center space-x-3 relative w-[80%]">
|
|
<span class="text-sm font-medium truncate tooltip" data-tooltip={ file.Name }>
|
|
{ file.Name }
|
|
</span>
|
|
<div class="flex justify-end text-red-500 mr-2 tooltip" data-tooltip="File is corrupted. Please reupload.">
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
</svg>
|
|
<span class="text-xs font-medium">Corrupted</span>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
} else {
|
|
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap flex items-center">
|
|
@FileIcon(file.Type)
|
|
<div class="rounded-md p-3 flex items-center space-x-3 relative w-[80%]">
|
|
<span class="text-sm font-medium truncate tooltip" data-tooltip={ file.Name }>
|
|
{ file.Name }
|
|
</span>
|
|
</div>
|
|
</td>
|
|
}
|
|
<td class="px-6 py-4">{ utils.ConvertFileSize(file.Size) }</td>
|
|
<td class="px-6 py-4">
|
|
<div class="flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-5 w-5 mr-2 text-gray-400">
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
|
<polyline points="7 10 12 15 17 10"></polyline>
|
|
<line x1="12" x2="12" y1="15" y2="3"></line>
|
|
</svg>
|
|
{ utils.IntToString(file.Downloaded) }
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
<div class="flex items-center space-x-2">
|
|
if file.IsPrivate {
|
|
<div class="flex items-center space-x-2">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5 text-gray-600"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
|
></path>
|
|
</svg>
|
|
<span class="text-sm text-gray-700">Private</span>
|
|
</div>
|
|
} else {
|
|
<div class="flex items-center space-x-2">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5 text-gray-600"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
></path>
|
|
</svg>
|
|
<span class="text-sm text-gray-700">Public</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
<div class="dropdown relative inline-block text-left">
|
|
<button onClick={ toggleDropDown() } id="dropdown-button" class="dropdown-button bg-white border border-gray-300 rounded-md px-4 py-2 inline-flex items-center justify-center text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
|
<svg fill="#000000" height="12px" width="12px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32.055 32.055" xml:space="preserve"><g stroke-width="0"></g><g stroke-linecap="round" stroke-linejoin="round"></g><g><g><path d="M3.968,12.061C1.775,12.061,0,13.835,0,16.027c0,2.192,1.773,3.967,3.968,3.967c2.189,0,3.966-1.772,3.966-3.967 C7.934,13.835,6.157,12.061,3.968,12.061z M16.233,12.061c-2.188,0-3.968,1.773-3.968,3.965c0,2.192,1.778,3.967,3.968,3.967 s3.97-1.772,3.97-3.967C20.201,13.835,18.423,12.061,16.233,12.061z M28.09,12.061c-2.192,0-3.969,1.774-3.969,3.967 c0,2.19,1.774,3.965,3.969,3.965c2.188,0,3.965-1.772,3.965-3.965S30.278,12.061,28.09,12.061z"></path> </g> </g></svg>
|
|
</button>
|
|
<div class="dropdown-menu hidden absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 z-10">
|
|
if file.Done {
|
|
<div class="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
|
|
<a href={ templ.SafeURL("/file/" + file.ID.String()) } class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 w-full" role="menuitem">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" x2="12" y1="15" y2="3"></line></svg>
|
|
<i class="ri-file-copy-line mr-3 text-gray-400"></i> Download
|
|
</a>
|
|
if file.IsPrivate {
|
|
<button class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 w-full" role="menuitem" hx-put={ "/file/" + file.ID.String() } hx-target={ "#file-" + file.ID.String() } hx-swap="outerHTML">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4 text-gray-600"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
></path>
|
|
</svg>
|
|
<i class="ri-delete-bin-line mr-3 text-gray-400"></i> Make Public
|
|
</button>
|
|
} else {
|
|
<button class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 w-full" role="menuitem" hx-put={ "/file/" + file.ID.String() } hx-target={ "#file-" + file.ID.String() } hx-swap="outerHTML">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4 text-gray-600"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
|
></path>
|
|
</svg>
|
|
<i class="ri-delete-bin-line mr-3 text-gray-400"></i> Make Private
|
|
</button>
|
|
}
|
|
<button onClick={ showShareModal(file.IsPrivate, file.ID.String()) } class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 w-full" role="menuitem">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-share-2"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"></line><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"></line></svg>
|
|
<i class="ri-delete-bin-line mr-3 text-gray-400"></i> Share
|
|
</button>
|
|
</div>
|
|
}
|
|
<div class="py-1 border-t" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
|
|
<button onClick={ showRenameModal(file.Name, file.ID.String()) } class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 w-full" role="menuitem">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-folder-pen"><path d="M2 11.5V5a2 2 0 0 1 2-2h3.9c.7 0 1.3.3 1.7.9l.8 1.2c.4.6 1 .9 1.7.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-9.5"></path><path d="M11.378 13.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"></path></svg>
|
|
<i class="ri-share-line mr-3 text-gray-400"></i> Rename
|
|
</button>
|
|
<button onClick={ showDeletionModal(file.Name, file.ID.String()) } class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 w-full" role="menuitem">
|
|
<svg width="16px" height="16px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g stroke-width="0"></g><g stroke-linecap="round" stroke-linejoin="round"></g><g><path d="M20.5001 6H3.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round"></path> <path d="M9.5 11L10 16" stroke="#000000" stroke-width="1.5" stroke-linecap="round"></path> <path d="M14.5 11L14 16" stroke="#000000" stroke-width="1.5" stroke-linecap="round"></path> <path d="M6.5 6C6.55588 6 6.58382 6 6.60915 5.99936C7.43259 5.97849 8.15902 5.45491 8.43922 4.68032C8.44784 4.65649 8.45667 4.62999 8.47434 4.57697L8.57143 4.28571C8.65431 4.03708 8.69575 3.91276 8.75071 3.8072C8.97001 3.38607 9.37574 3.09364 9.84461 3.01877C9.96213 3 10.0932 3 10.3553 3H13.6447C13.9068 3 14.0379 3 14.1554 3.01877C14.6243 3.09364 15.03 3.38607 15.2493 3.8072C15.3043 3.91276 15.3457 4.03708 15.4286 4.28571L15.5257 4.57697C15.5433 4.62992 15.5522 4.65651 15.5608 4.68032C15.841 5.45491 16.5674 5.97849 17.3909 5.99936C17.4162 6 17.4441 6 17.5 6" stroke="#000000" stroke-width="1.5"></path> <path d="M18.3735 15.3991C18.1965 18.054 18.108 19.3815 17.243 20.1907C16.378 21 15.0476 21 12.3868 21H11.6134C8.9526 21 7.6222 21 6.75719 20.1907C5.89218 19.3815 5.80368 18.054 5.62669 15.3991L5.16675 8.5M18.8334 8.5L18.6334 11.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round"></path> </g></svg>
|
|
<i class="ri-clipboard-line mr-3 text-gray-400"></i> Remove
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
|
|
templ FileIcon(fileType string) {
|
|
if fileType == "jpg" || fileType == "jpeg" || fileType == "png" || fileType == "gif" || fileType == "bmp" || fileType == "tiff" {
|
|
<svg width="24px" height="24px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><title>image-picture</title> <desc>Created with Sketch Beta.</desc> <defs></defs> <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"><g id="Icon-Set" sketch:type="MSLayerGroup" transform="translate(-360.000000, -99.000000)" fill="#000000"><path d="M368,109 C366.896,109 366,108.104 366,107 C366,105.896 366.896,105 368,105 C369.104,105 370,105.896 370,107 C370,108.104 369.104,109 368,109 L368,109 Z M368,103 C365.791,103 364,104.791 364,107 C364,109.209 365.791,111 368,111 C370.209,111 372,109.209 372,107 C372,104.791 370.209,103 368,103 L368,103 Z M390,116.128 L384,110 L374.059,120.111 L370,116 L362,123.337 L362,103 C362,101.896 362.896,101 364,101 L388,101 C389.104,101 390,101.896 390,103 L390,116.128 L390,116.128 Z M390,127 C390,128.104 389.104,129 388,129 L382.832,129 L375.464,121.535 L384,112.999 L390,118.999 L390,127 L390,127 Z M364,129 C362.896,129 362,128.104 362,127 L362,126.061 L369.945,118.945 L380.001,129 L364,129 L364,129 Z M388,99 L364,99 C361.791,99 360,100.791 360,103 L360,127 C360,129.209 361.791,131 364,131 L388,131 C390.209,131 392,129.209 392,127 L392,103 C392,100.791 390.209,99 388,99 L388,99 Z" id="image-picture" sketch:type="MSShapeGroup"></path> </g> </g> </g></svg>
|
|
} else if fileType == "pdf" || fileType == "doc" || fileType == "docx" || fileType == "txt" || fileType == "odt" || fileType == "xls" || fileType == "xlsx" || fileType == "ppt" || fileType == "pptx" {
|
|
<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 70 70" enable-background="new 0 0 70 70" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><g><path d="M47.248,22.583c1.104,0,1.335-0.284,1.335-1.389v-8.863c0-1.104-0.23-1.748-1.335-1.748H23.936 c-1.104,0-2.353,0.644-2.353,1.748v8.863c0,1.104,0.248,1.389,1.353,1.389H47.248z M23.583,12.583h23v8h-23V12.583z"></path> <path d="M62.341,12.866l-8.226-8.649c-0.75-0.75-1.803-1.634-2.863-1.634H17.439c-2.209,0-3.856,2.716-3.856,4.925v55.075h-3 V30.417c0-1.104-0.896-2-2-2s-2,0.896-2,2v35c0,1.104,1.229,1.166,2.334,1.166h8.522h6.478h35.522c2.209,0,4.144-0.866,4.144-3.075 V15.694C63.583,14.634,63.091,13.616,62.341,12.866z M58.791,14.583h-7.208V7.86L58.791,14.583z M23.917,62.583h-6.334v-56h32.014 l-0.014,8.834c0,0.553,0.781,1.166,1.334,1.166h8.666v46H23.917z"></path> <path d="M33.917,26.583h-10c-0.553,0-1,0.447-1,1s0.447,1,1,1h10c0.553,0,1-0.447,1-1S34.47,26.583,33.917,26.583z"></path> <path d="M50.917,26.583h-13c-0.553,0-1,0.447-1,1s0.447,1,1,1h13c0.553,0,1-0.447,1-1S51.47,26.583,50.917,26.583z"></path> <path d="M23.917,33.583h4c0.553,0,1-0.447,1-1s-0.447-1-1-1h-4c-0.553,0-1,0.447-1,1S23.364,33.583,23.917,33.583z"></path> <path d="M39.917,32.583c0-0.553-0.447-1-1-1h-7c-0.553,0-1,0.447-1,1s0.447,1,1,1h7C39.47,33.583,39.917,33.136,39.917,32.583z"></path> <path d="M31.917,36.583h-8c-0.553,0-1,0.447-1,1s0.447,1,1,1h8c0.553,0,1-0.447,1-1S32.47,36.583,31.917,36.583z"></path> <path d="M50.917,36.583h-15c-0.553,0-1,0.447-1,1s0.447,1,1,1h15c0.553,0,1-0.447,1-1S51.47,36.583,50.917,36.583z"></path> <path d="M50.917,31.583h-7c-0.553,0-1,0.447-1,1s0.447,1,1,1h7c0.553,0,1-0.447,1-1S51.47,31.583,50.917,31.583z"></path> <path d="M42.917,56.583h-7c-0.553,0-1,0.447-1,1s0.447,1,1,1h7c0.553,0,1-0.447,1-1S43.47,56.583,42.917,56.583z"></path> <path d="M50.917,51.583h-8c-0.553,0-1,0.447-1,1s0.447,1,1,1h8c0.553,0,1-0.447,1-1S51.47,51.583,50.917,51.583z"></path> <path d="M22.917,52.583c0,0.553,0.447,1,1,1h15c0.553,0,1-0.447,1-1s-0.447-1-1-1h-15C23.364,51.583,22.917,52.03,22.917,52.583z"></path> <path d="M30.917,56.583h-7c-0.553,0-1,0.447-1,1s0.447,1,1,1h7c0.553,0,1-0.447,1-1S31.47,56.583,30.917,56.583z"></path> <path d="M23.917,43.583h6c0.553,0,1-0.447,1-1s-0.447-1-1-1h-6c-0.553,0-1,0.447-1,1S23.364,43.583,23.917,43.583z"></path> <path d="M50.917,41.583h-17c-0.553,0-1,0.447-1,1s0.447,1,1,1h17c0.553,0,1-0.447,1-1S51.47,41.583,50.917,41.583z"></path> <path d="M36.917,46.583h-13c-0.553,0-1,0.447-1,1s0.447,1,1,1h13c0.553,0,1-0.447,1-1S37.47,46.583,36.917,46.583z"></path> <path d="M50.917,46.583h-10c-0.553,0-1,0.447-1,1s0.447,1,1,1h10c0.553,0,1-0.447,1-1S51.47,46.583,50.917,46.583z"></path> </g> </g></svg>
|
|
} else if fileType == "zip" || fileType == "rar" || fileType == "tar" || fileType == "gz" || fileType == "7z" || fileType == "bz2" {
|
|
<svg width="24px" height="24px" viewBox="0 0 192 192" xmlns="http://www.w3.org/2000/svg" id="Layer_1" fill="#000000">
|
|
<g stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
|
<defs>
|
|
<style>.cls-2,.cls-3{fill:none;stroke-width:8px;stroke:#000000;stroke-linecap:round}.cls-2{stroke-miterlimit:10}.cls-3{stroke-linejoin:round}</style>
|
|
</defs><path d="M0 0h192v192H0z" style="fill:none"></path><path d="M21.68 31.74h148.64c.94 5.92 1.64 12.88 1.68 20.68.04 8.29-.69 15.66-1.68 21.86H21.68c-.98-6.2-1.71-13.57-1.68-21.86.03-7.8.74-14.76 1.68-20.68Z" class="cls-3"></path><path d="M34.53 41.34v22.35" class="cls-2"></path><path d="M71.38 116.78h-49.7c-.98-6.2-1.71-13.57-1.68-21.86.03-7.8.74-14.76 1.68-20.68h148.64c.94 5.92 1.64 12.88 1.68 20.68.04 8.29-.69 15.66-1.68 21.86H119" class="cls-3"></path><path d="M34.53 83.85v22.36" class="cls-2"></path><path d="M119.01 116.75h51.32c.94 5.92 1.64 12.88 1.68 20.68.04 8.29-.69 15.66-1.68 21.86H21.68c-.98-6.2-1.71-13.57-1.68-21.86.03-7.8.74-14.76 1.68-20.68h49.71" class="cls-3"></path><path d="M34.53 127.37v22.35" class="cls-2"></path><path d="M74.74 28.18h42.51v135.63H74.74z" style="stroke-width:12px;stroke-linejoin:round;stroke:#000000;stroke-linecap:round;fill:none"></path><path d="M74.74 89h-5.06l-2.02 42.43h56.68L122.32 89h-5.06" class="cls-3"></path><path d="m92.96 129-2.02-16.2c.51-2.39 2.65-4.1 5.06-4.05 2.34.05 4.36 1.73 4.85 4.05-.61 5.4-1.21 10.8-1.82 16.2h-6.07Z" style="stroke-width:6px;stroke-linejoin:round;stroke:#000000;stroke-linecap:round;fill:none"></path>
|
|
</svg>
|
|
} else if fileType == "exe" || fileType == "bin" || fileType == "sh" || fileType == "bat" || fileType == "cmd" || fileType == "msi" {
|
|
<svg width="24px" height="24px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#000000"><g stroke-width="0"></g><g stroke-linecap="round" stroke-linejoin="round"></g> <path d="m 8 0 c -0.769531 0 -1.539062 0.292969 -2.121094 0.875 l -5.003906 5.003906 c -1.164062 1.164063 -1.164062 3.078125 0 4.242188 l 5.003906 5.003906 c 1.164063 1.164062 3.078125 1.164062 4.242188 0 l 5.007812 -5.003906 c 1.164063 -1.164063 1.164063 -3.078125 0 -4.242188 l -5.007812 -5.003906 c -0.582032 -0.582031 -1.351563 -0.875 -2.121094 -0.875 z m 0.101562 1.988281 c 0.210938 0.023438 0.414063 0.117188 0.585938 0.28125 l -0.339844 0.113281 c -0.074218 -0.136718 -0.15625 -0.269531 -0.246094 -0.394531 z m -1.570312 1.058594 c 0.300781 0.421875 0.464844 0.929687 0.46875 1.453125 c 0 1.378906 -1.121094 2.5 -2.5 2.5 c -0.523438 -0.003906 -1.03125 -0.171875 -1.449219 -0.472656 z m 3.441406 0.503906 l 3.742188 3.742188 c 0.402344 0.402343 0.402344 1.011719 0 1.414062 l -0.253906 0.25 c -0.039063 -0.046875 -0.074219 -0.09375 -0.117188 -0.140625 l 0.621094 -0.855468 l -0.808594 -0.585938 l -0.621094 0.851562 c -0.167968 -0.078124 -0.347656 -0.136718 -0.535156 -0.175781 v -1.050781 h -1 v 1.050781 c -0.183594 0.039063 -0.363281 0.097657 -0.53125 0.175781 l -0.621094 -0.851562 l -0.804687 0.585938 l 0.617187 0.855468 c -0.125 0.136719 -0.238281 0.289063 -0.332031 0.453125 l -1 -0.324219 l -0.308594 0.949219 l 1 0.324219 c -0.011719 0.09375 -0.019531 0.1875 -0.019531 0.28125 s 0.007812 0.1875 0.019531 0.28125 l -1 0.324219 l 0.308594 0.949219 l 1 -0.324219 c 0.09375 0.164062 0.207031 0.316406 0.332031 0.453125 l -0.617187 0.855468 l 0.195312 0.140626 l -0.53125 0.53125 c -0.402343 0.40625 -1.011719 0.40625 -1.414062 0 l -4.902344 -4.902344 l 0.027344 -0.039063 l 0.207031 -0.289062 c 0.332031 0.152343 0.683594 0.269531 1.046875 0.339843 v 1.179688 h 1.652344 v -1.179688 c 0.363281 -0.070312 0.714843 -0.1875 1.046875 -0.339843 l 0.207031 0.289062 l 0.484375 0.667969 l 1.332031 -0.972656 l -0.480469 -0.667969 l -0.210937 -0.289063 c 0.25 -0.269531 0.46875 -0.566406 0.644531 -0.890624 l 0.339844 0.113281 l 0.785156 0.253906 l 0.511719 -1.566406 l -0.785156 -0.257813 l -0.339844 -0.109375 c 0.023437 -0.179687 0.039063 -0.363281 0.039063 -0.550781 s -0.015626 -0.371094 -0.039063 -0.550781 l 0.339844 -0.109375 l 0.785156 -0.257813 z m 1.527344 5.449219 c 0.527344 0 0.984375 0.265625 1.25 0.667969 l -2.078125 2.082031 c -0.40625 -0.269531 -0.671875 -0.722656 -0.671875 -1.25 c 0 -0.835938 0.667969 -1.5 1.5 -1.5 z m 0 0" fill="#000000"></path> </svg>
|
|
} else if fileType == "apk" {
|
|
<svg fill="#000000" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 585.918 585.918" xml:space="preserve"><g stroke-width="0"></g><g stroke-linecap="round" stroke-linejoin="round"></g> <g><path d="M357.396,535.33c0.776,0.042,1.542,0.109,2.329,0.109h177.39c20.75,0,37.627-16.883,37.627-37.627V86.597 c0-20.743-16.877-37.628-37.627-37.628h-177.39c-0.781,0-1.553,0.077-2.329,0.113V0L11.176,46.206v492.311l346.22,47.401V535.33z M359.726,70.476h177.39c8.893,0,16.125,7.236,16.125,16.126v411.22c0,8.888-7.232,16.127-16.125,16.127h-10.803l3.127-2.794 l0.504-0.509c7.256-7.271,7.256-19.16-0.011-26.432c-7.264-7.264-19.154-7.264-26.426,0.006l-27.044,27.028h-13.219l33.653-33.648 L377.964,358.677l-20.567,20.566v-13.214l13.953-13.956c7.274-7.281,7.274-19.165,0-26.437c-3.833-3.838-8.926-5.539-13.953-5.292 V70.711C358.162,70.599,358.929,70.476,359.726,70.476z M90.498,346.57l-7.979-28.636l-29.124-0.351l-7.126,27.869l-23.105-0.589 l30.226-108.52l30.184-0.785l32.494,111.658L90.498,346.57z M199.945,295.804c-8.811,8.447-21.743,12.153-36.638,12.042 c-3.297-0.026-6.257-0.221-8.525-0.566v40.925l-24.41-0.61V235.866c7.535-1.538,18.205-2.832,33.417-3.236 c15.598-0.409,26.845,2.402,34.457,8.443c7.326,5.743,12.294,15.397,12.294,26.883C210.541,279.46,206.772,289.206,199.945,295.804 z M294.378,351.762l-30.057-52.629l-10.376,12.566v39.034l-26.614-0.672V231.835l26.614-0.693v52.882h0.528 c2.676-4.626,5.541-8.918,8.229-13.207l27.813-40.623l34.895-0.913l-41.5,52.662l43.786,70.666L294.378,351.762z"></path> <path d="M165.112,252.223c-5.103,0.097-8.536,0.661-10.331,1.205v33.798c2.11,0.507,4.746,0.672,8.357,0.672 c13.417-0.021,21.766-7.095,21.766-18.974C184.9,258.25,177.706,252.002,165.112,252.223z"></path> <path d="M522.731,381.831l24.43-7.712c1.218-0.382,1.911-1.706,1.514-2.93c-0.368-1.233-1.701-1.914-2.919-1.526l-24.798,7.816 c-4.085-9.217-9.902-17.854-17.462-25.411c-7.547-7.555-16.188-13.366-25.416-17.451l7.822-24.803 c0.387-1.224-0.294-2.54-1.524-2.93c-1.227-0.382-2.54,0.311-2.929,1.534l-7.706,24.425c-27.187-10.242-58.604-5.922-82.205,12.986 l118.201,118.196C528.652,440.437,532.979,409.008,522.731,381.831z M453.617,368.263c-5.29,5.274-13.868,5.274-19.16-0.011 c-5.292-5.287-5.292-13.87,0-19.155c5.28-5.292,13.87-5.292,19.171,0C458.909,354.388,458.909,362.965,453.617,368.263z M487.308,421.112c-5.291-5.285-5.28-13.868,0-19.154c5.303-5.293,13.869-5.293,19.172,0c5.285,5.286,5.285,13.869,0,19.154 C501.177,426.41,492.61,426.41,487.308,421.112z"></path> <path d="M69.043,255.89h-0.307c-1.499,6.552-3.016,14.89-4.659,21.252l-5.984,23.266l22.481,0.078l-6.386-23.412 C72.371,270.543,70.555,262.399,69.043,255.89z"></path> </g></svg>
|
|
} else {
|
|
<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M13 3L13.7071 2.29289C13.5196 2.10536 13.2652 2 13 2V3ZM19 9H20C20 8.73478 19.8946 8.48043 19.7071 8.29289L19 9ZM13.109 8.45399L14 8V8L13.109 8.45399ZM13.546 8.89101L14 8L13.546 8.89101ZM10 13C10 12.4477 9.55228 12 9 12C8.44772 12 8 12.4477 8 13H10ZM8 16C8 16.5523 8.44772 17 9 17C9.55228 17 10 16.5523 10 16H8ZM8.5 9C7.94772 9 7.5 9.44772 7.5 10C7.5 10.5523 7.94772 11 8.5 11V9ZM9.5 11C10.0523 11 10.5 10.5523 10.5 10C10.5 9.44772 10.0523 9 9.5 9V11ZM8.5 6C7.94772 6 7.5 6.44772 7.5 7C7.5 7.55228 7.94772 8 8.5 8V6ZM9.5 8C10.0523 8 10.5 7.55228 10.5 7C10.5 6.44772 10.0523 6 9.5 6V8ZM17.908 20.782L17.454 19.891L17.454 19.891L17.908 20.782ZM18.782 19.908L19.673 20.362L18.782 19.908ZM5.21799 19.908L4.32698 20.362H4.32698L5.21799 19.908ZM6.09202 20.782L6.54601 19.891L6.54601 19.891L6.09202 20.782ZM6.09202 3.21799L5.63803 2.32698L5.63803 2.32698L6.09202 3.21799ZM5.21799 4.09202L4.32698 3.63803L4.32698 3.63803L5.21799 4.09202ZM12 3V7.4H14V3H12ZM14.6 10H19V8H14.6V10ZM12 7.4C12 7.66353 11.9992 7.92131 12.0169 8.13823C12.0356 8.36682 12.0797 8.63656 12.218 8.90798L14 8C14.0293 8.05751 14.0189 8.08028 14.0103 7.97537C14.0008 7.85878 14 7.69653 14 7.4H12ZM14.6 8C14.3035 8 14.1412 7.99922 14.0246 7.9897C13.9197 7.98113 13.9425 7.9707 14 8L13.092 9.78201C13.3634 9.92031 13.6332 9.96438 13.8618 9.98305C14.0787 10.0008 14.3365 10 14.6 10V8ZM12.218 8.90798C12.4097 9.2843 12.7157 9.59027 13.092 9.78201L14 8V8L12.218 8.90798ZM8 13V16H10V13H8ZM8.5 11H9.5V9H8.5V11ZM8.5 8H9.5V6H8.5V8ZM13 2H8.2V4H13V2ZM4 6.2V17.8H6V6.2H4ZM8.2 22H15.8V20H8.2V22ZM20 17.8V9H18V17.8H20ZM19.7071 8.29289L13.7071 2.29289L12.2929 3.70711L18.2929 9.70711L19.7071 8.29289ZM15.8 22C16.3436 22 16.8114 22.0008 17.195 21.9694C17.5904 21.9371 17.9836 21.8658 18.362 21.673L17.454 19.891C17.4045 19.9162 17.3038 19.9539 17.0322 19.9761C16.7488 19.9992 16.3766 20 15.8 20V22ZM18 17.8C18 18.3766 17.9992 18.7488 17.9761 19.0322C17.9539 19.3038 17.9162 19.4045 17.891 19.454L19.673 20.362C19.8658 19.9836 19.9371 19.5904 19.9694 19.195C20.0008 18.8114 20 18.3436 20 17.8H18ZM18.362 21.673C18.9265 21.3854 19.3854 20.9265 19.673 20.362L17.891 19.454C17.7951 19.6422 17.6422 19.7951 17.454 19.891L18.362 21.673ZM4 17.8C4 18.3436 3.99922 18.8114 4.03057 19.195C4.06287 19.5904 4.13419 19.9836 4.32698 20.362L6.10899 19.454C6.0838 19.4045 6.04612 19.3038 6.02393 19.0322C6.00078 18.7488 6 18.3766 6 17.8H4ZM8.2 20C7.62345 20 7.25117 19.9992 6.96784 19.9761C6.69617 19.9539 6.59545 19.9162 6.54601 19.891L5.63803 21.673C6.01641 21.8658 6.40963 21.9371 6.80497 21.9694C7.18864 22.0008 7.65645 22 8.2 22V20ZM4.32698 20.362C4.6146 20.9265 5.07354 21.3854 5.63803 21.673L6.54601 19.891C6.35785 19.7951 6.20487 19.6422 6.10899 19.454L4.32698 20.362ZM8.2 2C7.65645 2 7.18864 1.99922 6.80497 2.03057C6.40963 2.06287 6.01641 2.13419 5.63803 2.32698L6.54601 4.10899C6.59545 4.0838 6.69617 4.04612 6.96784 4.02393C7.25117 4.00078 7.62345 4 8.2 4V2ZM6 6.2C6 5.62345 6.00078 5.25117 6.02393 4.96784C6.04612 4.69617 6.0838 4.59545 6.10899 4.54601L4.32698 3.63803C4.13419 4.01641 4.06287 4.40963 4.03057 4.80497C3.99922 5.18864 4 5.65645 4 6.2H6ZM5.63803 2.32698C5.07354 2.6146 4.6146 3.07354 4.32698 3.63803L6.10899 4.54601C6.20487 4.35785 6.35785 4.20487 6.54601 4.10899L5.63803 2.32698Z" fill="#000000"></path> </g></svg>
|
|
}
|
|
}
|
|
|
|
script showDeletionModal(name string, id string) {
|
|
const modal = document.getElementById('deleteModal');
|
|
const modalContent = modal.querySelector('div');
|
|
const confirmDelete = document.getElementById('confirmDelete');
|
|
const fileNameToDelete = document.getElementById('fileNameToDelete');
|
|
|
|
confirmDelete.setAttribute("hx-delete", "/file/" + id + "?consent=true");
|
|
confirmDelete.setAttribute("hx-target", "#file-" + id);
|
|
htmx.process(confirmDelete);
|
|
modal.classList.remove('hidden');
|
|
setTimeout(() => {
|
|
modal.classList.remove('opacity-0');
|
|
modalContent.classList.remove('-translate-y-full', 'scale-95', 'opacity-0');
|
|
}, 50);
|
|
fileNameToDelete.textContent = name;
|
|
}
|
|
|
|
script hideDeletionModal() {
|
|
const modal = document.getElementById('deleteModal');
|
|
const modalContent = modal.querySelector('div');
|
|
|
|
modal.classList.add('opacity-0');
|
|
modalContent.classList.add('-translate-y-full', 'scale-95', 'opacity-0');
|
|
setTimeout(() => {
|
|
modal.classList.add('hidden');
|
|
}, 300);
|
|
}
|
|
|
|
script showRenameModal(name string, id string) {
|
|
const rename = document.getElementById('renameModal');
|
|
const renameModalContent = rename.querySelector('div');
|
|
const fileName = document.getElementById("newFileName");
|
|
const confirmRenameFile = document.getElementById("confirmRenameFile");
|
|
|
|
confirmRenameFile.setAttribute("hx-target", "#file-" + id);
|
|
htmx.process(confirmRenameFile);
|
|
|
|
fileName.addEventListener("change", function (event) {
|
|
event.preventDefault();
|
|
confirmRenameFile.setAttribute("hx-patch", "/file/" + id + "?name=" + event.target.value);
|
|
htmx.process(confirmRenameFile);
|
|
});
|
|
rename.classList.remove('hidden');
|
|
setTimeout(() => {
|
|
rename.classList.remove('opacity-0');
|
|
renameModalContent.classList.remove('-translate-y-full', 'scale-95', 'opacity-0');
|
|
}, 50);
|
|
fileName.value = name
|
|
}
|
|
|
|
script hideRenameModal() {
|
|
const rename = document.getElementById('renameModal');
|
|
const renameModalContent = rename.querySelector('div');
|
|
|
|
rename.classList.add('opacity-0');
|
|
renameModalContent.classList.add('-translate-y-full', 'scale-95', 'opacity-0');
|
|
setTimeout(() => {
|
|
rename.classList.add('hidden');
|
|
}, 300);
|
|
}
|
|
|
|
script showShareModal(isPrivate bool, fileID string) {
|
|
const shareModal = document.getElementById('shareModal');
|
|
const shareModalContent = shareModal.querySelector('div');
|
|
const publicToggle = document.getElementById('public-toggle');
|
|
const lockDiv = document.getElementById('lockDiv');
|
|
const privateWarning = document.getElementById('privateWarning');
|
|
const shareLink = document.getElementById('shareLink');
|
|
const copyButton = document.getElementById('copyButton');
|
|
|
|
if (!isPrivate) {
|
|
lockDiv.classList.add('hidden');
|
|
} else {
|
|
lockDiv.classList.remove('hidden');
|
|
}
|
|
|
|
shareLink.value = window.location + "/" + fileID
|
|
|
|
const twitterLink = document.getElementById('twitterShare');
|
|
const facebookLink = document.getElementById('facebookShare');
|
|
const linkedinLink = document.getElementById('linkedInShare');
|
|
|
|
const twitterShareURL = `https://twitter.com/intent/tweet?url=${encodeURIComponent(shareLink.value)}`;
|
|
twitterLink.setAttribute('href', twitterShareURL);
|
|
|
|
const facebookShareURL = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareLink.value)}`;
|
|
facebookLink.setAttribute('href', facebookShareURL);
|
|
|
|
const linkedinShareURL = `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(shareLink.value)}`;
|
|
linkedinLink.setAttribute('href', linkedinShareURL);
|
|
|
|
copyButton.addEventListener('click', function() {
|
|
shareLink.select();
|
|
document.execCommand('copy');
|
|
this.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check"><path d="M20 6 9 17l-5-5"/></svg>';
|
|
setTimeout(() => {
|
|
this.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>';
|
|
}, 2000);
|
|
});
|
|
|
|
shareModal.classList.remove('hidden');
|
|
setTimeout(() => {
|
|
shareModal.classList.remove('opacity-0');
|
|
shareModalContent.classList.remove('-translate-y-full', 'scale-95', 'opacity-0');
|
|
}, 50);
|
|
}
|
|
|
|
script hideShareModal() {
|
|
const shareModal = document.getElementById('shareModal');
|
|
const shareModalContent = shareModal.querySelector('div');
|
|
|
|
shareModal.classList.add('opacity-0');
|
|
shareModalContent.classList.add('-translate-y-full', 'scale-95', 'opacity-0');
|
|
setTimeout(() => {
|
|
shareModal.classList.add('hidden');
|
|
}, 300);
|
|
}
|
|
|
|
templ Main(title string, files []types.FileData, user types.User, allowance *types.Allowance) {
|
|
@component(title, files, user, allowance)
|
|
}
|