ui changes
This commit is contained in:
parent
ae0af1f996
commit
f7c0a677b9
@ -187,6 +187,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
10
frontend/public/img/icons/download.svg
Normal file
10
frontend/public/img/icons/download.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2349_1587)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.9997 6.83337C14.2758 6.83337 14.4997 7.05723 14.4997 7.33337V14.6484L15.62 13.3413C15.7998 13.1316 16.1154 13.1074 16.3251 13.2871C16.5347 13.4668 16.559 13.7824 16.3793 13.9921L14.3793 16.3254C14.2843 16.4363 14.1456 16.5 13.9997 16.5C13.8537 16.5 13.715 16.4363 13.62 16.3254L11.62 13.9921C11.4403 13.7824 11.4646 13.4668 11.6743 13.2871C11.8839 13.1074 12.1996 13.1316 12.3793 13.3413L13.4997 14.6484V7.33337C13.4997 7.05723 13.7235 6.83337 13.9997 6.83337ZM10.6636 11.5014C10.9397 11.4998 11.1648 11.7224 11.1663 11.9986C11.1679 12.2747 10.9453 12.4998 10.6691 12.5013C9.94013 12.5054 9.4234 12.5243 9.03124 12.5964C8.65337 12.6658 8.43465 12.7772 8.27235 12.9395C8.08784 13.124 7.96754 13.3831 7.90177 13.8723C7.83407 14.3758 7.83301 15.0432 7.83301 16.0002V16.6669C7.83301 17.6238 7.83407 18.2912 7.90177 18.7948C7.96754 19.284 8.08784 19.543 8.27235 19.7275C8.45686 19.912 8.7159 20.0323 9.20509 20.0981C9.70866 20.1658 10.3761 20.1669 11.333 20.1669H16.6663C17.6233 20.1669 18.2907 20.1658 18.7943 20.0981C19.2834 20.0323 19.5425 19.912 19.727 19.7275C19.9115 19.543 20.0318 19.284 20.0976 18.7948C20.1653 18.2912 20.1663 17.6238 20.1663 16.6669V16.0002C20.1663 15.0432 20.1653 14.3758 20.0976 13.8723C20.0318 13.3831 19.9115 13.124 19.727 12.9395C19.5647 12.7772 19.346 12.6658 18.9681 12.5964C18.5759 12.5243 18.0592 12.5054 17.3302 12.5013C17.0541 12.4998 16.8315 12.2747 16.833 11.9986C16.8346 11.7224 17.0597 11.4998 17.3358 11.5014C18.0568 11.5054 18.6577 11.5226 19.1488 11.6128C19.6541 11.7056 20.0842 11.8825 20.4341 12.2324C20.8354 12.6337 21.008 13.1389 21.0887 13.739C21.1664 14.317 21.1664 15.0519 21.1663 15.9636V16.7034C21.1664 17.6152 21.1664 18.35 21.0887 18.928C21.008 19.5281 20.8354 20.0333 20.4341 20.4346C20.0328 20.8359 19.5276 21.0085 18.9275 21.0892C18.3495 21.1669 17.6146 21.1669 16.7029 21.1669H11.2964C10.3847 21.1669 9.64982 21.1669 9.07184 21.0892C8.47177 21.0085 7.96652 20.8359 7.56524 20.4346C7.16396 20.0333 6.99137 19.5281 6.91069 18.928C6.83298 18.35 6.83299 17.6152 6.83301 16.7034V15.9636C6.83299 15.0519 6.83298 14.317 6.91069 13.739C6.99137 13.1389 7.16396 12.6337 7.56524 12.2324C7.91519 11.8825 8.34524 11.7056 8.85058 11.6128C9.34162 11.5226 9.94254 11.5054 10.6636 11.5014Z" fill="#EBEBF5" fill-opacity="0.6"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2349_1587">
|
||||
<rect x="6" y="6" width="16" height="16" rx="3.33333" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
16
frontend/public/img/icons/folder.svg
Normal file
16
frontend/public/img/icons/folder.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 55 KiB |
11
frontend/public/img/icons/home.svg
Normal file
11
frontend/public/img/icons/home.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2510_1572)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.07168 2.09429C6.67365 2.28785 6.19751 2.58263 5.52033 3.00291L4.187 3.83041C3.54645 4.22796 3.09672 4.50773 2.76126 4.76463C2.43487 5.01459 2.24709 5.22087 2.11871 5.4554C1.98988 5.69076 1.91467 5.96593 1.87506 6.38752C1.83449 6.81922 1.83398 7.36404 1.83398 8.13611V9.15013C1.83398 10.4641 1.83498 11.4009 1.92744 12.1123C2.01826 12.811 2.18933 13.2164 2.47451 13.5114C2.75741 13.804 3.14256 13.9778 3.81013 14.0706C4.49387 14.1657 5.39563 14.1668 6.66732 14.1668H9.33398C10.6057 14.1668 11.5074 14.1657 12.1912 14.0706C12.8587 13.9778 13.2439 13.804 13.5268 13.5114C13.812 13.2164 13.983 12.811 14.0739 12.1123C14.1663 11.4009 14.1673 10.4641 14.1673 9.15013V8.13611C14.1673 7.36404 14.1668 6.81922 14.1262 6.38752C14.0866 5.96593 14.0114 5.69076 13.8826 5.4554C13.7542 5.22087 13.5664 5.01459 13.24 4.76463C12.9046 4.50773 12.4549 4.22796 11.8143 3.83041L10.481 3.00291C9.80379 2.58263 9.32765 2.28785 8.92962 2.09429C8.54183 1.90571 8.2672 1.8335 8.00065 1.8335C7.73411 1.8335 7.45947 1.90571 7.07168 2.09429ZM6.63435 1.19499C7.09967 0.968709 7.52857 0.833496 8.00065 0.833496C8.47273 0.833496 8.90163 0.968709 9.36695 1.19499C9.81675 1.41373 10.3364 1.73622 10.9854 2.13904L12.3631 2.99411C12.9773 3.37524 13.469 3.68043 13.8481 3.9707C14.2406 4.27129 14.542 4.57742 14.7598 4.97525C14.9771 5.37224 15.0749 5.79466 15.1219 6.29397C15.1673 6.77785 15.1673 7.36957 15.1673 8.11164V9.18671C15.1673 10.456 15.1673 11.4579 15.0655 12.2412C14.9611 13.0448 14.7416 13.6935 14.2457 14.2065C13.7476 14.7217 13.1137 14.9519 12.3289 15.0611C11.5683 15.1669 10.5969 15.1668 9.37271 15.1668H6.62859C5.40438 15.1668 4.43298 15.1669 3.67239 15.0611C2.88762 14.9519 2.25371 14.7217 1.75556 14.2065C1.25969 13.6935 1.04023 13.0448 0.935787 12.2412C0.833968 11.4579 0.833975 10.456 0.833985 9.18673L0.833985 8.11165C0.833979 7.36957 0.833975 6.77786 0.879444 6.29397C0.926362 5.79466 1.02422 5.37224 1.24152 4.97525C1.45928 4.57742 1.76075 4.27129 2.15325 3.9707C2.53228 3.68043 3.02404 3.37524 3.63817 2.99409L5.01589 2.13904C5.66493 1.73622 6.18455 1.41373 6.63435 1.19499Z" fill="#737373"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.7805 9.19543C7.27655 9.2986 6.80063 9.66808 6.50271 10.056C6.38468 10.2097 6.3291 10.4386 6.3291 10.7514V14.297H5.3291V10.7514C5.3291 10.3521 5.39398 9.85795 5.7096 9.44695C6.10465 8.93253 6.77147 8.38126 7.57994 8.21575C8.43927 8.03984 9.36288 8.32 10.153 9.30267C10.5432 9.78805 10.6683 10.391 10.6683 10.9308V14.297H9.66829V10.9308C9.66829 10.529 9.57341 10.1778 9.37363 9.92927C8.79205 9.20594 8.23358 9.10268 7.7805 9.19543Z" fill="#737373"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2510_1572">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
33
frontend/public/img/icons/mp4.svg
Normal file
33
frontend/public/img/icons/mp4.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 4.0 MiB |
9
frontend/public/img/icons/pdf-icon.svg
Normal file
9
frontend/public/img/icons/pdf-icon.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 150 KiB |
@ -16,8 +16,8 @@
|
||||
[{[ if .Name -]}][{[ .Name ]}][{[ else ]}]File Browser[{[ end ]}]
|
||||
</title>
|
||||
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
@ -126,8 +126,8 @@
|
||||
}
|
||||
|
||||
#loading .spinner > div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
@ -181,9 +181,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
|
||||
[{[ if .CSS -]}]
|
||||
[{[ if .Theme -]}]
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="[{[ .StaticURL ]}]/themes/[{[ .Theme ]}].css"
|
||||
/>
|
||||
[{[ end ]}] [{[ if .CSS -]}]
|
||||
<link rel="stylesheet" href="[{[ .StaticURL ]}]/custom.css" />
|
||||
[{[ end ]}]
|
||||
</body>
|
||||
|
||||
556
frontend/public/themes/dark.css
Normal file
556
frontend/public/themes/dark.css
Normal file
@ -0,0 +1,556 @@
|
||||
:root {
|
||||
--background: #141D24;
|
||||
--surfacePrimary: #20292F;
|
||||
--surfaceSecondary: #3A4147;
|
||||
--divider: rgba(255, 255, 255, 0.12);
|
||||
--icon: #ffffff;
|
||||
/* --textPrimary: rgba(255, 255, 255, 0.87); */
|
||||
--textPrimary: #DFDEDF !important;
|
||||
--textSecondary: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
/* ::-webkit-scrollbar {
|
||||
display: none!important;
|
||||
} */
|
||||
#listing.mosaic,
|
||||
.breadcrumbs {
|
||||
background-color: #38393A !important;
|
||||
}
|
||||
|
||||
#listing.list {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
#loading {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
#loading .spinner div,
|
||||
main .spinner div {
|
||||
background: var(--icon);
|
||||
}
|
||||
|
||||
#login {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
header {
|
||||
background: #38393A !important;
|
||||
}
|
||||
|
||||
#search #input {
|
||||
background: var(--surfaceSecondary);
|
||||
border-color: var(--surfacePrimary);
|
||||
}
|
||||
|
||||
#search #input input::placeholder {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
|
||||
#search.active #input {
|
||||
background: rgb(71 71 71) !important;
|
||||
}
|
||||
|
||||
#search.active input {
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
#search #result {
|
||||
background: var(--background);
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
#search .boxes {
|
||||
/* background: var(--surfaceSecondary); */
|
||||
}
|
||||
|
||||
#search #result .boxes {
|
||||
background: #38393A !important;
|
||||
border: 0.5px solid #4C4C4C !important;
|
||||
box-shadow: 0px 36px 100px rgba(0, 0, 0, 0.4), 0px 0px 3px rgba(0, 0, 0, 0.55) !important;
|
||||
border-radius: 12px !important;
|
||||
}
|
||||
|
||||
#search .boxes>div>div {
|
||||
background: #282828 !important;
|
||||
}
|
||||
|
||||
#search .boxes h3,
|
||||
#search .boxes>div>div>p {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
.action {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
.action:hover {
|
||||
background-color: rgba(255, 255, 255, .1) !important;
|
||||
}
|
||||
|
||||
.action i {
|
||||
/* color: var(--icon) !important; */
|
||||
}
|
||||
|
||||
.action .counter {
|
||||
border-color: var(--surfacePrimary);
|
||||
}
|
||||
|
||||
nav>div {
|
||||
border-color: var(--divider);
|
||||
}
|
||||
|
||||
.breadcrumbs {
|
||||
border-color: var(--divider);
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
.breadcrumbs span {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
.breadcrumbs a:hover {
|
||||
background: rgba(120, 120, 128, 0.2);
|
||||
}
|
||||
|
||||
#listing .item {
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textPrimary);
|
||||
border-color: var(--divider) !important;
|
||||
}
|
||||
|
||||
#listing .item i {
|
||||
color: var(--icon);
|
||||
}
|
||||
|
||||
#listing .item .modified {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
|
||||
#listing h2,
|
||||
#listing.list .header span {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
#listing.list .header span {
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
#listing.list .header i {
|
||||
color: var(--icon);
|
||||
}
|
||||
|
||||
#listing.list .item.header {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
.message {
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #38393A !important;
|
||||
color: var(--textPrimary) !important;
|
||||
box-shadow: 0px 36px 100px rgba(0, 0, 0, 0.4), 0px 0px 3px rgba(0, 0, 0, 0.55) !important;
|
||||
border-radius: 12px !important;
|
||||
}
|
||||
|
||||
.card-title,
|
||||
.card-content {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
.button--flat:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
}
|
||||
|
||||
.dashboard #nav ul li {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
|
||||
.dashboard #nav ul li:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
}
|
||||
|
||||
.card h3,
|
||||
.dashboard #nav,
|
||||
.dashboard p label {
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
.card#share input,
|
||||
.card#share select,
|
||||
.input {
|
||||
background: var(--surfaceSecondary);
|
||||
color: var(--textPrimary);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.input:hover,
|
||||
.input:focus {
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.input--red {
|
||||
background: #73302D;
|
||||
}
|
||||
|
||||
.input--green {
|
||||
background: #147A41;
|
||||
}
|
||||
|
||||
.dashboard #nav .wrapper,
|
||||
.collapsible {
|
||||
border-color: var(--divider);
|
||||
}
|
||||
|
||||
.collapsible>label * {
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
table th {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
|
||||
.file-list li:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
}
|
||||
|
||||
.file-list li:before {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
|
||||
.file-list li[aria-selected=true]:before {
|
||||
color: var(--icon);
|
||||
}
|
||||
|
||||
.shell {
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
.shell__divider {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.shell__divider:hover {
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.shell__result {
|
||||
border-top: 1px solid var(--divider);
|
||||
}
|
||||
|
||||
#editor-container {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
#editor-container .bar {
|
||||
background: var(--surfacePrimary);
|
||||
}
|
||||
|
||||
@media (max-width: 736px) {
|
||||
#file-selection {
|
||||
background: var(--surfaceSecondary) !important;
|
||||
}
|
||||
|
||||
#file-selection span {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
|
||||
nav {
|
||||
background: var(--surfaceSecondary) !important;
|
||||
}
|
||||
|
||||
#dropdown {
|
||||
background: var(--surfaceSecondary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.share__box {
|
||||
background: var(--surfacePrimary) !important;
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
|
||||
.share__box__element {
|
||||
border-top-color: var(--divider);
|
||||
}
|
||||
|
||||
/*----------Custom---------------------------*/
|
||||
|
||||
body,
|
||||
#login {
|
||||
background-color: #303030 !important;
|
||||
}
|
||||
|
||||
/* header {
|
||||
background-color: #1b1b1b !important;
|
||||
} */
|
||||
|
||||
#search #input {
|
||||
background-color: #424242 !important;
|
||||
color: rgba(255, 255, 255, 0.7) !important;
|
||||
}
|
||||
|
||||
#listing.list .item,
|
||||
#listing.mosaic .item {
|
||||
background: rgba(50, 50, 50, 1) !important;
|
||||
color: rgba(255, 255, 255, 0.7) !important;
|
||||
}
|
||||
|
||||
#listing.list .item:hover,
|
||||
#listing.mosaic .item:hover,
|
||||
#listing .item[aria-selected=true] {
|
||||
background: linear-gradient(0deg, rgba(30, 30, 30, 0.6), rgba(30, 30, 30, 0.6)), rgba(84, 84, 88, 0.3) !important;
|
||||
}
|
||||
|
||||
/* #listing.mosaic,
|
||||
.breadcrumbs {
|
||||
background-color: #303030 !important;
|
||||
} */
|
||||
|
||||
|
||||
/*action*/
|
||||
.action span {
|
||||
color: #DFDEDF !important;
|
||||
}
|
||||
|
||||
|
||||
/* listing */
|
||||
#listing .item .size,
|
||||
#listing .item .modified {
|
||||
color: rgba(223, 222, 223, 0.8) !important;
|
||||
}
|
||||
|
||||
#listing .item .name {
|
||||
|
||||
color: #DFDEDF !important;
|
||||
}
|
||||
|
||||
select,
|
||||
textarea,
|
||||
input,
|
||||
.dashboard textarea,
|
||||
.dashboard #locale,
|
||||
.dashboard input[type=password],
|
||||
.dashboard input[type=text] {
|
||||
background: #212121;
|
||||
color: rgba(255, 255, 255, 0.9) !important;
|
||||
border-color: #303030;
|
||||
}
|
||||
|
||||
.action,
|
||||
#breadcrumbs,
|
||||
#breadcrumbs span,
|
||||
.dashboard #nav,
|
||||
#login h1 {
|
||||
color: rgba(255, 255, 255, 0.7) !important;
|
||||
}
|
||||
|
||||
#search #result {
|
||||
background-color: #212121 !important;
|
||||
color: rgba(255, 255, 255, 0.7) !important;
|
||||
}
|
||||
|
||||
.action:hover {
|
||||
/* background: rgba(120, 120, 128, 0.2) !important; */
|
||||
/* border: 1px solid transparent !important; */
|
||||
box-shadow: unset !important;
|
||||
border-radius: 45px !important;
|
||||
}
|
||||
|
||||
nav>div:first-of-type:before {
|
||||
/* color: rgba(255, 255, 255, 0.45)!important; */
|
||||
}
|
||||
|
||||
nav.active,
|
||||
#dropdown.active {
|
||||
background-color: rgb(51, 51, 51) !important;
|
||||
}
|
||||
|
||||
button[aria-label="New file"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/new-file-dark.svg') !important;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 4px center;
|
||||
|
||||
}
|
||||
|
||||
button[aria-label="New folder"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/new-folder-dark.svg') !important;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 4px center;
|
||||
}
|
||||
|
||||
button[aria-label="Download"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/download-dark.svg') !important;
|
||||
|
||||
}
|
||||
|
||||
button[aria-label="Close"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/close-dark.svg') !important;
|
||||
|
||||
}
|
||||
|
||||
#dropdown button[aria-label="Rename"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/edit-dark.svg') !important;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
}
|
||||
|
||||
/* button[aria-label="Delete"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/delete-dark.svg') !important;
|
||||
|
||||
} */
|
||||
|
||||
button[aria-label="Switch view"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/switch-view-dark.svg') !important;
|
||||
}
|
||||
|
||||
button[aria-label="Upload"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/upload-dark.svg') !important;
|
||||
}
|
||||
|
||||
button[aria-label="My files"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/files-dark.svg') !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: left center !important;
|
||||
}
|
||||
|
||||
a[aria-label="Home"] {
|
||||
background-image: url('https://evoque-localportal.s3.ap-south-1.amazonaws.com/file-browser/home-dark.svg') !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: 16px center !important;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background-size: auto;
|
||||
}
|
||||
|
||||
|
||||
.card .card-action.full .action .title,
|
||||
.card.floating .card-title>h2 {
|
||||
color: rgba(255, 255, 255, 1) !important;
|
||||
}
|
||||
|
||||
.card.floating .card-content>p {
|
||||
color: rgba(255, 255, 255, 0.8) !important;
|
||||
}
|
||||
|
||||
.card#download,
|
||||
.card.floating {
|
||||
background: #38393A !important;
|
||||
border: 0.5px solid #4C4C4C !important;
|
||||
box-shadow: 0px 36px 100px rgba(0, 0, 0, 0.4), 0px 0px 3px rgba(0, 0, 0, 0.55) !important;
|
||||
}
|
||||
|
||||
.card .card-action.full .action {
|
||||
background: rgba(40, 40, 40, 1) !important;
|
||||
}
|
||||
|
||||
.card .card-action.full .action:hover,
|
||||
#download .card-content .button:hover {
|
||||
background: linear-gradient(0deg, rgba(30, 30, 30, 0.6), rgba(30, 30, 30, 0.6)), rgba(84, 84, 88, 0.3) !important;
|
||||
}
|
||||
|
||||
#download .card-content .button {
|
||||
background: rgba(50, 50, 50, 1) !important;
|
||||
color: rgba(223, 222, 223, 1) !important;
|
||||
}
|
||||
|
||||
#previewer {
|
||||
background-color: rgba(0, 0, 0, 0.9) !important;
|
||||
}
|
||||
|
||||
#previewer header>title {
|
||||
color: rgb(255, 255, 255) !important;
|
||||
}
|
||||
|
||||
#search button[aria-label="Close"] {
|
||||
background-image: unset !important;
|
||||
}
|
||||
|
||||
#search.active #input>.action i {
|
||||
background-color: rgba(255, 255, 255, .5) !important;
|
||||
}
|
||||
|
||||
#previewer .preview .info {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.button--flat.button--grey {
|
||||
color: #ffff !important;
|
||||
}
|
||||
|
||||
button[aria-label="Upload"]>i,
|
||||
button[aria-label="Delete"]>i,
|
||||
button[aria-label="Move file"]>i,
|
||||
button[aria-label="Copy file"]>i,
|
||||
button[aria-label="Share"]>i,
|
||||
button[aria-label="Rename"]>i
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
button[aria-label="Download"]>i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button[aria-label="Switch view"]>i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.card .card-action.full .action i {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.card .card-action.full .action .title {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
a[aria-label="Home"]>i.material-icons {
|
||||
font-size: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
button[aria-label="My files"]>i {
|
||||
display: none !important;
|
||||
}
|
||||
button[aria-label="New file"]>i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button[aria-label="New folder"]>i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#search .boxes i {
|
||||
color: transparent !important;
|
||||
font-size: 0 !important;
|
||||
}
|
||||
#dropdown.active button[aria-label="Switch view"] {
|
||||
background-image: unset !important;
|
||||
}
|
||||
|
||||
#dropdown.active button[aria-label="Switch view"] {
|
||||
background-image: unset !important;
|
||||
}
|
||||
|
||||
#dropdown.active button[aria-label="Upload"] {
|
||||
background-image: unset !important;
|
||||
}
|
||||
|
||||
#dropdown.active button[aria-label="Download"] {
|
||||
background-image: unset !important
|
||||
}
|
||||
button[aria-label="More"].action:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
@ -1,111 +1,38 @@
|
||||
<template>
|
||||
<div class="card floating">
|
||||
<div class="card-title">
|
||||
<h2>{{ t("prompts.upload") }}</h2>
|
||||
<h2>{{ $t("prompts.upload") }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-content">
|
||||
<p>{{ t("prompts.uploadMessage") }}</p>
|
||||
<p>{{ $t("prompts.uploadMessage") }}</p>
|
||||
</div>
|
||||
|
||||
<div class="card-action full">
|
||||
<div
|
||||
@click="uploadFile"
|
||||
@keypress.enter="uploadFile"
|
||||
class="action"
|
||||
id="focus-prompt"
|
||||
tabindex="1"
|
||||
>
|
||||
<i class="material-icons">insert_drive_file</i>
|
||||
<div class="title">{{ t("buttons.file") }}</div>
|
||||
<div @click="uploadFile" class="action">
|
||||
<i class="material-icons"></i>
|
||||
<div class="title">{{ $t("buttons.file") }}</div>
|
||||
</div>
|
||||
<div
|
||||
@click="uploadFolder"
|
||||
@keypress.enter="uploadFolder"
|
||||
class="action"
|
||||
tabindex="2"
|
||||
>
|
||||
<i class="material-icons">folder</i>
|
||||
<div class="title">{{ t("buttons.folder") }}</div>
|
||||
<div @click="uploadFolder" class="action">
|
||||
<i class="material-icons"></i>
|
||||
<div class="title">{{ $t("buttons.folder") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useFileStore } from "@/stores/file";
|
||||
import { useLayoutStore } from "@/stores/layout";
|
||||
|
||||
import * as upload from "@/utils/upload";
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const fileStore = useFileStore();
|
||||
const layoutStore = useLayoutStore();
|
||||
|
||||
// TODO: this is a copy of the same function in FileListing.vue
|
||||
const uploadInput = (event: Event) => {
|
||||
layoutStore.closeHovers();
|
||||
|
||||
let files = (event.currentTarget as HTMLInputElement)?.files;
|
||||
if (files === null) return;
|
||||
|
||||
let folder_upload = !!files[0].webkitRelativePath;
|
||||
|
||||
const uploadFiles: UploadList = [];
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const fullPath = folder_upload ? file.webkitRelativePath : undefined;
|
||||
uploadFiles.push({
|
||||
file,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
isDir: false,
|
||||
fullPath,
|
||||
});
|
||||
}
|
||||
|
||||
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
||||
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
||||
|
||||
if (conflict) {
|
||||
layoutStore.showHover({
|
||||
prompt: "replace",
|
||||
action: (event: Event) => {
|
||||
event.preventDefault();
|
||||
layoutStore.closeHovers();
|
||||
upload.handleFiles(uploadFiles, path, false);
|
||||
},
|
||||
confirm: (event: Event) => {
|
||||
event.preventDefault();
|
||||
layoutStore.closeHovers();
|
||||
upload.handleFiles(uploadFiles, path, true);
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
upload.handleFiles(uploadFiles, path);
|
||||
};
|
||||
|
||||
const openUpload = (isFolder: boolean) => {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.multiple = true;
|
||||
input.webkitdirectory = isFolder;
|
||||
// TODO: call the function in FileListing.vue instead
|
||||
input.onchange = uploadInput;
|
||||
input.click();
|
||||
};
|
||||
|
||||
const uploadFile = () => {
|
||||
openUpload(false);
|
||||
};
|
||||
const uploadFolder = () => {
|
||||
openUpload(true);
|
||||
<script>
|
||||
export default {
|
||||
name: "upload",
|
||||
methods: {
|
||||
uploadFile: function () {
|
||||
document.getElementById("upload-input").value = "";
|
||||
document.getElementById("upload-input").click();
|
||||
},
|
||||
uploadFolder: function () {
|
||||
document.getElementById("upload-folder-input").value = "";
|
||||
document.getElementById("upload-folder-input").click();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
.button {
|
||||
outline: 0;
|
||||
border: 0;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.1em;
|
||||
padding: .5em 1em;
|
||||
border-radius: .1em;
|
||||
cursor: pointer;
|
||||
background: var(--blue);
|
||||
color: white;
|
||||
border: 1px solid var(--divider);
|
||||
box-shadow: 0 0 5px var(--divider);
|
||||
transition: 0.1s ease all;
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.05);
|
||||
transition: .1s ease all;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
@ -38,7 +38,7 @@
|
||||
}
|
||||
|
||||
.button--flat:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
background: var(--moon-grey);
|
||||
}
|
||||
|
||||
.button--flat.button--red {
|
||||
@ -50,6 +50,6 @@
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
opacity: 0.5;
|
||||
opacity: .5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
.input {
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textSecondary);
|
||||
border: 1px solid var(--borderPrimary);
|
||||
border-radius: 0.1em;
|
||||
padding: 0.5em 1em;
|
||||
transition: 0.2s ease all;
|
||||
border-radius: .1em;
|
||||
padding: .5em 1em;
|
||||
background: white;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
transition: .2s ease all;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.input:hover,
|
||||
.input:focus {
|
||||
border-color: var(--borderSecondary);
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.input--block {
|
||||
margin-bottom: 0.5em;
|
||||
margin-bottom: .5em;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input--textarea {
|
||||
line-height: 1.15;
|
||||
font-family: monospace;
|
||||
font-family: "Inter", sans-serif;
|
||||
min-height: 10em;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.input--red {
|
||||
background: var(--input-red) !important;
|
||||
background: #fcd0cd;
|
||||
}
|
||||
|
||||
.input--green {
|
||||
background: var(--input-green) !important;
|
||||
background: #c9f2da;
|
||||
}
|
||||
|
||||
@ -12,11 +12,8 @@
|
||||
}
|
||||
|
||||
.share__box {
|
||||
box-shadow:
|
||||
rgba(0, 0, 0, 0.06) 0px 1px 3px,
|
||||
rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textPrimary);
|
||||
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
background: #fff;
|
||||
border-radius: 0.2em;
|
||||
margin: 5px;
|
||||
overflow: hidden;
|
||||
@ -42,7 +39,7 @@
|
||||
|
||||
.share__box__element {
|
||||
padding: 1em;
|
||||
border-top: 1px solid var(--borderPrimary);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
@ -65,7 +62,7 @@
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid var(--borderPrimary);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.share__box__items #listing.list .item .name {
|
||||
@ -79,7 +76,7 @@
|
||||
.share__wrong__password {
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
padding: 0.5em;
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
animation: 0.2s opac forwards;
|
||||
}
|
||||
animation: .2s opac forwards;
|
||||
}
|
||||
@ -3,8 +3,17 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
max-height: calc(100% - 4em);
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textPrimary);
|
||||
background: white;
|
||||
color: #212121;
|
||||
z-index: 9997;
|
||||
width: 100%;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
transition: .2s ease transform;
|
||||
}
|
||||
|
||||
.shell__divider {
|
||||
position: relative;
|
||||
height: 8px;
|
||||
z-index: 9999;
|
||||
background: rgba(127, 127, 127, 0.1);
|
||||
transition: 0.2s ease background;
|
||||
@ -23,8 +32,6 @@
|
||||
overflow: auto;
|
||||
font-size: 1rem;
|
||||
cursor: text;
|
||||
box-shadow: 0 0 5px var(--borderPrimary);
|
||||
transition: 0.2s ease transform;
|
||||
}
|
||||
|
||||
.shell__overlay {
|
||||
@ -45,7 +52,7 @@ body.rtl .shell-content {
|
||||
display: flex;
|
||||
padding: 0.5em;
|
||||
align-items: flex-start;
|
||||
border-top: 1px solid var(--divider);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.shell--hidden {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
:root {
|
||||
--blue: #2196f3;
|
||||
--dark-blue: #1e88e5;
|
||||
--red: #f44336;
|
||||
--dark-red: #d32f2f;
|
||||
--dark-blue: #1E88E5;
|
||||
--red: #F44336;
|
||||
--dark-red: #D32F2F;
|
||||
--moon-grey: #f2f2f2;
|
||||
|
||||
--icon-red: #da4453;
|
||||
@ -11,44 +11,4 @@
|
||||
--icon-green: #2ecc71;
|
||||
--icon-blue: #1d99f3;
|
||||
--icon-violet: #9b59b6;
|
||||
|
||||
--input-red: rgb(252, 208, 205);
|
||||
--input-green: rgb(201, 242, 218);
|
||||
|
||||
--item-selected: white;
|
||||
|
||||
--action: rgb(84, 110, 122);
|
||||
|
||||
--background: rgb(250, 250, 250);
|
||||
--surfacePrimary: rgb(255, 255, 255);
|
||||
--surfaceSecondary: rgb(230, 230, 230);
|
||||
--divider: rgba(0, 0, 0, 0.05);
|
||||
--iconPrimary: var(--icon-blue);
|
||||
--iconSecondary: rgb(255, 255, 255);
|
||||
--iconTertiary: rgb(204, 204, 204);
|
||||
--textPrimary: rgb(111, 111, 111);
|
||||
--textSecondary: rgb(51, 51, 51);
|
||||
--hover: rgba(0, 0, 0, 0.1);
|
||||
--borderPrimary: rgba(0, 0, 0, 0.1);
|
||||
--borderSecondary: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--input-red: rgb(115, 48, 45);
|
||||
--input-green: rgb(20, 122, 65);
|
||||
|
||||
--action: rgb(255, 255, 255);
|
||||
|
||||
--background: rgb(20, 29, 36);
|
||||
--surfacePrimary: rgb(32, 41, 47);
|
||||
--surfaceSecondary: rgb(58, 65, 71);
|
||||
--textPrimary: rgba(255, 255, 255, 0.6);
|
||||
--textSecondary: rgba(255, 255, 255, 0.87);
|
||||
--divider: rgba(255, 255, 255, 0.12);
|
||||
--iconPrimary: rgb(255, 255, 255);
|
||||
--iconSecondary: rgb(255, 255, 255);
|
||||
--iconTertiary: rgb(255, 255, 255);
|
||||
--hover: rgba(255, 255, 255, 0.1);
|
||||
--borderPrimary: rgba(255, 255, 255, 0.05);
|
||||
--borderSecondary: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
@ -1,180 +1,154 @@
|
||||
body {
|
||||
font-family: "Roboto", sans-serif;
|
||||
padding-top: 4em;
|
||||
background: var(--background);
|
||||
color: var(--textSecondary);
|
||||
font-family: "Roboto", sans-serif;
|
||||
padding-top: 4em;
|
||||
background-color: #fafafa;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
body.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*,
|
||||
*:hover,
|
||||
*:active,
|
||||
*:focus {
|
||||
outline: 0;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
audio,
|
||||
video {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile-only {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 95%;
|
||||
max-width: 960px;
|
||||
margin: 1em auto 0;
|
||||
width: 95%;
|
||||
max-width: 960px;
|
||||
margin: 1em auto 0;
|
||||
}
|
||||
|
||||
i.spin {
|
||||
animation: 1s spin linear infinite;
|
||||
animation: 1s spin linear infinite;
|
||||
}
|
||||
|
||||
#app {
|
||||
transition: 0.2s ease padding;
|
||||
transition: 0.2s ease padding;
|
||||
}
|
||||
|
||||
#app.multiple {
|
||||
padding-bottom: 4em;
|
||||
padding-bottom: 4em;
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 16em;
|
||||
position: fixed;
|
||||
top: 4em;
|
||||
left: 0;
|
||||
width: 16em;
|
||||
position: fixed;
|
||||
top: 4em;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
html[dir="rtl"] nav {
|
||||
left: initial;
|
||||
right: 0;
|
||||
body.rtl nav {
|
||||
left: unset;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
nav .action {
|
||||
width: 100%;
|
||||
display: block;
|
||||
border-radius: 0;
|
||||
font-size: 1.1em;
|
||||
padding: 0.5em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
display: block;
|
||||
border-radius: 0;
|
||||
font-size: 1.1em;
|
||||
padding: 0.5em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
html[dir="rtl"] nav .action {
|
||||
text-align: right;
|
||||
body.rtl .action {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
nav > div {
|
||||
border-top: 1px solid var(--divider);
|
||||
nav>div {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
nav .action > * {
|
||||
vertical-align: middle;
|
||||
nav .action>* {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
main {
|
||||
min-height: 1em;
|
||||
margin: 0 1em 1em auto;
|
||||
width: calc(100% - 19em);
|
||||
min-height: 1em;
|
||||
margin: 0 1em 1em auto;
|
||||
width: calc(100% - 19em);
|
||||
}
|
||||
|
||||
.breadcrumbs {
|
||||
height: 3em;
|
||||
background: var(--background);
|
||||
border-bottom: 1px solid var(--divider);
|
||||
height: 3em;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.breadcrumbs span,
|
||||
.breadcrumbs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--textPrimary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #6f6f6f;
|
||||
}
|
||||
|
||||
.breadcrumbs a {
|
||||
color: inherit;
|
||||
transition: 0.1s ease-in;
|
||||
border-radius: 0.125em;
|
||||
color: inherit;
|
||||
transition: 0.1s ease-in;
|
||||
border-radius: 0.125em;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .breadcrumbs a {
|
||||
transform: translateX(-16em);
|
||||
body.rtl .breadcrumbs a {
|
||||
transform: translateX(-16em);
|
||||
}
|
||||
|
||||
.breadcrumbs a:hover {
|
||||
background-color: var(--divider);
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.breadcrumbs span a {
|
||||
padding: 0.2em;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
.files {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
z-index: 9999999999;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
z-index: 9999999999;
|
||||
}
|
||||
|
||||
.progress div {
|
||||
height: 100%;
|
||||
background-color: #40c4ff;
|
||||
width: 0;
|
||||
transition: 0.2s ease width;
|
||||
height: 100%;
|
||||
background-color: #40c4ff;
|
||||
width: 0;
|
||||
transition: 0.2s ease width;
|
||||
}
|
||||
|
||||
.break-word {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.vue-number-input > input {
|
||||
background: var(--surfacePrimary) !important;
|
||||
border-color: var(--surfaceSecondary) !important;
|
||||
color: var(--textSecondary) !important;
|
||||
}
|
||||
|
||||
.vue-number-input--small > input {
|
||||
height: 1rem !important;
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
|
||||
.vue-number-input :hover,
|
||||
.vue-number-input :focus {
|
||||
border-color: var(--borderSecondary) !important;
|
||||
}
|
||||
|
||||
.vue-number-input__button {
|
||||
background: var(--surfacePrimary) !important;
|
||||
}
|
||||
|
||||
.vue-number-input__button--minus,
|
||||
.vue-number-input__button--plus {
|
||||
border-color: var(--surfaceSecondary) !important;
|
||||
}
|
||||
|
||||
.vue-number-input__button::before,
|
||||
.vue-number-input__button::after {
|
||||
background: var(--textSecondary) !important;
|
||||
}
|
||||
word-break: break-all;
|
||||
}
|
||||
1098
frontend/src/css/custom.css
Normal file
1098
frontend/src/css/custom.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,17 +4,17 @@
|
||||
|
||||
.dashboard .row {
|
||||
display: flex;
|
||||
margin: 0 -0.5em;
|
||||
margin: 0 -.5em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .dashboard .row {
|
||||
body.rtl .dashboard .row {
|
||||
margin-right: 16em;
|
||||
}
|
||||
|
||||
.dashboard .row .column {
|
||||
display: flex;
|
||||
padding: 0 0.5em;
|
||||
padding: 0 .5em;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@ -22,33 +22,33 @@ html[dir="rtl"] .dashboard .row {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media(max-width: 1200px) {
|
||||
.dashboard .row .column {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
color: inherit
|
||||
}
|
||||
|
||||
.dashboard p label {
|
||||
margin-bottom: 0.2em;
|
||||
margin-bottom: .2em;
|
||||
display: block;
|
||||
font-size: 0.8em;
|
||||
font-size: .8em;
|
||||
font-weight: 500;
|
||||
color: var(--textPrimary);
|
||||
color: rgba(0, 0, 0, 0.57);
|
||||
}
|
||||
|
||||
li code,
|
||||
p code {
|
||||
background: var(--divider);
|
||||
padding: 0.1em;
|
||||
border-radius: 0.2em;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
padding: .1em;
|
||||
border-radius: .2em;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 0.8em;
|
||||
font-size: .8em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@ -61,21 +61,21 @@ p code {
|
||||
.dashboard #nav .wrapper {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
border-bottom: 2px solid var(--divider);
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
html[dir="rtl"] .dashboard #nav .wrapper {
|
||||
body.rtl #nav .wrapper {
|
||||
margin-right: 16em;
|
||||
}
|
||||
|
||||
.dashboard #nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
color: var(--action);
|
||||
color: rgb(84, 110, 122);
|
||||
font-weight: 500;
|
||||
padding: 0;
|
||||
margin: 0 0 -2px 0;
|
||||
font-size: 0.8em;
|
||||
font-size: .8em;
|
||||
text-align: center;
|
||||
justify-content: left;
|
||||
}
|
||||
@ -85,11 +85,12 @@ html[dir="rtl"] .dashboard #nav .wrapper {
|
||||
padding: 1.5em 2em;
|
||||
white-space: nowrap;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: 0.1s ease-in-out all;
|
||||
transition: .1s ease-in-out all;
|
||||
|
||||
}
|
||||
|
||||
.dashboard #nav ul li:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
background: var(--moon-grey);
|
||||
}
|
||||
|
||||
.dashboard #nav ul li.active {
|
||||
@ -119,7 +120,7 @@ table {
|
||||
}
|
||||
|
||||
table tr {
|
||||
border-bottom: 1px solid var(--iconTertiary);
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table tr:last-child {
|
||||
@ -128,44 +129,40 @@ table tr:last-child {
|
||||
|
||||
table th {
|
||||
font-weight: 500;
|
||||
color: var(--textSecondary);
|
||||
color: #757575;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding: 0.5em 0;
|
||||
padding: .5em 0;
|
||||
}
|
||||
|
||||
table td.small {
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
table tr > *:first-child {
|
||||
table tr>*:first-child {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
html[dir="rtl"] table tr > * {
|
||||
body.rtl table tr>* {
|
||||
padding-left: unset;
|
||||
padding-right: 1em;
|
||||
text-align: right;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
table tr > *:last-child {
|
||||
table tr>*:last-child {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
margin: 0 0 1rem 0;
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textSecondary);
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow:
|
||||
0 2px 2px 0 rgba(0, 0, 0, 0.14),
|
||||
0 1px 5px 0 rgba(0, 0, 0, 0.12),
|
||||
0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@ -174,18 +171,18 @@ table tr > *:last-child {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 99999;
|
||||
max-width: 25em;
|
||||
width: 90%;
|
||||
max-height: 95%;
|
||||
/* animation-duration: 0.3s;
|
||||
animation-fill-mode: forwards; */
|
||||
animation: .1s show forwards;
|
||||
}
|
||||
|
||||
.card > * > *:first-child {
|
||||
.card>*>*:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.card > * > *:last-child {
|
||||
.card>*>*:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@ -194,24 +191,24 @@ table tr > *:last-child {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.card .card-title > *:first-child {
|
||||
.card .card-title>*:first-child {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .card .card-title > *:first-child {
|
||||
body.rtl .card .card-title>*:first-child {
|
||||
margin-right: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.card > div {
|
||||
.card>div {
|
||||
padding: 1em 1em;
|
||||
}
|
||||
|
||||
.card > div:first-child {
|
||||
.card>div:first-child {
|
||||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
.card > div:last-child {
|
||||
.card>div:last-child {
|
||||
padding-bottom: 1.5em;
|
||||
}
|
||||
|
||||
@ -237,7 +234,7 @@ body.rtl .card .card-action {
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
color: var(--textPrimary);
|
||||
color: rgba(0, 0, 0, 0.53);
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
margin: 2em 0 1em;
|
||||
@ -256,14 +253,6 @@ body.rtl .card .card-action {
|
||||
max-width: 15em;
|
||||
}
|
||||
|
||||
.card#share input,
|
||||
.card#share select,
|
||||
.card#share input::-webkit-inner-spin-button,
|
||||
.card#share input::-webkit-outer-spin-button {
|
||||
background: var(--surfacePrimary);
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
|
||||
.card#share ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
@ -288,24 +277,24 @@ body.rtl .card .card-action {
|
||||
|
||||
.card#share ul li input,
|
||||
.card#share ul li select {
|
||||
padding: 0.2em;
|
||||
margin-right: 0.5em;
|
||||
border: 1px solid var(--borderPrimary);
|
||||
padding: .2em;
|
||||
margin-right: .5em;
|
||||
border: 1px solid #dadada;
|
||||
}
|
||||
|
||||
.card#share .action.copy-clipboard::after {
|
||||
content: "Copied!";
|
||||
content: 'Copied!';
|
||||
position: absolute;
|
||||
left: -25%;
|
||||
width: 150%;
|
||||
font-size: 0.6em;
|
||||
font-size: .6em;
|
||||
text-align: center;
|
||||
background: #44a6f5;
|
||||
color: #fff;
|
||||
padding: 0.5em 0.2em;
|
||||
border-radius: 0.4em;
|
||||
padding: .5em .2em;
|
||||
border-radius: .4em;
|
||||
top: -2em;
|
||||
transition: 0.1s ease opacity;
|
||||
transition: .1s ease opacity;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@ -335,9 +324,10 @@ body.rtl .card .card-action {
|
||||
z-index: 9999;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
animation: 0.1s show forwards;
|
||||
animation: .1s show forwards;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * *
|
||||
* PROMPT - MOVE *
|
||||
* * * * * * * * * * * * * * * */
|
||||
@ -354,33 +344,33 @@ body.rtl .card .card-action {
|
||||
.file-list li {
|
||||
width: 100%;
|
||||
user-select: none;
|
||||
border-radius: 0.2em;
|
||||
padding: 0.3em;
|
||||
border-radius: .2em;
|
||||
padding: .3em;
|
||||
}
|
||||
|
||||
.file-list li[aria-selected="true"] {
|
||||
.file-list li[aria-selected=true] {
|
||||
background: var(--blue) !important;
|
||||
color: var(--iconSecondary) !important;
|
||||
transition: 0.1s ease all;
|
||||
color: #fff !important;
|
||||
transition: .1s ease all;
|
||||
}
|
||||
|
||||
.file-list li:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
background-color: #e9eaeb;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-list li:before {
|
||||
content: "folder";
|
||||
color: var(--textPrimary);
|
||||
color: #6f6f6f;
|
||||
vertical-align: middle;
|
||||
line-height: 1.4;
|
||||
font-family: "Material Icons";
|
||||
font-family: 'Material Icons';
|
||||
font-size: 1.75em;
|
||||
margin-right: 0.25em;
|
||||
margin-right: .25em;
|
||||
}
|
||||
|
||||
.file-list li[aria-selected="true"]:before {
|
||||
color: var(--iconSecondary);
|
||||
.file-list li[aria-selected=true]:before {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.help {
|
||||
@ -409,11 +399,11 @@ body.rtl .card .card-action {
|
||||
}
|
||||
|
||||
.collapsible {
|
||||
border-top: 1px solid var(--borderPrimary);
|
||||
border-top: 1px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.collapsible:last-of-type {
|
||||
border-bottom: 1px solid var(--borderPrimary);
|
||||
border-bottom: 1px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.collapsible > input {
|
||||
@ -431,18 +421,18 @@ body.rtl .card .card-action {
|
||||
|
||||
.collapsible > label * {
|
||||
margin: 0;
|
||||
color: var(--textPrimary);
|
||||
color: rgba(0,0,0,0.57);
|
||||
}
|
||||
|
||||
.collapsible > label i {
|
||||
transition: 0.2s ease transform;
|
||||
transition: .2s ease transform;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.collapsible .collapse {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: 0.2s ease all;
|
||||
transition: .2s ease all;
|
||||
}
|
||||
|
||||
.collapsible > input:checked ~ .collapse {
|
||||
@ -452,7 +442,7 @@ body.rtl .card .card-action {
|
||||
}
|
||||
|
||||
.collapsible > input:checked ~ label i {
|
||||
transform: rotate(180deg);
|
||||
transform: rotate(180deg)
|
||||
}
|
||||
|
||||
.card .collapsible {
|
||||
@ -478,12 +468,12 @@ body.rtl .card .card-action {
|
||||
flex: 1;
|
||||
padding: 2em;
|
||||
border-radius: 0.2em;
|
||||
border: 1px solid var(--borderPrimary);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card .card-action.full .action {
|
||||
margin: 0 0.25em 0.5em;
|
||||
margin: 0 0.25em 0.50em;
|
||||
}
|
||||
|
||||
.card .card-action.full .action i {
|
||||
@ -499,7 +489,7 @@ body.rtl .card .card-action {
|
||||
}
|
||||
|
||||
/*** RTL - Fix disk usage information (in english) ***/
|
||||
html[dir="rtl"] .credits {
|
||||
body.rtl .credits {
|
||||
text-align: right;
|
||||
direction: ltr;
|
||||
}
|
||||
}
|
||||
@ -1,279 +1,273 @@
|
||||
header {
|
||||
z-index: 1000;
|
||||
background: var(--surfacePrimary);
|
||||
border-bottom: 1px solid var(--divider);
|
||||
box-shadow: 0 0 5px var(--borderPrimary);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4em;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
padding: 0.5em 0.5em 0.5em 1em;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4em;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
padding: 0.5em 0.5em 0.5em 1em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header > * {
|
||||
flex: 0 0 auto;
|
||||
header>* {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
header title {
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
padding: 0 1em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.2em;
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
padding: 0 1em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
header .overlay {
|
||||
width: 0;
|
||||
height: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
header a,
|
||||
header a:hover {
|
||||
color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
header > div:first-child > .action,
|
||||
header>div:first-child>.action,
|
||||
header img {
|
||||
margin-right: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
header img {
|
||||
height: 2.5em;
|
||||
height: 2.5em;
|
||||
}
|
||||
|
||||
header .action span {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
header > div div {
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
header>div div {
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header .search-button,
|
||||
header .menu-button {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#more {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#search {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 25em;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 25em;
|
||||
}
|
||||
|
||||
#search.active {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
z-index: 9999;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#search #input {
|
||||
background: var(--surfaceSecondary);
|
||||
border-color: var(--surfacePrimary);
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding: 0em 0.75em;
|
||||
border-radius: 0.3em;
|
||||
transition: 0.1s ease all;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#search #input input::placeholder {
|
||||
color: var(--textSecondary);
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding: 0em 0.75em;
|
||||
border-radius: 0.3em;
|
||||
transition: .1s ease all;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#search.active #input {
|
||||
border-bottom: 1px solid var(--borderPrimary);
|
||||
box-shadow: 0 0 5px var(--borderPrimary);
|
||||
background: var(--surfacePrimary);
|
||||
height: 4em;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
background-color: #fff;
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
#search.active > div {
|
||||
border-radius: 0 !important;
|
||||
#search.active>div {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
#search.active i,
|
||||
#search.active input {
|
||||
color: var(--textPrimary);
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
#search #input > .action,
|
||||
#search #input > i {
|
||||
margin-right: 0.3em;
|
||||
user-select: none;
|
||||
#search #input>.action,
|
||||
#search #input>i {
|
||||
margin-right: 0.3em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#search input {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#search #result {
|
||||
visibility: visible;
|
||||
max-height: none;
|
||||
background: var(--background);
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
color: var(--textPrimary);
|
||||
height: 0;
|
||||
transition:
|
||||
0.1s ease height,
|
||||
0.1s ease padding;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
z-index: 1;
|
||||
visibility: visible;
|
||||
max-height: none;
|
||||
background-color: #f8f8f8;
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
height: 0;
|
||||
transition: .1s ease height, .1s ease padding;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #search #result {
|
||||
direction: ltr;
|
||||
body.rtl #search #result {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
#search #result > div > *:first-child {
|
||||
margin-top: 0;
|
||||
#search #result>div>*:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #search #result {
|
||||
text-align: right;
|
||||
body.rtl #search #result {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*** RTL - Keep search result LTR because it has paths (in english) ***/
|
||||
html[dir="rtl"] #search #result ul > * {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
body.rtl #search #result ul>* {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#search.active #result {
|
||||
padding: 0.5em;
|
||||
height: calc(100% - 4em);
|
||||
padding: .5em;
|
||||
height: calc(100%);
|
||||
}
|
||||
|
||||
#search ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#search li {
|
||||
margin-bottom: 0.5em;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
#search #result > div {
|
||||
max-width: 45em;
|
||||
margin: 0 auto;
|
||||
#search #result>div {
|
||||
max-width: 45em;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#search #result #renew {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
display: none;
|
||||
margin: 0;
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
display: none;
|
||||
margin: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
#search.ongoing #result #renew {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#search.active #result i {
|
||||
color: var(--iconTertiary);
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
#search.active #result > p > i {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
display: table;
|
||||
#search.active #result>p>i {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#search.active #result ul li a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.3em 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .3em 0;
|
||||
}
|
||||
|
||||
#search.active #result ul li a i {
|
||||
margin-right: 0.3em;
|
||||
margin-right: .3em;
|
||||
}
|
||||
|
||||
/* I dont think we need these anymore */
|
||||
/* #search::-webkit-input-placeholder {
|
||||
color: var(--textPrimary);
|
||||
#search::-webkit-input-placeholder {
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
#search:-moz-placeholder {
|
||||
opacity: 1;
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
#search::-moz-placeholder {
|
||||
opacity: 1;
|
||||
color: var(--textPrimary);
|
||||
opacity: 1;
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
#search:-ms-input-placeholder {
|
||||
color: var(--textPrimary);
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
#search #input input::placeholder {
|
||||
color: var(--textPrimary);
|
||||
} */
|
||||
|
||||
#search .boxes {
|
||||
border: 1px solid var(--borderPrimary);
|
||||
box-shadow: 0 0 5px var(--borderPrimary);
|
||||
background: var(--surfacePrimary);
|
||||
margin: 1em 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
background: #fff;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
#search .boxes h3 {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
font-size: 1em;
|
||||
color: var(--textSecondary);
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
font-size: 1em;
|
||||
color: #212121;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #search .boxes h3 {
|
||||
text-align: right;
|
||||
body.rtl #search .boxes h3 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#search .boxes > div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-right: -1em;
|
||||
margin-bottom: -1em;
|
||||
#search .boxes>div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-right: -1em;
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
|
||||
#search .boxes > div > div {
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
width: 10em;
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
margin-bottom: 1em;
|
||||
margin-right: 1em;
|
||||
flex-grow: 1;
|
||||
#search .boxes>div>div {
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
width: 10em;
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
margin-bottom: 1em;
|
||||
margin-right: 1em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#search .boxes p {
|
||||
margin: 1em 0 0;
|
||||
margin: 1em 0 0;
|
||||
}
|
||||
|
||||
#search .boxes i {
|
||||
color: #fff !important;
|
||||
font-size: 3.5em;
|
||||
}
|
||||
color: #fff !important;
|
||||
font-size: 3.5em;
|
||||
}
|
||||
@ -2,50 +2,30 @@
|
||||
|
||||
/* General */
|
||||
|
||||
.file-icons [aria-label^="."] {
|
||||
opacity: 0.33;
|
||||
}
|
||||
.file-icons [aria-label$=".bak"] {
|
||||
opacity: 0.33;
|
||||
}
|
||||
.file-icons [aria-label^="."] { opacity: 0.33 }
|
||||
.file-icons [aria-label$=".bak"] { opacity: 0.33 }
|
||||
|
||||
.file-icons [data-type="audio"] i::before {
|
||||
content: "volume_up";
|
||||
}
|
||||
.file-icons [data-type="blob"] i::before {
|
||||
content: "insert_drive_file";
|
||||
}
|
||||
.file-icons [data-type="image"] i::before {
|
||||
content: "image";
|
||||
}
|
||||
.file-icons [data-type="pdf"] i::before {
|
||||
content: "description";
|
||||
}
|
||||
.file-icons [data-type="text"] i::before {
|
||||
content: "description";
|
||||
}
|
||||
.file-icons [data-type="video"] i::before {
|
||||
content: "movie";
|
||||
}
|
||||
.file-icons [data-type="invalid_link"] i::before {
|
||||
content: "link_off";
|
||||
}
|
||||
.file-icons [data-type=audio] i::before { content: 'volume_up' }
|
||||
.file-icons [data-type=blob] i::before { content: 'insert_drive_file' }
|
||||
.file-icons [data-type=image] i::before { content: 'image' }
|
||||
.file-icons [data-type=pdf] i::before { content: 'description' }
|
||||
.file-icons [data-type=text] i::before { content: 'description' }
|
||||
.file-icons [data-type=video] i::before { content: 'movie' }
|
||||
.file-icons [data-type=invalid_link] i::before { content: 'link_off' }
|
||||
|
||||
/* #f90 - Image */
|
||||
|
||||
.file-icons [aria-label$=".ai"] i::before,
|
||||
.file-icons [aria-label$=".odg"] i::before,
|
||||
.file-icons [aria-label$=".xcf"] i::before {
|
||||
content: "image";
|
||||
}
|
||||
.file-icons [aria-label$=".xcf"] i::before
|
||||
{ content: 'image' }
|
||||
|
||||
/* #f90 - Presentation */
|
||||
|
||||
.file-icons [aria-label$=".odp"] i::before,
|
||||
.file-icons [aria-label$=".ppt"] i::before,
|
||||
.file-icons [aria-label$=".pptx"] i::before {
|
||||
content: "slideshow";
|
||||
}
|
||||
.file-icons [aria-label$=".pptx"] i::before
|
||||
{ content: 'slideshow' }
|
||||
|
||||
/* #0f0 - Spreadsheet/Database */
|
||||
|
||||
@ -54,9 +34,8 @@
|
||||
.file-icons [aria-label$=".odb"] i::before,
|
||||
.file-icons [aria-label$=".ods"] i::before,
|
||||
.file-icons [aria-label$=".xls"] i::before,
|
||||
.file-icons [aria-label$=".xlsx"] i::before {
|
||||
content: "border_all";
|
||||
}
|
||||
.file-icons [aria-label$=".xlsx"] i::before
|
||||
{ content: 'border_all' }
|
||||
|
||||
/* #00f - Document */
|
||||
|
||||
@ -64,9 +43,8 @@
|
||||
.file-icons [aria-label$=".docx"] i::before,
|
||||
.file-icons [aria-label$=".log"] i::before,
|
||||
.file-icons [aria-label$=".odt"] i::before,
|
||||
.file-icons [aria-label$=".rtf"] i::before {
|
||||
content: "description";
|
||||
}
|
||||
.file-icons [aria-label$=".rtf"] i::before
|
||||
{ content: 'description' }
|
||||
|
||||
/* #999 - Code */
|
||||
|
||||
@ -87,9 +65,8 @@
|
||||
.file-icons [aria-label$=".rs"] i::before,
|
||||
.file-icons [aria-label$=".vue"] i::before,
|
||||
.file-icons [aria-label$=".xml"] i::before,
|
||||
.file-icons [aria-label$=".yml"] i::before {
|
||||
content: "code";
|
||||
}
|
||||
.file-icons [aria-label$=".yml"] i::before
|
||||
{ content: 'code' }
|
||||
|
||||
/* #999 - Executable */
|
||||
|
||||
@ -98,18 +75,16 @@
|
||||
.file-icons [aria-label$=".exe"] i::before,
|
||||
.file-icons [aria-label$=".jar"] i::before,
|
||||
.file-icons [aria-label$=".ps1"] i::before,
|
||||
.file-icons [aria-label$=".sh"] i::before {
|
||||
content: "web_asset";
|
||||
}
|
||||
.file-icons [aria-label$=".sh"] i::before
|
||||
{ content: 'web_asset' }
|
||||
|
||||
/* #999 - Installer */
|
||||
|
||||
.file-icons [aria-label$=".deb"] i::before,
|
||||
.file-icons [aria-label$=".msi"] i::before,
|
||||
.file-icons [aria-label$=".pkg"] i::before,
|
||||
.file-icons [aria-label$=".rpm"] i::before {
|
||||
content: "archive";
|
||||
}
|
||||
.file-icons [aria-label$=".rpm"] i::before
|
||||
{ content: 'archive' }
|
||||
|
||||
/* #999 - Compressed */
|
||||
|
||||
@ -121,9 +96,8 @@
|
||||
.file-icons [aria-label$=".tar"] i::before,
|
||||
.file-icons [aria-label$=".xz"] i::before,
|
||||
.file-icons [aria-label$=".zip"] i::before,
|
||||
.file-icons [aria-label$=".zst"] i::before {
|
||||
content: "folder_zip";
|
||||
}
|
||||
.file-icons [aria-label$=".zst"] i::before
|
||||
{ content: 'folder_zip' }
|
||||
|
||||
/* #999 - Disk */
|
||||
|
||||
@ -134,35 +108,25 @@
|
||||
.file-icons [aria-label$=".vdi"] i::before,
|
||||
.file-icons [aria-label$=".vhd"] i::before,
|
||||
.file-icons [aria-label$=".vmdk"] i::before,
|
||||
.file-icons [aria-label$=".wim"] i::before {
|
||||
content: "album";
|
||||
}
|
||||
.file-icons [aria-label$=".wim"] i::before
|
||||
{ content: 'album' }
|
||||
|
||||
/* #999 - Font */
|
||||
|
||||
.file-icons [aria-label$=".otf"] i::before,
|
||||
.file-icons [aria-label$=".ttf"] i::before,
|
||||
.file-icons [aria-label$=".woff"] i::before,
|
||||
.file-icons [aria-label$=".woff2"] i::before {
|
||||
content: "font_download";
|
||||
}
|
||||
.file-icons [aria-label$=".woff2"] i::before
|
||||
{ content: 'font_download' }
|
||||
|
||||
/* Colors */
|
||||
|
||||
/* General */
|
||||
|
||||
.file-icons [data-type="audio"] i {
|
||||
color: var(--icon-yellow);
|
||||
}
|
||||
.file-icons [data-type="image"] i {
|
||||
color: var(--icon-orange);
|
||||
}
|
||||
.file-icons [data-type="video"] i {
|
||||
color: var(--icon-violet);
|
||||
}
|
||||
.file-icons [data-type="invalid_link"] i {
|
||||
color: var(--icon-red);
|
||||
}
|
||||
.file-icons [data-type=audio] i { color: var(--icon-yellow) }
|
||||
.file-icons [data-type=image] i { color: var(--icon-orange) }
|
||||
.file-icons [data-type=video] i { color: var(--icon-violet) }
|
||||
.file-icons [data-type=invalid_link] i { color: var(--icon-red) }
|
||||
|
||||
/* #f00 - Adobe/Oracle */
|
||||
|
||||
@ -171,9 +135,8 @@
|
||||
.file-icons [aria-label$=".jar"] i,
|
||||
.file-icons [aria-label$=".psd"] i,
|
||||
.file-icons [aria-label$=".rb"] i,
|
||||
.file-icons [data-type="pdf"] i {
|
||||
color: var(--icon-red);
|
||||
}
|
||||
.file-icons [data-type=pdf] i
|
||||
{ color: var(--icon-red) }
|
||||
|
||||
/* #f90 - Image/Presentation */
|
||||
|
||||
@ -183,18 +146,16 @@
|
||||
.file-icons [aria-label$=".ppt"] i,
|
||||
.file-icons [aria-label$=".pptx"] i,
|
||||
.file-icons [aria-label$=".vue"] i,
|
||||
.file-icons [aria-label$=".xcf"] i {
|
||||
color: var(--icon-orange);
|
||||
}
|
||||
.file-icons [aria-label$=".xcf"] i
|
||||
{ color: var(--icon-orange) }
|
||||
|
||||
/* #ff0 - Various */
|
||||
|
||||
.file-icons [aria-label$=".css"] i,
|
||||
.file-icons [aria-label$=".js"] i,
|
||||
.file-icons [aria-label$=".json"] i,
|
||||
.file-icons [aria-label$=".zip"] i {
|
||||
color: var(--icon-yellow);
|
||||
}
|
||||
.file-icons [aria-label$=".zip"] i
|
||||
{ color: var(--icon-yellow) }
|
||||
|
||||
/* #0f0 - Spreadsheet/Google */
|
||||
|
||||
@ -203,9 +164,8 @@
|
||||
.file-icons [aria-label$=".go"] i,
|
||||
.file-icons [aria-label$=".ods"] i,
|
||||
.file-icons [aria-label$=".xls"] i,
|
||||
.file-icons [aria-label$=".xlsx"] i {
|
||||
color: var(--icon-green);
|
||||
}
|
||||
.file-icons [aria-label$=".xlsx"] i
|
||||
{ color: var(--icon-green) }
|
||||
|
||||
/* #00f - Document/Microsoft/Apple/Closed */
|
||||
|
||||
@ -228,26 +188,18 @@
|
||||
.file-icons [aria-label$=".ps1"] i,
|
||||
.file-icons [aria-label$=".rtf"] i,
|
||||
.file-icons [aria-label$=".vob"] i,
|
||||
.file-icons [aria-label$=".wim"] i {
|
||||
color: var(--icon-blue);
|
||||
}
|
||||
.file-icons [aria-label$=".wim"] i
|
||||
{ color: var(--icon-blue) }
|
||||
|
||||
/* #60f - Various */
|
||||
|
||||
.file-icons [aria-label$=".iso"] i,
|
||||
.file-icons [aria-label$=".php"] i,
|
||||
.file-icons [aria-label$=".rar"] i {
|
||||
color: var(--icon-violet);
|
||||
}
|
||||
.file-icons [aria-label$=".rar"] i
|
||||
{ color: var(--icon-violet) }
|
||||
|
||||
/* Overrides */
|
||||
|
||||
.file-icons [data-dir="true"] i {
|
||||
color: var(--icon-blue);
|
||||
}
|
||||
.file-icons [data-dir="true"] i::before {
|
||||
content: "folder";
|
||||
}
|
||||
.file-icons [aria-selected="true"] i {
|
||||
color: var(--iconSecondary);
|
||||
}
|
||||
.file-icons [data-dir=true] i { color: var(--icon-blue) }
|
||||
.file-icons [data-dir=true] i::before { content: 'folder' }
|
||||
.file-icons [aria-selected=true] i { color: var(--item-selected) }
|
||||
|
||||
@ -1,288 +1,571 @@
|
||||
html[dir="rtl"] #listing {
|
||||
margin-right: 16em;
|
||||
#listing {
|
||||
--item-selected: white;
|
||||
}
|
||||
|
||||
body.rtl #listing {
|
||||
margin-right: 16em;
|
||||
}
|
||||
|
||||
#listing h2 {
|
||||
margin: 0 0 0 0.5em;
|
||||
font-size: 0.9em;
|
||||
color: var(--textPrimary);
|
||||
font-weight: 500;
|
||||
margin: 0 0 0 0.5em;
|
||||
font-size: .9em;
|
||||
color: rgba(0, 0, 0, 0.38);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#listing .item div:last-of-type * {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#listing > div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
#listing>div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
#listing .item {
|
||||
background: var(--surfacePrimary);
|
||||
border-color: var(--divider);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
color: var(--textPrimary);
|
||||
transition:
|
||||
0.1s ease background,
|
||||
0.1s ease opacity;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
color: #6f6f6f;
|
||||
transition: .1s ease background, .1s ease opacity;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#listing .item div:last-of-type {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#listing .item p {
|
||||
margin: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#listing .item .size,
|
||||
#listing .item .modified {
|
||||
font-size: 0.9em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
#listing .item .name {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#listing .item i {
|
||||
font-size: 4em;
|
||||
margin-right: 0.1em;
|
||||
vertical-align: bottom;
|
||||
font-size: 4em;
|
||||
margin-right: 0.1em;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
#listing .item img {
|
||||
width: 4em;
|
||||
height: 4em;
|
||||
object-fit: cover;
|
||||
margin-right: 0.1em;
|
||||
vertical-align: bottom;
|
||||
width: 4em;
|
||||
height: 4em;
|
||||
object-fit: cover;
|
||||
margin-right: 0.1em;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.message {
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
margin: 1em auto;
|
||||
display: block !important;
|
||||
width: 95%;
|
||||
color: var(--textPrimary);
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
margin: 1em auto;
|
||||
display: block !important;
|
||||
width: 95%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.message i {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 0.2em;
|
||||
display: block;
|
||||
font-size: 2.5em;
|
||||
margin-bottom: .2em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#listing.mosaic {
|
||||
padding-top: 1em;
|
||||
margin: 0 -0.5em;
|
||||
padding-top: 1em;
|
||||
margin: 0 -0.5em;
|
||||
}
|
||||
|
||||
#listing.mosaic .item {
|
||||
width: calc(33% - 1em);
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
border-radius: 0.2em;
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.06),
|
||||
0 1px 2px rgba(0, 0, 0, 0.12);
|
||||
width: calc(33% - 1em);
|
||||
margin: .5em;
|
||||
padding: 0.5em;
|
||||
border-radius: 0.2em;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .06), 0 1px 2px rgba(0, 0, 0, .12);
|
||||
}
|
||||
|
||||
#listing.mosaic .item:hover {
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.12),
|
||||
0 1px 2px rgba(0, 0, 0, 0.24) !important;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24) !important;
|
||||
}
|
||||
|
||||
#listing.mosaic .header {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#listing.mosaic .item div:first-of-type {
|
||||
width: 5em;
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
#listing.mosaic .item div:last-of-type {
|
||||
width: calc(100% - 5vw);
|
||||
width: calc(100% - 5vw);
|
||||
}
|
||||
|
||||
#listing.mosaic.gallery .item div:first-of-type {
|
||||
width: 100%;
|
||||
height: 12em;
|
||||
width: 100%;
|
||||
height: 12em;
|
||||
}
|
||||
|
||||
#listing.mosaic.gallery .item div:last-of-type {
|
||||
position: absolute;
|
||||
bottom: 0.5em;
|
||||
padding: 1em;
|
||||
width: calc(100% - 1em);
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
bottom: 0.5em;
|
||||
padding: 1em;
|
||||
width: calc(100% - 1em);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#listing.mosaic.gallery .item[data-type="image"] div:last-of-type {
|
||||
color: white;
|
||||
background: linear-gradient(#0000, #0009);
|
||||
#listing.mosaic.gallery .item[data-type=image] div:last-of-type {
|
||||
color: white;
|
||||
background: linear-gradient(#0000, #0009);
|
||||
}
|
||||
|
||||
#listing.mosaic.gallery .item i {
|
||||
width: 100%;
|
||||
margin-right: 0;
|
||||
font-size: 8em;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-right: 0;
|
||||
font-size: 8em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#listing.mosaic.gallery .item img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#listing.gallery .size,
|
||||
#listing.gallery .modified {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#listing.list {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#listing.list .item {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border: 1px solid var(--borderPrimary);
|
||||
padding: 1em;
|
||||
border-top: 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding: 1em;
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
#listing.list h2 {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#listing .item[aria-selected="true"] {
|
||||
background: var(--blue) !important;
|
||||
color: var(--iconSecondary) !important;
|
||||
#listing .item[aria-selected=true] {
|
||||
/* background: var(--blue) !important; */
|
||||
color: var(--item-selected) !important;
|
||||
}
|
||||
|
||||
#listing.list .item div:first-of-type {
|
||||
width: 3em;
|
||||
width: 3em;
|
||||
}
|
||||
|
||||
#listing.list .item div:first-of-type i {
|
||||
font-size: 2em;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
#listing.list .item div:first-of-type img {
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#listing.list .item div:last-of-type {
|
||||
width: calc(100% - 3em);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: calc(100% - 3em);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#listing.list .item .name {
|
||||
width: 50%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#listing.list .item .size {
|
||||
width: 25%;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
#listing .item.header {
|
||||
display: none !important;
|
||||
background-color: var(--iconTertiary);
|
||||
display: none !important;
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
#listing.list .header i {
|
||||
font-size: 1.5em;
|
||||
vertical-align: middle;
|
||||
margin-left: 0.2em;
|
||||
font-size: 1.5em;
|
||||
vertical-align: middle;
|
||||
margin-left: .2em;
|
||||
}
|
||||
|
||||
#listing.list .item.header {
|
||||
display: flex !important;
|
||||
background: var(--background);
|
||||
z-index: 999;
|
||||
padding: 0.85em;
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--borderPrimary);
|
||||
display: flex !important;
|
||||
background: #fafafa;
|
||||
z-index: 999;
|
||||
padding: .85em;
|
||||
border: 0;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
#listing.list .item.header > div:first-child {
|
||||
width: 0;
|
||||
#listing.list .item.header>div:first-child {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#listing.list .item.header .name {
|
||||
margin-right: 3em;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
#listing.list .header a {
|
||||
color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#listing.list .item.header > div:first-child {
|
||||
width: 0;
|
||||
#listing.list .item.header>div:first-child {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#listing.list .name {
|
||||
font-weight: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#listing.list .item.header .name {
|
||||
margin-right: 3em;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
#listing.list .header span {
|
||||
vertical-align: middle;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#listing.list .header i {
|
||||
opacity: 0;
|
||||
transition: 0.1s ease all;
|
||||
opacity: 0;
|
||||
transition: .1s ease all;
|
||||
}
|
||||
|
||||
#listing.list .header p:hover i,
|
||||
#listing.list .header .active i {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#listing.list .item.header .active {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#listing #multiple-selection {
|
||||
position: fixed;
|
||||
bottom: -4em;
|
||||
left: 0;
|
||||
z-index: 99999;
|
||||
width: 100%;
|
||||
background-color: var(--blue);
|
||||
height: 4em;
|
||||
padding: 0.5em 0.5em 0.5em 1em;
|
||||
justify-content: space-between;
|
||||
transition: 0.2s ease bottom;
|
||||
position: fixed;
|
||||
bottom: -4em;
|
||||
left: 0;
|
||||
z-index: 99999;
|
||||
width: 100%;
|
||||
background-color: var(--blue);
|
||||
height: 4em;
|
||||
padding: 0.5em 0.5em 0.5em 1em;
|
||||
justify-content: space-between;
|
||||
transition: .2s ease bottom;
|
||||
}
|
||||
|
||||
#listing #multiple-selection.active {
|
||||
bottom: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#listing #multiple-selection p,
|
||||
#listing #multiple-selection i {
|
||||
color: var(--iconSecondary);
|
||||
color: var(--item-selected);
|
||||
}
|
||||
|
||||
|
||||
/* remove a bit of padding from the file list entries */
|
||||
|
||||
#listing.list .item {
|
||||
padding: 0.7em;
|
||||
}
|
||||
|
||||
/* make folders yellow-ish */
|
||||
#listing .item[data-dir=true] div i {
|
||||
color: #ffc84b;
|
||||
}
|
||||
|
||||
/* packed files - colorize and change icon */
|
||||
#listing .item[aria-label$=".7z"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".7z"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".7z"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".arj"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".arj"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".arj"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".zip"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".zip"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".zip"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".gz"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".gz"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".gz"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".tar"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".tar"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".tar"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
||||
#listing .item[aria-label$=".bz"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".bz"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".bz"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".bz2"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".bz2"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".bz2"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".xz"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".xz"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".xz"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".tbz"] div i {
|
||||
color: #a268a1;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".tbz"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".tbz"] .material-icons::before {
|
||||
content: "archive";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
||||
/* office files */
|
||||
/* PDF - colorize and change icon /*
|
||||
/* Note: This is yellow because I use SumatraPDF */
|
||||
#listing .item[aria-label$=".pdf"] div i {
|
||||
color: #FFEE00;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".pdf"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".pdf"] .material-icons::before {
|
||||
content: "picture_as_pdf";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* word processors - colorize and change icon */
|
||||
/* Word */
|
||||
#listing .item[aria-label$=".doc"] div i {
|
||||
color: #185ABD;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".doc"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".doc"] .material-icons::before {
|
||||
content: "description";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".docx"] div i {
|
||||
color: #185ABD;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".docx"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".docx"] .material-icons::before {
|
||||
content: "description";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* OpenOffice Writer */
|
||||
#listing .item[aria-label$=".odt"] div i {
|
||||
color: #185ABD;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".odt"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".odt"] .material-icons::before {
|
||||
content: "description";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* LibreOffice Writer */
|
||||
#listing .item[aria-label$=".sxw"] div i {
|
||||
color: #185ABD;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".sxw"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".sxw"] .material-icons::before {
|
||||
content: "description";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
||||
/* PowerPoint */
|
||||
#listing .item[aria-label$=".ppt"] div i {
|
||||
color: #D35230;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".pptx"] div i {
|
||||
color: #D35230;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".pps"] div i {
|
||||
color: #D35230;
|
||||
}
|
||||
|
||||
/* OpenOffice Impress */
|
||||
#listing .item[aria-label$=".odp"] div i {
|
||||
color: #D35230;
|
||||
}
|
||||
|
||||
|
||||
/* Excel */
|
||||
#listing .item[aria-label$=".xls"] div i {
|
||||
color: #107C41;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".xlsx"] div i {
|
||||
color: #107C41;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".ods"] div i {
|
||||
color: #107C41;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".sxc"] div i {
|
||||
color: #107C41;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".wri"] div i {
|
||||
color: #336eff;
|
||||
}
|
||||
|
||||
|
||||
/* sound files - colorize */
|
||||
#listing .item[data-type=audio] div i {
|
||||
color: #F47900;
|
||||
}
|
||||
|
||||
/* video files - colorize */
|
||||
#listing .item[data-type=video] div i {
|
||||
color: #F47900;
|
||||
}
|
||||
|
||||
/* text files - change icon*/
|
||||
#listing .item[aria-label$=".txt"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".txt"] .material-icons::before {
|
||||
content: "description";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".md"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".md"] .material-icons::before {
|
||||
content: "description";
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* various other files*/
|
||||
/* iCal - change icon*/
|
||||
#listing .item[aria-label$=".ics"] .material-icons {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#listing .item[aria-label$=".ics"] .material-icons::before {
|
||||
content: "event";
|
||||
visibility: visible;
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
#login {
|
||||
background: var(--surfacePrimary);
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@ -17,7 +17,7 @@
|
||||
#login h1 {
|
||||
text-align: center;
|
||||
font-size: 2.5em;
|
||||
margin: 0.4em 0 0.67em;
|
||||
margin: .4em 0 .67em;
|
||||
}
|
||||
|
||||
#login form {
|
||||
@ -34,15 +34,15 @@
|
||||
}
|
||||
|
||||
#login #recaptcha {
|
||||
margin: 0.5em 0 0;
|
||||
margin: .5em 0 0;
|
||||
}
|
||||
|
||||
#login .wrong {
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
padding: 0.5em;
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
animation: 0.2s opac forwards;
|
||||
animation: .2s opac forwards;
|
||||
}
|
||||
|
||||
@keyframes opac {
|
||||
@ -61,5 +61,5 @@
|
||||
text-transform: lowercase;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
margin: 0.5rem 0;
|
||||
margin: .5rem 0;
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
@media (max-width: 1024px) {
|
||||
nav {
|
||||
width: 10em;
|
||||
width: 10em
|
||||
}
|
||||
/* Mobile Only fix div hidden by bottom navigation bar of mobile browser when using height: 100vh */
|
||||
#previewer .preview {
|
||||
/* height: calc(100% - 4em) !important; */
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
main {
|
||||
width: calc(100% - 13em);
|
||||
width: calc(100% - 13em)
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,27 +25,27 @@
|
||||
width: 60%;
|
||||
}
|
||||
#more {
|
||||
display: inherit;
|
||||
display: inherit
|
||||
}
|
||||
header .overlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--borderPrimary);
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
#dropdown {
|
||||
position: fixed;
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
display: block;
|
||||
background: var(--surfaceSecondary);
|
||||
box-shadow: 0 0 5px var(--borderPrimary);
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
transform: scale(0);
|
||||
transition: 0.1s ease-in-out transform;
|
||||
transition: .1s ease-in-out transform;
|
||||
transform-origin: top right;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #dropdown {
|
||||
body.rtl #dropdown {
|
||||
right: unset;
|
||||
left: 1em;
|
||||
transform-origin: top left;
|
||||
@ -61,7 +65,7 @@
|
||||
}
|
||||
#dropdown .action span:not(.counter) {
|
||||
display: inline-block;
|
||||
padding: 0.4em;
|
||||
padding: .4em;
|
||||
}
|
||||
#dropdown .counter {
|
||||
left: 2.25em;
|
||||
@ -73,10 +77,8 @@
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--surfaceSecondary);
|
||||
box-shadow:
|
||||
rgba(0, 0, 0, 0.06) 0px 1px 3px,
|
||||
rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
background: #fff;
|
||||
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
width: 95%;
|
||||
max-width: 20em;
|
||||
z-index: 1;
|
||||
@ -88,7 +90,7 @@
|
||||
#file-selection > span {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
color: var(--textPrimary);
|
||||
color: #6f6f6f;
|
||||
margin-right: auto;
|
||||
}
|
||||
#file-selection .action span {
|
||||
@ -97,15 +99,15 @@
|
||||
nav {
|
||||
top: 0;
|
||||
z-index: 99999;
|
||||
background: var(--surfaceSecondary);
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
width: 16em;
|
||||
box-shadow: 0 0 5px var(--borderPrimary);
|
||||
transition: 0.1s ease left;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
transition: .1s ease left;
|
||||
left: -17em;
|
||||
}
|
||||
|
||||
html[dir="rtl"] nav {
|
||||
body.rtl nav {
|
||||
left: unset;
|
||||
right: -17em;
|
||||
}
|
||||
@ -113,7 +115,7 @@
|
||||
left: 0;
|
||||
}
|
||||
|
||||
html[dir="rtl"] nav.active {
|
||||
body.rtl nav.active {
|
||||
left: unset;
|
||||
right: 0;
|
||||
}
|
||||
@ -133,19 +135,19 @@
|
||||
margin-bottom: 5em;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #listing {
|
||||
body.rtl #listing {
|
||||
margin-right: unset;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .breadcrumbs {
|
||||
body.rtl .breadcrumbs {
|
||||
transform: translateX(16em);
|
||||
}
|
||||
|
||||
html[dir="rtl"] #nav .wrapper {
|
||||
body.rtl #nav .wrapper {
|
||||
margin-right: unset;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .dashboard .row {
|
||||
|
||||
body.rtl .dashboard .row {
|
||||
margin-right: unset;
|
||||
}
|
||||
|
||||
@ -168,4 +170,4 @@
|
||||
#listing.list .item .name {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
@import "normalize.css/normalize.css";
|
||||
@import "vue-toastification/dist/index.css";
|
||||
@import "vue-final-modal/style.css";
|
||||
@import "noty/lib/noty.css";
|
||||
@import "noty/lib/themes/mint.css";
|
||||
@import "./_variables.css";
|
||||
@import "./_buttons.css";
|
||||
@import "./_inputs.css";
|
||||
@ -16,23 +16,10 @@
|
||||
@import "./login.css";
|
||||
@import "./mobile.css";
|
||||
|
||||
/* For testing only
|
||||
:focus {
|
||||
outline: 2px solid crimson !important;
|
||||
border-radius: 3px !important;
|
||||
} */
|
||||
|
||||
.link {
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
#loading {
|
||||
background: var(--background);
|
||||
}
|
||||
#loading .spinner > div {
|
||||
background: var(--iconPrimary);
|
||||
}
|
||||
|
||||
main .spinner {
|
||||
display: block;
|
||||
text-align: center;
|
||||
@ -45,7 +32,7 @@ main .spinner > div {
|
||||
height: 0.8em;
|
||||
margin: 0 0.1em;
|
||||
font-size: 1em;
|
||||
background: var(--iconPrimary);
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
@ -85,7 +72,7 @@ main .spinner .bounce2 {
|
||||
transition: 0.2s ease all;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
color: var(--action);
|
||||
color: #546e7a;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
@ -107,7 +94,7 @@ main .spinner .bounce2 {
|
||||
}
|
||||
|
||||
.action:hover {
|
||||
background-color: var(--hover);
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.action ul {
|
||||
@ -128,7 +115,7 @@ main .spinner .bounce2 {
|
||||
}
|
||||
|
||||
.action ul li:hover {
|
||||
background-color: var(--divider);
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
#click-overlay {
|
||||
@ -151,7 +138,7 @@ main .spinner .bounce2 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: var(--blue);
|
||||
color: var(--iconSecondary);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
font-size: 0.75em;
|
||||
width: 1.8em;
|
||||
@ -159,13 +146,14 @@ main .spinner .bounce2 {
|
||||
text-align: center;
|
||||
line-height: 1.55em;
|
||||
font-weight: bold;
|
||||
border: 2px solid var(--borderPrimary);
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
/* PREVIEWER */
|
||||
|
||||
#previewer {
|
||||
background-color: rgba(0, 0, 0, 0.99);
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
padding-top: 4em;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@ -178,25 +166,15 @@ main .spinner .bounce2 {
|
||||
#previewer header {
|
||||
background: none;
|
||||
color: #fff;
|
||||
border-bottom: 0px;
|
||||
box-shadow: 0px 0px 0px;
|
||||
z-index: 19999;
|
||||
}
|
||||
|
||||
#previewer header > .action i {
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 1px #000000;
|
||||
}
|
||||
|
||||
#previewer header > title {
|
||||
white-space: nowrap;
|
||||
text-shadow: 1px 1px 1px #000000;
|
||||
}
|
||||
|
||||
@media (min-width: 738px) {
|
||||
#previewer header #dropdown .action i {
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 1px #000000;
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +188,7 @@ main .spinner .bounce2 {
|
||||
|
||||
#previewer .preview {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
height: calc(100vh - 4em);
|
||||
}
|
||||
|
||||
#previewer .preview pre {
|
||||
@ -225,11 +203,6 @@ main .spinner .bounce2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#previewer .preview audio {
|
||||
width: 95%;
|
||||
height: 88%;
|
||||
}
|
||||
|
||||
#previewer .preview video {
|
||||
height: 100%;
|
||||
}
|
||||
@ -274,7 +247,7 @@ main .spinner .bounce2 {
|
||||
#previewer > button {
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
top: calc(50% + 1.85em);
|
||||
transform: translateY(-50%);
|
||||
background-color: rgba(80, 80, 80, 0.5);
|
||||
color: white;
|
||||
@ -314,7 +287,7 @@ main .spinner .bounce2 {
|
||||
#previewer .spinner > div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background: var(--iconPrimary);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* EDITOR */
|
||||
@ -322,21 +295,17 @@ main .spinner .bounce2 {
|
||||
#editor-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--background);
|
||||
background-color: #fafafa;
|
||||
position: fixed;
|
||||
padding-top: 4em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 9998;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#editor-container .bar {
|
||||
background: var(--surfacePrimary);
|
||||
}
|
||||
|
||||
#editor-container #editor {
|
||||
flex: 1;
|
||||
}
|
||||
@ -347,7 +316,7 @@ main .spinner .bounce2 {
|
||||
}
|
||||
|
||||
/*** RTL - flip and position arrow of path ***/
|
||||
html[dir="rtl"] .breadcrumbs .chevron {
|
||||
body.rtl .breadcrumbs .chevron {
|
||||
transform: scaleX(-1) translateX(16em);
|
||||
}
|
||||
|
||||
@ -359,6 +328,22 @@ html[dir="rtl"] .breadcrumbs .chevron {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * *
|
||||
* PROMPT *
|
||||
* * * * * * * * * * * * * * * */
|
||||
|
||||
.noty_buttons {
|
||||
text-align: right;
|
||||
padding: 0 10px 10px !important;
|
||||
}
|
||||
|
||||
.noty_buttons button {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 0 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * *
|
||||
* FOOTER *
|
||||
* * * * * * * * * * * * * * * */
|
||||
@ -436,17 +421,17 @@ html[dir="rtl"] .breadcrumbs .chevron {
|
||||
* RTL overrides *
|
||||
* * * * * * * * * * * * * * * */
|
||||
|
||||
html[dir="rtl"] .card-content textarea {
|
||||
body.rtl .card-content textarea {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .card-content .small + input {
|
||||
body.rtl .card-content .small + input {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .card.floating .card-content .file-list {
|
||||
body.rtl .card.floating .card-content .file-list {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
46
frontend/src/utils/constants.js
Normal file
46
frontend/src/utils/constants.js
Normal file
@ -0,0 +1,46 @@
|
||||
const name = window.FileBrowser.Name || "File Browser";
|
||||
const disableExternal = window.FileBrowser.DisableExternal;
|
||||
const disableUsedPercentage = window.FileBrowser.DisableUsedPercentage;
|
||||
const baseURL = window.FileBrowser.BaseURL;
|
||||
const staticURL = window.FileBrowser.StaticURL;
|
||||
const recaptcha = window.FileBrowser.ReCaptcha;
|
||||
const recaptchaKey = window.FileBrowser.ReCaptchaKey;
|
||||
const signup = window.FileBrowser.Signup;
|
||||
const version = window.FileBrowser.Version;
|
||||
const logoURL = `${staticURL}/img/logo.svg`;
|
||||
const Folder=`${staticURL}/img/icons/folder.svg`;
|
||||
const Home=`${staticURL}/img/icons/home.svg`;
|
||||
const noAuth = window.FileBrowser.NoAuth;
|
||||
const authMethod = window.FileBrowser.AuthMethod;
|
||||
const loginPage = window.FileBrowser.LoginPage;
|
||||
const theme = window.FileBrowser.Theme;
|
||||
const enableThumbs = window.FileBrowser.EnableThumbs;
|
||||
const resizePreview = window.FileBrowser.ResizePreview;
|
||||
const enableExec = window.FileBrowser.EnableExec;
|
||||
const tusSettings = window.FileBrowser.TusSettings;
|
||||
const origin = window.location.origin;
|
||||
const tusEndpoint = `/api/tus`;
|
||||
|
||||
export {
|
||||
name,
|
||||
disableExternal,
|
||||
disableUsedPercentage,
|
||||
baseURL,
|
||||
logoURL,
|
||||
Folder,
|
||||
Home,
|
||||
recaptcha,
|
||||
recaptchaKey,
|
||||
signup,
|
||||
version,
|
||||
noAuth,
|
||||
authMethod,
|
||||
loginPage,
|
||||
theme,
|
||||
enableThumbs,
|
||||
resizePreview,
|
||||
enableExec,
|
||||
tusSettings,
|
||||
origin,
|
||||
tusEndpoint,
|
||||
};
|
||||
@ -1,129 +1,152 @@
|
||||
<template>
|
||||
<div id="editor-container" @touchmove.prevent.stop @wheel.prevent.stop>
|
||||
<div id="editor-container">
|
||||
<header-bar>
|
||||
<action icon="close" :label="t('buttons.close')" @action="close()" />
|
||||
<title>{{ fileStore.req?.name ?? "" }}</title>
|
||||
<action :label="$t('buttons.close')" @action="close()" />
|
||||
<title>{{ req.name }}</title>
|
||||
|
||||
<action
|
||||
v-if="authStore.user?.perm.modify"
|
||||
v-if="user.perm.modify"
|
||||
id="save-button"
|
||||
icon="save"
|
||||
:label="t('buttons.save')"
|
||||
:label="$t('buttons.save')"
|
||||
@action="save()"
|
||||
/>
|
||||
</header-bar>
|
||||
|
||||
<Breadcrumbs base="/files" noLink />
|
||||
<breadcrumbs base="/files" noLink />
|
||||
|
||||
<form id="editor"></form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import { files as api } from "@/api";
|
||||
import { theme } from "@/utils/constants";
|
||||
import buttons from "@/utils/buttons";
|
||||
import url from "@/utils/url";
|
||||
import ace, { Ace, version as ace_version } from "ace-builds";
|
||||
import modelist from "ace-builds/src-noconflict/ext-modelist";
|
||||
import "ace-builds/src-noconflict/ext-language_tools";
|
||||
|
||||
import { version as ace_version } from "ace-builds";
|
||||
import ace from "ace-builds/src-min-noconflict/ace.js";
|
||||
import modelist from "ace-builds/src-min-noconflict/ext-modelist.js";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { useFileStore } from "@/stores/file";
|
||||
import { useLayoutStore } from "@/stores/layout";
|
||||
import { inject, onBeforeUnmount, onMounted, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { getTheme } from "@/utils/theme";
|
||||
|
||||
const $showError = inject<IToastError>("$showError")!;
|
||||
export default {
|
||||
name: "editor",
|
||||
components: {
|
||||
HeaderBar,
|
||||
Action,
|
||||
Breadcrumbs,
|
||||
},
|
||||
data: function () {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["req", "user"]),
|
||||
breadcrumbs() {
|
||||
let parts = this.$route.path.split("/");
|
||||
|
||||
const fileStore = useFileStore();
|
||||
const authStore = useAuthStore();
|
||||
const layoutStore = useLayoutStore();
|
||||
if (parts[0] === "") {
|
||||
parts.shift();
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
if (parts[parts.length - 1] === "") {
|
||||
parts.pop();
|
||||
}
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
let breadcrumbs = [];
|
||||
|
||||
const editor = ref<Ace.Editor | null>(null);
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]) });
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("keydown", keyEvent);
|
||||
breadcrumbs.shift();
|
||||
|
||||
const fileContent = fileStore.req?.content || "";
|
||||
if (breadcrumbs.length > 3) {
|
||||
while (breadcrumbs.length !== 4) {
|
||||
breadcrumbs.shift();
|
||||
}
|
||||
|
||||
ace.config.set(
|
||||
"basePath",
|
||||
`https://cdn.jsdelivr.net/npm/ace-builds@${ace_version}/src-min-noconflict/`
|
||||
);
|
||||
breadcrumbs[0].name = "...";
|
||||
}
|
||||
|
||||
editor.value = ace.edit("editor", {
|
||||
value: fileContent,
|
||||
showPrintMargin: false,
|
||||
readOnly: fileStore.req?.type === "textImmutable",
|
||||
theme: "ace/theme/chrome",
|
||||
mode: modelist.getModeForPath(fileStore.req?.name).mode,
|
||||
wrap: true,
|
||||
enableBasicAutocompletion: true,
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
});
|
||||
return breadcrumbs;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
window.addEventListener("keydown", this.keyEvent);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("keydown", this.keyEvent);
|
||||
this.editor.destroy();
|
||||
},
|
||||
mounted: function () {
|
||||
const fileContent = this.req.content || "";
|
||||
|
||||
if (getTheme() === "dark") {
|
||||
editor.value!.setTheme("ace/theme/twilight");
|
||||
}
|
||||
ace.config.set(
|
||||
"basePath",
|
||||
`https://cdn.jsdelivr.net/npm/ace-builds@${ace_version}/src-min-noconflict/`
|
||||
);
|
||||
|
||||
editor.value.focus();
|
||||
});
|
||||
this.editor = ace.edit("editor", {
|
||||
value: fileContent,
|
||||
showPrintMargin: false,
|
||||
readOnly: this.req.type === "textImmutable",
|
||||
theme: "ace/theme/chrome",
|
||||
mode: modelist.getModeForPath(this.req.name).mode,
|
||||
wrap: true,
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("keydown", keyEvent);
|
||||
editor.value?.destroy();
|
||||
});
|
||||
if (theme == "dark") {
|
||||
this.editor.setTheme("ace/theme/twilight");
|
||||
}
|
||||
|
||||
const keyEvent = (event: KeyboardEvent) => {
|
||||
if (event.code === "Escape") {
|
||||
close();
|
||||
}
|
||||
this.editor.focus();
|
||||
},
|
||||
methods: {
|
||||
keyEvent(event) {
|
||||
if (event.code === "Escape") {
|
||||
this.close();
|
||||
}
|
||||
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
return;
|
||||
}
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key !== "s") {
|
||||
return;
|
||||
}
|
||||
if (String.fromCharCode(event.which).toLowerCase() !== "s") {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
save();
|
||||
};
|
||||
event.preventDefault();
|
||||
this.save();
|
||||
},
|
||||
async save() {
|
||||
const button = "save";
|
||||
buttons.loading("save");
|
||||
|
||||
const save = async () => {
|
||||
const button = "save";
|
||||
buttons.loading("save");
|
||||
try {
|
||||
await api.put(this.$route.path, this.editor.getValue());
|
||||
this.editor.session.getUndoManager().markClean();
|
||||
buttons.success(button);
|
||||
} catch (e) {
|
||||
buttons.done(button);
|
||||
this.$showError(e);
|
||||
}
|
||||
},
|
||||
close() {
|
||||
if (!this.editor.session.getUndoManager().isClean()) {
|
||||
this.$store.commit("showHover", "discardEditorChanges");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await api.put(route.path, editor.value?.getValue());
|
||||
editor.value?.session.getUndoManager().markClean();
|
||||
buttons.success(button);
|
||||
} catch (e: any) {
|
||||
buttons.done(button);
|
||||
$showError(e);
|
||||
}
|
||||
};
|
||||
const close = () => {
|
||||
if (!editor.value?.session.getUndoManager().isClean()) {
|
||||
layoutStore.showHover("discardEditorChanges");
|
||||
return;
|
||||
}
|
||||
this.$store.commit("updateRequest", {});
|
||||
|
||||
fileStore.updateRequest(null);
|
||||
|
||||
let uri = url.removeLastDir(route.path) + "/";
|
||||
router.push({ path: uri });
|
||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
||||
this.$router.push({ path: uri });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
822
frontend/src/views/files/Listing.vue
Normal file
822
frontend/src/views/files/Listing.vue
Normal file
@ -0,0 +1,822 @@
|
||||
<template>
|
||||
<div>
|
||||
<header-bar showMenu showLogo>
|
||||
<search />
|
||||
<title />
|
||||
<action
|
||||
class="search-button"
|
||||
icon="search"
|
||||
:label="$t('buttons.search')"
|
||||
@action="openSearch()"
|
||||
/>
|
||||
|
||||
<template #actions>
|
||||
<action
|
||||
v-if="headerButtons.shell"
|
||||
icon="code"
|
||||
:label="$t('buttons.shell')"
|
||||
@action="$store.commit('toggleShell')"
|
||||
/>
|
||||
<action
|
||||
:label="$t('buttons.switchView')"
|
||||
@action="switchView"
|
||||
/>
|
||||
<action
|
||||
v-if="headerButtons.download"
|
||||
:label="$t('buttons.download')"
|
||||
@action="download"
|
||||
:counter="selectedCount"
|
||||
/>
|
||||
<action
|
||||
v-if="headerButtons.upload"
|
||||
id="upload-button"
|
||||
:label="$t('buttons.upload')"
|
||||
@action="upload"
|
||||
/>
|
||||
<action icon="info" :label="$t('buttons.info')" show="info" />
|
||||
<action
|
||||
icon="check_circle"
|
||||
:label="$t('buttons.selectMultiple')"
|
||||
@action="toggleMultipleSelection"
|
||||
/>
|
||||
</template>
|
||||
</header-bar>
|
||||
|
||||
<div v-if="isMobile" id="file-selection">
|
||||
<span v-if="selectedCount > 0">{{ selectedCount }} selected</span>
|
||||
</div>
|
||||
|
||||
<div v-if="loading">
|
||||
<h2 class="message delayed">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
</div>
|
||||
<span>{{ $t("files.loading") }}</span>
|
||||
</h2>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div v-if="req.numDirs + req.numFiles == 0">
|
||||
<h2 class="message">
|
||||
<i class="material-icons">sentiment_dissatisfied</i>
|
||||
<span>{{ $t("files.lonely") }}</span>
|
||||
</h2>
|
||||
<input
|
||||
style="display: none"
|
||||
type="file"
|
||||
id="upload-input"
|
||||
@change="uploadInput($event)"
|
||||
multiple
|
||||
/>
|
||||
<input
|
||||
style="display: none"
|
||||
type="file"
|
||||
id="upload-folder-input"
|
||||
@change="uploadInput($event)"
|
||||
webkitdirectory
|
||||
multiple
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
id="listing"
|
||||
ref="listing"
|
||||
:class="user.viewMode + ' file-icons'"
|
||||
>
|
||||
<div>
|
||||
<div class="item header">
|
||||
<div></div>
|
||||
<div>
|
||||
<p
|
||||
:class="{ active: nameSorted }"
|
||||
class="name"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="sort('name')"
|
||||
:title="$t('files.sortByName')"
|
||||
:aria-label="$t('files.sortByName')"
|
||||
>
|
||||
<span>{{ $t("files.name") }}</span>
|
||||
<i class="material-icons">{{ nameIcon }}</i>
|
||||
</p>
|
||||
|
||||
<p
|
||||
:class="{ active: sizeSorted }"
|
||||
class="size"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="sort('size')"
|
||||
:title="$t('files.sortBySize')"
|
||||
:aria-label="$t('files.sortBySize')"
|
||||
>
|
||||
<span>{{ $t("files.size") }}</span>
|
||||
<i class="material-icons">{{ sizeIcon }}</i>
|
||||
</p>
|
||||
<p
|
||||
:class="{ active: modifiedSorted }"
|
||||
class="modified"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="sort('modified')"
|
||||
:title="$t('files.sortByLastModified')"
|
||||
:aria-label="$t('files.sortByLastModified')"
|
||||
>
|
||||
<span>{{ $t("files.lastModified") }}</span>
|
||||
<i class="material-icons">{{ modifiedIcon }}</i>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 v-if="req.numDirs > 0">{{ $t("files.folders") }}</h2>
|
||||
<div v-if="req.numDirs > 0">
|
||||
<item
|
||||
v-for="item in dirs"
|
||||
:key="base64(item.name)"
|
||||
v-bind:index="item.index"
|
||||
v-bind:name="item.name"
|
||||
v-bind:isDir="item.isDir"
|
||||
v-bind:url="item.url"
|
||||
v-bind:modified="item.modified"
|
||||
v-bind:type="item.type"
|
||||
v-bind:size="item.size"
|
||||
v-bind:path="item.path"
|
||||
>
|
||||
</item>
|
||||
</div>
|
||||
|
||||
<h2 v-if="req.numFiles > 0">{{ $t("files.files") }}</h2>
|
||||
<div v-if="req.numFiles > 0">
|
||||
<item
|
||||
v-for="item in files"
|
||||
:key="base64(item.name)"
|
||||
v-bind:index="item.index"
|
||||
v-bind:name="item.name"
|
||||
v-bind:isDir="item.isDir"
|
||||
v-bind:url="item.url"
|
||||
v-bind:modified="item.modified"
|
||||
v-bind:type="item.type"
|
||||
v-bind:size="item.size"
|
||||
v-bind:path="item.path"
|
||||
>
|
||||
</item>
|
||||
</div>
|
||||
|
||||
<input
|
||||
style="display: none"
|
||||
type="file"
|
||||
id="upload-input"
|
||||
@change="uploadInput($event)"
|
||||
multiple
|
||||
/>
|
||||
<input
|
||||
style="display: none"
|
||||
type="file"
|
||||
id="upload-folder-input"
|
||||
@change="uploadInput($event)"
|
||||
webkitdirectory
|
||||
multiple
|
||||
/>
|
||||
|
||||
<div :class="{ active: $store.state.multiple }" id="multiple-selection">
|
||||
<p>{{ $t("files.multipleSelectionEnabled") }}</p>
|
||||
<div
|
||||
@click="$store.commit('multiple', false)"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
:title="$t('files.clear')"
|
||||
:aria-label="$t('files.clear')"
|
||||
class="action"
|
||||
>
|
||||
<i class="material-icons">clear</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
import { mapState, mapGetters, mapMutations } from "vuex";
|
||||
import { users, files as api } from "@/api";
|
||||
import { enableExec } from "@/utils/constants";
|
||||
import * as upload from "@/utils/upload";
|
||||
import css from "@/utils/css";
|
||||
import throttle from "lodash.throttle";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import Search from "@/components/Search.vue";
|
||||
import Item from "@/components/files/ListingItem.vue";
|
||||
|
||||
export default {
|
||||
name: "listing",
|
||||
components: {
|
||||
HeaderBar,
|
||||
Action,
|
||||
Search,
|
||||
Item,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
showLimit: 50,
|
||||
columnWidth: 280,
|
||||
dragCounter: 0,
|
||||
width: window.innerWidth,
|
||||
itemWeight: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["req", "selected", "user", "multiple", "selected", "loading"]),
|
||||
...mapGetters(["selectedCount", "currentPrompt"]),
|
||||
nameSorted() {
|
||||
return this.req.sorting.by === "name";
|
||||
},
|
||||
sizeSorted() {
|
||||
return this.req.sorting.by === "size";
|
||||
},
|
||||
modifiedSorted() {
|
||||
return this.req.sorting.by === "modified";
|
||||
},
|
||||
ascOrdered() {
|
||||
return this.req.sorting.asc;
|
||||
},
|
||||
items() {
|
||||
const dirs = [];
|
||||
const files = [];
|
||||
|
||||
this.req.items.forEach((item) => {
|
||||
if (item.isDir) {
|
||||
dirs.push(item);
|
||||
} else {
|
||||
files.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return { dirs, files };
|
||||
},
|
||||
dirs() {
|
||||
return this.items.dirs.slice(0, this.showLimit);
|
||||
},
|
||||
files() {
|
||||
let showLimit = this.showLimit - this.items.dirs.length;
|
||||
|
||||
if (showLimit < 0) showLimit = 0;
|
||||
|
||||
return this.items.files.slice(0, showLimit);
|
||||
},
|
||||
nameIcon() {
|
||||
if (this.nameSorted && !this.ascOrdered) {
|
||||
return "arrow_upward";
|
||||
}
|
||||
|
||||
return "arrow_downward";
|
||||
},
|
||||
sizeIcon() {
|
||||
if (this.sizeSorted && this.ascOrdered) {
|
||||
return "arrow_downward";
|
||||
}
|
||||
|
||||
return "arrow_upward";
|
||||
},
|
||||
modifiedIcon() {
|
||||
if (this.modifiedSorted && this.ascOrdered) {
|
||||
return "arrow_downward";
|
||||
}
|
||||
|
||||
return "arrow_upward";
|
||||
},
|
||||
viewIcon() {
|
||||
const icons = {
|
||||
list: "view_module",
|
||||
mosaic: "grid_view",
|
||||
"mosaic gallery": "view_list",
|
||||
};
|
||||
return icons[this.user.viewMode];
|
||||
},
|
||||
headerButtons() {
|
||||
return {
|
||||
upload: this.user.perm.create,
|
||||
download: this.user.perm.download,
|
||||
shell: this.user.perm.execute && enableExec,
|
||||
delete: this.selectedCount > 0 && this.user.perm.delete,
|
||||
rename: this.selectedCount === 1 && this.user.perm.rename,
|
||||
share: this.selectedCount === 1 && this.user.perm.share,
|
||||
move: this.selectedCount > 0 && this.user.perm.rename,
|
||||
copy: this.selectedCount > 0 && this.user.perm.create,
|
||||
};
|
||||
},
|
||||
isMobile() {
|
||||
return this.width <= 736;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
req: function () {
|
||||
// Reset the show value
|
||||
this.showLimit = 50;
|
||||
|
||||
// Ensures that the listing is displayed
|
||||
Vue.nextTick(() => {
|
||||
// How much every listing item affects the window height
|
||||
this.setItemWeight();
|
||||
|
||||
// Fill and fit the window with listing items
|
||||
this.fillWindow(true);
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted: function () {
|
||||
// Check the columns size for the first time.
|
||||
this.colunmsResize();
|
||||
|
||||
// How much every listing item affects the window height
|
||||
this.setItemWeight();
|
||||
|
||||
// Fill and fit the window with listing items
|
||||
this.fillWindow(true);
|
||||
|
||||
// Add the needed event listeners to the window and document.
|
||||
window.addEventListener("keydown", this.keyEvent);
|
||||
window.addEventListener("scroll", this.scrollEvent);
|
||||
window.addEventListener("resize", this.windowsResize);
|
||||
|
||||
if (!this.user.perm.create) return;
|
||||
document.addEventListener("dragover", this.preventDefault);
|
||||
document.addEventListener("dragenter", this.dragEnter);
|
||||
document.addEventListener("dragleave", this.dragLeave);
|
||||
document.addEventListener("drop", this.drop);
|
||||
},
|
||||
beforeDestroy() {
|
||||
// Remove event listeners before destroying this page.
|
||||
window.removeEventListener("keydown", this.keyEvent);
|
||||
window.removeEventListener("scroll", this.scrollEvent);
|
||||
window.removeEventListener("resize", this.windowsResize);
|
||||
|
||||
if (this.user && !this.user.perm.create) return;
|
||||
document.removeEventListener("dragover", this.preventDefault);
|
||||
document.removeEventListener("dragenter", this.dragEnter);
|
||||
document.removeEventListener("dragleave", this.dragLeave);
|
||||
document.removeEventListener("drop", this.drop);
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["updateUser", "addSelected"]),
|
||||
base64: function (name) {
|
||||
return window.btoa(unescape(encodeURIComponent(name)));
|
||||
},
|
||||
keyEvent(event) {
|
||||
// No prompts are shown
|
||||
if (this.currentPrompt !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Esc!
|
||||
if (event.keyCode === 27) {
|
||||
// Reset files selection.
|
||||
this.$store.commit("resetSelected");
|
||||
}
|
||||
|
||||
// Del!
|
||||
if (event.keyCode === 46) {
|
||||
if (!this.user.perm.delete || this.selectedCount == 0) return;
|
||||
|
||||
// Show delete prompt.
|
||||
this.$store.commit("showHover", "delete");
|
||||
}
|
||||
|
||||
// F2!
|
||||
if (event.keyCode === 113) {
|
||||
if (!this.user.perm.rename || this.selectedCount !== 1) return;
|
||||
|
||||
// Show rename prompt.
|
||||
this.$store.commit("showHover", "rename");
|
||||
}
|
||||
|
||||
// Ctrl is pressed
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
let key = String.fromCharCode(event.which).toLowerCase();
|
||||
|
||||
switch (key) {
|
||||
case "f":
|
||||
event.preventDefault();
|
||||
this.$store.commit("showHover", "search");
|
||||
break;
|
||||
case "c":
|
||||
case "x":
|
||||
this.copyCut(event, key);
|
||||
break;
|
||||
case "v":
|
||||
this.paste(event);
|
||||
break;
|
||||
case "a":
|
||||
event.preventDefault();
|
||||
for (let file of this.items.files) {
|
||||
if (this.$store.state.selected.indexOf(file.index) === -1) {
|
||||
this.addSelected(file.index);
|
||||
}
|
||||
}
|
||||
for (let dir of this.items.dirs) {
|
||||
if (this.$store.state.selected.indexOf(dir.index) === -1) {
|
||||
this.addSelected(dir.index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "s":
|
||||
event.preventDefault();
|
||||
document.getElementById("download-button").click();
|
||||
break;
|
||||
}
|
||||
},
|
||||
preventDefault(event) {
|
||||
// Wrapper around prevent default.
|
||||
event.preventDefault();
|
||||
},
|
||||
copyCut(event, key) {
|
||||
if (event.target.tagName.toLowerCase() === "input") {
|
||||
return;
|
||||
}
|
||||
|
||||
let items = [];
|
||||
|
||||
for (let i of this.selected) {
|
||||
items.push({
|
||||
from: this.req.items[i].url,
|
||||
name: this.req.items[i].name,
|
||||
});
|
||||
}
|
||||
|
||||
if (items.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$store.commit("updateClipboard", {
|
||||
key: key,
|
||||
items: items,
|
||||
path: this.$route.path,
|
||||
});
|
||||
},
|
||||
paste(event) {
|
||||
if (event.target.tagName.toLowerCase() === "input") {
|
||||
return;
|
||||
}
|
||||
|
||||
let items = [];
|
||||
|
||||
for (let item of this.$store.state.clipboard.items) {
|
||||
const from = item.from.endsWith("/")
|
||||
? item.from.slice(0, -1)
|
||||
: item.from;
|
||||
const to = this.$route.path + encodeURIComponent(item.name);
|
||||
items.push({ from, to, name: item.name });
|
||||
}
|
||||
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let action = (overwrite, rename) => {
|
||||
api
|
||||
.copy(items, overwrite, rename)
|
||||
.then(() => {
|
||||
this.$store.commit("setReload", true);
|
||||
})
|
||||
.catch(this.$showError);
|
||||
};
|
||||
|
||||
if (this.$store.state.clipboard.key === "x") {
|
||||
action = (overwrite, rename) => {
|
||||
api
|
||||
.move(items, overwrite, rename)
|
||||
.then(() => {
|
||||
this.$store.commit("resetClipboard");
|
||||
this.$store.commit("setReload", true);
|
||||
})
|
||||
.catch(this.$showError);
|
||||
};
|
||||
}
|
||||
|
||||
if (this.$store.state.clipboard.path == this.$route.path) {
|
||||
action(false, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let conflict = upload.checkConflict(items, this.req.items);
|
||||
|
||||
let overwrite = false;
|
||||
let rename = false;
|
||||
|
||||
if (conflict) {
|
||||
this.$store.commit("showHover", {
|
||||
prompt: "replace-rename",
|
||||
confirm: (event, option) => {
|
||||
overwrite = option == "overwrite";
|
||||
rename = option == "rename";
|
||||
|
||||
event.preventDefault();
|
||||
this.$store.commit("closeHovers");
|
||||
action(overwrite, rename);
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
action(overwrite, rename);
|
||||
},
|
||||
colunmsResize() {
|
||||
// Update the columns size based on the window width.
|
||||
let items = css(["#listing.mosaic .item", ".mosaic#listing .item"]);
|
||||
if (!items) return;
|
||||
|
||||
let columns = Math.floor(
|
||||
document.querySelector("main").offsetWidth / this.columnWidth
|
||||
);
|
||||
if (columns === 0) columns = 1;
|
||||
items.style.width = `calc(${100 / columns}% - 1em)`;
|
||||
},
|
||||
scrollEvent: throttle(function () {
|
||||
const totalItems = this.req.numDirs + this.req.numFiles;
|
||||
|
||||
// All items are displayed
|
||||
if (this.showLimit >= totalItems) return;
|
||||
|
||||
const currentPos = window.innerHeight + window.scrollY;
|
||||
|
||||
// Trigger at the 75% of the window height
|
||||
const triggerPos = document.body.offsetHeight - window.innerHeight * 0.25;
|
||||
|
||||
if (currentPos > triggerPos) {
|
||||
// Quantity of items needed to fill 2x of the window height
|
||||
const showQuantity = Math.ceil(
|
||||
(window.innerHeight * 2) / this.itemWeight
|
||||
);
|
||||
|
||||
// Increase the number of displayed items
|
||||
this.showLimit += showQuantity;
|
||||
}
|
||||
}, 100),
|
||||
dragEnter() {
|
||||
this.dragCounter++;
|
||||
|
||||
// When the user starts dragging an item, put every
|
||||
// file on the listing with 50% opacity.
|
||||
let items = document.getElementsByClassName("item");
|
||||
|
||||
Array.from(items).forEach((file) => {
|
||||
file.style.opacity = 0.5;
|
||||
});
|
||||
},
|
||||
dragLeave() {
|
||||
this.dragCounter--;
|
||||
|
||||
if (this.dragCounter == 0) {
|
||||
this.resetOpacity();
|
||||
}
|
||||
},
|
||||
drop: async function (event) {
|
||||
event.preventDefault();
|
||||
this.dragCounter = 0;
|
||||
this.resetOpacity();
|
||||
|
||||
let dt = event.dataTransfer;
|
||||
let el = event.target;
|
||||
|
||||
if (dt.files.length <= 0) return;
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (el !== null && !el.classList.contains("item")) {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
|
||||
let files = await upload.scanFiles(dt);
|
||||
let items = this.req.items;
|
||||
let path = this.$route.path.endsWith("/")
|
||||
? this.$route.path
|
||||
: this.$route.path + "/";
|
||||
|
||||
if (
|
||||
el !== null &&
|
||||
el.classList.contains("item") &&
|
||||
el.dataset.dir === "true"
|
||||
) {
|
||||
// Get url from ListingItem instance
|
||||
path = el.__vue__.url;
|
||||
|
||||
try {
|
||||
items = (await api.fetch(path)).items;
|
||||
} catch (error) {
|
||||
this.$showError(error);
|
||||
}
|
||||
}
|
||||
|
||||
let conflict = upload.checkConflict(files, items);
|
||||
|
||||
if (conflict) {
|
||||
this.$store.commit("showHover", {
|
||||
prompt: "replace",
|
||||
action: (event) => {
|
||||
event.preventDefault();
|
||||
this.$store.commit("closeHovers");
|
||||
upload.handleFiles(files, path, false);
|
||||
},
|
||||
confirm: (event) => {
|
||||
event.preventDefault();
|
||||
this.$store.commit("closeHovers");
|
||||
upload.handleFiles(files, path, true);
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
upload.handleFiles(files, path);
|
||||
},
|
||||
uploadInput(event) {
|
||||
this.$store.commit("closeHovers");
|
||||
|
||||
let files = event.currentTarget.files;
|
||||
let folder_upload =
|
||||
files[0].webkitRelativePath !== undefined &&
|
||||
files[0].webkitRelativePath !== "";
|
||||
|
||||
if (folder_upload) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i];
|
||||
files[i].fullPath = file.webkitRelativePath;
|
||||
}
|
||||
}
|
||||
|
||||
let path = this.$route.path.endsWith("/")
|
||||
? this.$route.path
|
||||
: this.$route.path + "/";
|
||||
let conflict = upload.checkConflict(files, this.req.items);
|
||||
|
||||
if (conflict) {
|
||||
this.$store.commit("showHover", {
|
||||
prompt: "replace",
|
||||
action: (event) => {
|
||||
event.preventDefault();
|
||||
this.$store.commit("closeHovers");
|
||||
upload.handleFiles(files, path, false);
|
||||
},
|
||||
confirm: (event) => {
|
||||
event.preventDefault();
|
||||
this.$store.commit("closeHovers");
|
||||
upload.handleFiles(files, path, true);
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
upload.handleFiles(files, path);
|
||||
},
|
||||
resetOpacity() {
|
||||
let items = document.getElementsByClassName("item");
|
||||
|
||||
Array.from(items).forEach((file) => {
|
||||
file.style.opacity = 1;
|
||||
});
|
||||
},
|
||||
async sort(by) {
|
||||
let asc = false;
|
||||
|
||||
if (by === "name") {
|
||||
if (this.nameIcon === "arrow_upward") {
|
||||
asc = true;
|
||||
}
|
||||
} else if (by === "size") {
|
||||
if (this.sizeIcon === "arrow_upward") {
|
||||
asc = true;
|
||||
}
|
||||
} else if (by === "modified") {
|
||||
if (this.modifiedIcon === "arrow_upward") {
|
||||
asc = true;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await users.update({ id: this.user.id, sorting: { by, asc } }, [
|
||||
"sorting",
|
||||
]);
|
||||
} catch (e) {
|
||||
this.$showError(e);
|
||||
}
|
||||
|
||||
this.$store.commit("setReload", true);
|
||||
},
|
||||
openSearch() {
|
||||
this.$store.commit("showHover", "search");
|
||||
},
|
||||
toggleMultipleSelection() {
|
||||
this.$store.commit("multiple", !this.multiple);
|
||||
this.$store.commit("closeHovers");
|
||||
},
|
||||
windowsResize: throttle(function () {
|
||||
this.colunmsResize();
|
||||
this.width = window.innerWidth;
|
||||
|
||||
// Listing element is not displayed
|
||||
if (this.$refs.listing == null) return;
|
||||
|
||||
// How much every listing item affects the window height
|
||||
this.setItemWeight();
|
||||
|
||||
// Fill but not fit the window
|
||||
this.fillWindow();
|
||||
}, 100),
|
||||
download() {
|
||||
if (this.selectedCount === 1 && !this.req.items[this.selected[0]].isDir) {
|
||||
api.download(null, this.req.items[this.selected[0]].url);
|
||||
return;
|
||||
}
|
||||
|
||||
this.$store.commit("showHover", {
|
||||
prompt: "download",
|
||||
confirm: (format) => {
|
||||
this.$store.commit("closeHovers");
|
||||
|
||||
let files = [];
|
||||
|
||||
if (this.selectedCount > 0) {
|
||||
for (let i of this.selected) {
|
||||
files.push(this.req.items[i].url);
|
||||
}
|
||||
} else {
|
||||
files.push(this.$route.path);
|
||||
}
|
||||
|
||||
api.download(format, ...files);
|
||||
},
|
||||
});
|
||||
},
|
||||
switchView: async function () {
|
||||
this.$store.commit("closeHovers");
|
||||
|
||||
const modes = {
|
||||
list: "mosaic",
|
||||
mosaic: "mosaic gallery",
|
||||
"mosaic gallery": "list",
|
||||
};
|
||||
|
||||
const data = {
|
||||
id: this.user.id,
|
||||
viewMode: modes[this.user.viewMode] || "list",
|
||||
};
|
||||
|
||||
users.update(data, ["viewMode"]).catch(this.$showError);
|
||||
|
||||
// Await ensures correct value for setItemWeight()
|
||||
await this.$store.commit("updateUser", data);
|
||||
|
||||
this.setItemWeight();
|
||||
this.fillWindow();
|
||||
},
|
||||
upload: function () {
|
||||
if (
|
||||
typeof window.DataTransferItem !== "undefined" &&
|
||||
typeof DataTransferItem.prototype.webkitGetAsEntry !== "undefined"
|
||||
) {
|
||||
this.$store.commit("showHover", "upload");
|
||||
} else {
|
||||
document.getElementById("upload-input").click();
|
||||
}
|
||||
},
|
||||
setItemWeight() {
|
||||
// Listing element is not displayed
|
||||
if (this.$refs.listing == null) return;
|
||||
|
||||
let itemQuantity = this.req.numDirs + this.req.numFiles;
|
||||
if (itemQuantity > this.showLimit) itemQuantity = this.showLimit;
|
||||
|
||||
// How much every listing item affects the window height
|
||||
this.itemWeight = this.$refs.listing.offsetHeight / itemQuantity;
|
||||
},
|
||||
fillWindow(fit = false) {
|
||||
const totalItems = this.req.numDirs + this.req.numFiles;
|
||||
|
||||
// More items are displayed than the total
|
||||
if (this.showLimit >= totalItems && !fit) return;
|
||||
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
// Quantity of items needed to fill 2x of the window height
|
||||
const showQuantity = Math.ceil(
|
||||
(windowHeight + windowHeight * 2) / this.itemWeight
|
||||
);
|
||||
|
||||
// Less items to display than current
|
||||
if (this.showLimit > showQuantity && !fit) return;
|
||||
|
||||
// Set the number of displayed items
|
||||
this.showLimit = showQuantity > totalItems ? totalItems : showQuantity;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -1,46 +1,34 @@
|
||||
<template>
|
||||
<div
|
||||
id="previewer"
|
||||
@touchmove.prevent.stop
|
||||
@wheel.prevent.stop
|
||||
@mousemove="toggleNavigation"
|
||||
@touchstart="toggleNavigation"
|
||||
>
|
||||
<header-bar v-if="showNav">
|
||||
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||
<header-bar>
|
||||
<action :label="$t('buttons.close')" @action="close()" />
|
||||
<title>{{ name }}</title>
|
||||
<action
|
||||
:disabled="layoutStore.loading"
|
||||
v-if="isResizeEnabled && fileStore.req?.type === 'image'"
|
||||
:icon="fullSize ? 'photo_size_select_large' : 'hd'"
|
||||
@action="toggleSize"
|
||||
/>
|
||||
|
||||
<template #actions>
|
||||
<action
|
||||
:disabled="layoutStore.loading"
|
||||
v-if="authStore.user?.perm.rename"
|
||||
icon="mode_edit"
|
||||
:disabled="loading"
|
||||
v-if="user.perm.rename"
|
||||
:label="$t('buttons.rename')"
|
||||
show="rename"
|
||||
/>
|
||||
<action
|
||||
:disabled="layoutStore.loading"
|
||||
v-if="authStore.user?.perm.delete"
|
||||
icon="delete"
|
||||
:disabled="loading"
|
||||
v-if="user.perm.delete"
|
||||
:label="$t('buttons.delete')"
|
||||
@action="deleteFile"
|
||||
id="delete-button"
|
||||
/>
|
||||
<action
|
||||
:disabled="layoutStore.loading"
|
||||
v-if="authStore.user?.perm.download"
|
||||
icon="file_download"
|
||||
:disabled="loading"
|
||||
v-if="user.perm.download"
|
||||
:label="$t('buttons.download')"
|
||||
@action="download"
|
||||
/>
|
||||
<action
|
||||
:disabled="layoutStore.loading"
|
||||
:disabled="loading"
|
||||
icon="info"
|
||||
:label="$t('buttons.info')"
|
||||
show="info"
|
||||
@ -48,7 +36,7 @@
|
||||
</template>
|
||||
</header-bar>
|
||||
|
||||
<div class="loading delayed" v-if="layoutStore.loading">
|
||||
<div class="loading delayed" v-if="loading">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
@ -57,29 +45,41 @@
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="preview">
|
||||
<ExtendedImage v-if="fileStore.req?.type == 'image'" :src="raw" />
|
||||
<ExtendedImage v-if="req.type == 'image'" :src="raw"></ExtendedImage>
|
||||
<audio
|
||||
v-else-if="fileStore.req?.type == 'audio'"
|
||||
v-else-if="req.type == 'audio'"
|
||||
ref="player"
|
||||
:src="raw"
|
||||
controls
|
||||
:autoplay="autoPlay"
|
||||
@play="autoPlay = true"
|
||||
></audio>
|
||||
<VideoPlayer
|
||||
v-else-if="fileStore.req?.type == 'video'"
|
||||
<video
|
||||
v-else-if="req.type == 'video'"
|
||||
ref="player"
|
||||
:source="raw"
|
||||
:subtitles="subtitles"
|
||||
:options="videoOptions"
|
||||
:src="raw"
|
||||
controls
|
||||
:autoplay="autoPlay"
|
||||
@play="autoPlay = true"
|
||||
>
|
||||
</VideoPlayer>
|
||||
<track
|
||||
kind="captions"
|
||||
v-for="(sub, index) in subtitles"
|
||||
:key="index"
|
||||
:src="sub"
|
||||
:label="'Subtitle ' + index"
|
||||
:default="index === 0"
|
||||
/>
|
||||
Sorry, your browser doesn't support embedded videos, but don't worry,
|
||||
you can <a :href="downloadUrl">download it</a>
|
||||
and watch it with your favorite video player!
|
||||
</video>
|
||||
<object
|
||||
v-else-if="fileStore.req?.extension.toLowerCase() == '.pdf'"
|
||||
v-else-if="req.extension.toLowerCase() == '.pdf'"
|
||||
class="pdf"
|
||||
:data="raw"
|
||||
></object>
|
||||
<div v-else-if="fileStore.req?.type == 'blob'" class="info">
|
||||
<div v-else-if="req.type == 'blob'" class="info">
|
||||
<div class="title">
|
||||
<i class="material-icons">feedback</i>
|
||||
{{ $t("files.noPreview") }}
|
||||
@ -91,17 +91,6 @@
|
||||
>{{ $t("buttons.download") }}
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
target="_blank"
|
||||
:href="raw"
|
||||
class="button button--flat"
|
||||
v-if="!fileStore.req?.isDir"
|
||||
>
|
||||
<div>
|
||||
<i class="material-icons">open_in_new</i
|
||||
>{{ $t("buttons.openFile") }}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -132,215 +121,214 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { useFileStore } from "@/stores/file";
|
||||
import { useLayoutStore } from "@/stores/layout";
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapState } from "vuex";
|
||||
import { files as api } from "@/api";
|
||||
import { resizePreview } from "@/utils/constants";
|
||||
import url from "@/utils/url";
|
||||
import throttle from "lodash/throttle";
|
||||
import throttle from "lodash.throttle";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import ExtendedImage from "@/components/files/ExtendedImage.vue";
|
||||
import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import VideoPlayer from "@/components/files/VideoPlayer.vue";
|
||||
|
||||
const mediaTypes: ResourceType[] = ["image", "video", "audio", "blob"];
|
||||
const mediaTypes = ["image", "video", "audio", "blob"];
|
||||
|
||||
const previousLink = ref<string>("");
|
||||
const nextLink = ref<string>("");
|
||||
const listing = ref<ResourceItem[] | null>(null);
|
||||
const name = ref<string>("");
|
||||
const fullSize = ref<boolean>(false);
|
||||
const showNav = ref<boolean>(true);
|
||||
const navTimeout = ref<null | number>(null);
|
||||
const hoverNav = ref<boolean>(false);
|
||||
const autoPlay = ref<boolean>(false);
|
||||
const previousRaw = ref<string>("");
|
||||
const nextRaw = ref<string>("");
|
||||
export default {
|
||||
name: "preview",
|
||||
components: {
|
||||
HeaderBar,
|
||||
Action,
|
||||
ExtendedImage,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
previousLink: "",
|
||||
nextLink: "",
|
||||
listing: null,
|
||||
name: "",
|
||||
fullSize: false,
|
||||
showNav: true,
|
||||
navTimeout: null,
|
||||
hoverNav: false,
|
||||
autoPlay: false,
|
||||
previousRaw: "",
|
||||
nextRaw: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["req", "user", "oldReq", "jwt", "loading"]),
|
||||
...mapGetters(["currentPrompt"]),
|
||||
hasPrevious() {
|
||||
return this.previousLink !== "";
|
||||
},
|
||||
hasNext() {
|
||||
return this.nextLink !== "";
|
||||
},
|
||||
downloadUrl() {
|
||||
return api.getDownloadURL(this.req);
|
||||
},
|
||||
raw() {
|
||||
if (this.req.type === "image" && !this.fullSize) {
|
||||
return api.getPreviewURL(this.req, "big");
|
||||
}
|
||||
|
||||
const player = ref<HTMLVideoElement | HTMLAudioElement | null>(null);
|
||||
return api.getDownloadURL(this.req, true);
|
||||
},
|
||||
showMore() {
|
||||
return this.currentPrompt?.prompt === "more";
|
||||
},
|
||||
isResizeEnabled() {
|
||||
return resizePreview;
|
||||
},
|
||||
subtitles() {
|
||||
if (this.req.subtitles) {
|
||||
return api.getSubtitlesURL(this.req);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route: function () {
|
||||
this.updatePreview();
|
||||
this.toggleNavigation();
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
window.addEventListener("keydown", this.key);
|
||||
this.listing = this.oldReq.items;
|
||||
this.updatePreview();
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("keydown", this.key);
|
||||
},
|
||||
methods: {
|
||||
deleteFile() {
|
||||
this.$store.commit("showHover", {
|
||||
prompt: "delete",
|
||||
confirm: () => {
|
||||
this.listing = this.listing.filter((item) => item.name !== this.name);
|
||||
|
||||
const $showError = inject<IToastError>("$showError")!;
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const fileStore = useFileStore();
|
||||
const layoutStore = useLayoutStore();
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const hasPrevious = computed(() => previousLink.value !== "");
|
||||
|
||||
const hasNext = computed(() => nextLink.value !== "");
|
||||
|
||||
const downloadUrl = computed(() =>
|
||||
fileStore.req ? api.getDownloadURL(fileStore.req, true) : ""
|
||||
);
|
||||
|
||||
const raw = computed(() => {
|
||||
if (fileStore.req?.type === "image" && !fullSize.value) {
|
||||
return api.getPreviewURL(fileStore.req, "big");
|
||||
}
|
||||
|
||||
return downloadUrl.value;
|
||||
});
|
||||
|
||||
const isResizeEnabled = computed(() => resizePreview);
|
||||
|
||||
const subtitles = computed(() => {
|
||||
if (fileStore.req?.subtitles) {
|
||||
return api.getSubtitlesURL(fileStore.req);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
const videoOptions = computed(() => {
|
||||
return { autoplay: autoPlay.value };
|
||||
});
|
||||
|
||||
watch(route, () => {
|
||||
updatePreview();
|
||||
toggleNavigation();
|
||||
});
|
||||
|
||||
// Specify hooks
|
||||
onMounted(async () => {
|
||||
window.addEventListener("keydown", key);
|
||||
if (fileStore.oldReq) {
|
||||
listing.value = fileStore.oldReq.items;
|
||||
updatePreview();
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => window.removeEventListener("keydown", key));
|
||||
|
||||
// Specify methods
|
||||
const deleteFile = () => {
|
||||
layoutStore.showHover({
|
||||
prompt: "delete",
|
||||
confirm: () => {
|
||||
if (listing.value === null) {
|
||||
if (this.hasNext) {
|
||||
this.next();
|
||||
} else if (!this.hasPrevious && !this.hasNext) {
|
||||
this.close();
|
||||
} else {
|
||||
this.prev();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
prev() {
|
||||
this.hoverNav = false;
|
||||
this.$router.replace({ path: this.previousLink });
|
||||
},
|
||||
next() {
|
||||
this.hoverNav = false;
|
||||
this.$router.replace({ path: this.nextLink });
|
||||
},
|
||||
key(event) {
|
||||
if (this.currentPrompt !== null) {
|
||||
return;
|
||||
}
|
||||
listing.value = listing.value.filter((item) => item.name !== name.value);
|
||||
|
||||
if (hasNext.value) {
|
||||
next();
|
||||
} else if (!hasPrevious.value && !hasNext.value) {
|
||||
close();
|
||||
} else {
|
||||
prev();
|
||||
if (event.which === 13 || event.which === 39) {
|
||||
// right arrow
|
||||
if (this.hasNext) this.next();
|
||||
} else if (event.which === 37) {
|
||||
// left arrow
|
||||
if (this.hasPrevious) this.prev();
|
||||
} else if (event.which === 27) {
|
||||
// esc
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const prev = () => {
|
||||
hoverNav.value = false;
|
||||
router.replace({ path: previousLink.value });
|
||||
};
|
||||
|
||||
const next = () => {
|
||||
hoverNav.value = false;
|
||||
router.replace({ path: nextLink.value });
|
||||
};
|
||||
|
||||
const key = (event: KeyboardEvent) => {
|
||||
if (layoutStore.currentPrompt !== null) {
|
||||
return;
|
||||
}
|
||||
if (event.which === 13 || event.which === 39) {
|
||||
// right arrow
|
||||
if (hasNext.value) next();
|
||||
} else if (event.which === 37) {
|
||||
// left arrow
|
||||
if (hasPrevious.value) prev();
|
||||
} else if (event.which === 27) {
|
||||
// esc
|
||||
close();
|
||||
}
|
||||
};
|
||||
const updatePreview = async () => {
|
||||
if (player.value && player.value.paused && !player.value.ended) {
|
||||
autoPlay.value = false;
|
||||
}
|
||||
|
||||
let dirs = route.fullPath.split("/");
|
||||
name.value = decodeURIComponent(dirs[dirs.length - 1]);
|
||||
|
||||
if (!listing.value) {
|
||||
try {
|
||||
const path = url.removeLastDir(route.path);
|
||||
const res = await api.fetch(path);
|
||||
listing.value = res.items;
|
||||
} catch (e: any) {
|
||||
$showError(e);
|
||||
}
|
||||
}
|
||||
|
||||
previousLink.value = "";
|
||||
nextLink.value = "";
|
||||
if (listing.value) {
|
||||
for (let i = 0; i < listing.value.length; i++) {
|
||||
if (listing.value[i].name !== name.value) {
|
||||
continue;
|
||||
async updatePreview() {
|
||||
if (
|
||||
this.$refs.player &&
|
||||
this.$refs.player.paused &&
|
||||
!this.$refs.player.ended
|
||||
) {
|
||||
this.autoPlay = false;
|
||||
}
|
||||
|
||||
for (let j = i - 1; j >= 0; j--) {
|
||||
if (mediaTypes.includes(listing.value[j].type)) {
|
||||
previousLink.value = listing.value[j].url;
|
||||
previousRaw.value = prefetchUrl(listing.value[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let j = i + 1; j < listing.value.length; j++) {
|
||||
if (mediaTypes.includes(listing.value[j].type)) {
|
||||
nextLink.value = listing.value[j].url;
|
||||
nextRaw.value = prefetchUrl(listing.value[j]);
|
||||
break;
|
||||
let dirs = this.$route.fullPath.split("/");
|
||||
this.name = decodeURIComponent(dirs[dirs.length - 1]);
|
||||
|
||||
if (!this.listing) {
|
||||
try {
|
||||
const path = url.removeLastDir(this.$route.path);
|
||||
const res = await api.fetch(path);
|
||||
this.listing = res.items;
|
||||
} catch (e) {
|
||||
this.$showError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.previousLink = "";
|
||||
this.nextLink = "";
|
||||
|
||||
for (let i = 0; i < this.listing.length; i++) {
|
||||
if (this.listing[i].name !== this.name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let j = i - 1; j >= 0; j--) {
|
||||
if (mediaTypes.includes(this.listing[j].type)) {
|
||||
this.previousLink = this.listing[j].url;
|
||||
this.previousRaw = this.prefetchUrl(this.listing[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let j = i + 1; j < this.listing.length; j++) {
|
||||
if (mediaTypes.includes(this.listing[j].type)) {
|
||||
this.nextLink = this.listing[j].url;
|
||||
this.nextRaw = this.prefetchUrl(this.listing[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
},
|
||||
prefetchUrl(item) {
|
||||
if (item.type !== "image") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.fullSize
|
||||
? api.getDownloadURL(item, true)
|
||||
: api.getPreviewURL(item, "big");
|
||||
},
|
||||
openMore() {
|
||||
this.$store.commit("showHover", "more");
|
||||
},
|
||||
resetPrompts() {
|
||||
this.$store.commit("closeHovers");
|
||||
},
|
||||
toggleSize() {
|
||||
this.fullSize = !this.fullSize;
|
||||
},
|
||||
toggleNavigation: throttle(function () {
|
||||
this.showNav = true;
|
||||
|
||||
if (this.navTimeout) {
|
||||
clearTimeout(this.navTimeout);
|
||||
}
|
||||
|
||||
this.navTimeout = setTimeout(() => {
|
||||
this.showNav = false || this.hoverNav;
|
||||
this.navTimeout = null;
|
||||
}, 1500);
|
||||
}, 500),
|
||||
close() {
|
||||
this.$store.commit("updateRequest", {});
|
||||
|
||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
||||
this.$router.push({ path: uri });
|
||||
},
|
||||
download() {
|
||||
window.open(this.downloadUrl);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const prefetchUrl = (item: ResourceItem) => {
|
||||
if (item.type !== "image") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return fullSize.value
|
||||
? api.getDownloadURL(item, true)
|
||||
: api.getPreviewURL(item, "big");
|
||||
};
|
||||
|
||||
const toggleSize = () => (fullSize.value = !fullSize.value);
|
||||
|
||||
const toggleNavigation = throttle(function () {
|
||||
showNav.value = true;
|
||||
|
||||
if (navTimeout.value) {
|
||||
clearTimeout(navTimeout.value);
|
||||
}
|
||||
|
||||
navTimeout.value = setTimeout(() => {
|
||||
showNav.value = false || hoverNav.value;
|
||||
navTimeout.value = null;
|
||||
}, 1500);
|
||||
}, 500);
|
||||
|
||||
const close = () => {
|
||||
fileStore.updateRequest(null);
|
||||
|
||||
let uri = url.removeLastDir(route.path) + "/";
|
||||
router.push({ path: uri });
|
||||
};
|
||||
|
||||
const download = () => window.open(downloadUrl.value);
|
||||
</script>
|
||||
|
||||
70
frontend/vite.config.js
Normal file
70
frontend/vite.config.js
Normal file
@ -0,0 +1,70 @@
|
||||
import { fileURLToPath, URL } from "node:url";
|
||||
import path from "node:path";
|
||||
import { defineConfig } from "vite";
|
||||
import legacy from "@vitejs/plugin-legacy";
|
||||
import vue2 from "@vitejs/plugin-vue2";
|
||||
import { compression } from "vite-plugin-compression2";
|
||||
import pluginRewriteAll from "vite-plugin-rewrite-all";
|
||||
|
||||
const plugins = [
|
||||
vue2(),
|
||||
legacy({
|
||||
targets: ["ie >= 11"],
|
||||
additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
|
||||
}),
|
||||
compression({ include: /\.js$/i, deleteOriginalAssets: true }),
|
||||
pluginRewriteAll(), // fixes 404 error with paths containing dot in dev server
|
||||
];
|
||||
|
||||
const resolve = {
|
||||
alias: {
|
||||
vue: "vue/dist/vue.esm.js",
|
||||
"@/": `${path.resolve(__dirname, "src")}/`,
|
||||
},
|
||||
};
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command }) => {
|
||||
if (command === "serve") {
|
||||
return {
|
||||
plugins,
|
||||
resolve,
|
||||
server: {
|
||||
proxy: {
|
||||
"/api/command": {
|
||||
target: "ws://127.0.0.1:8080",
|
||||
ws: true,
|
||||
},
|
||||
"/api": "http://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// command === 'build'
|
||||
return {
|
||||
plugins,
|
||||
resolve,
|
||||
base: "",
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
index: fileURLToPath(
|
||||
new URL(`./public/index.html`, import.meta.url)
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
experimental: {
|
||||
renderBuiltUrl(filename, { hostType }) {
|
||||
if (hostType === "js") {
|
||||
return { runtime: `window.__prependStaticUrl("${filename}")` };
|
||||
} else if (hostType === "html") {
|
||||
return `[{[ .StaticURL ]}]/${filename}`;
|
||||
} else {
|
||||
return { relative: true };
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user