Graphical overhaul.
Remove all legacy pixeldrain pages, handlers and assets. Remove old theming engine. Make logo responsive to the accent colour. Lots of other stuff.
@@ -1,4 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<title>GitHub</title>
|
||||
<path fill="#ffffff" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 866 B |
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 216.4144 232.00976">
|
||||
<path fill="#ffffff" d="M211.80734 139.0875c-3.18125 16.36625-28.4925 34.2775-57.5625 37.74875-15.15875 1.80875-30.08375 3.47125-45.99875 2.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125 0 2.53375.15625 4.94625.46875 7.2025 3.38375 25.68625 25.47 27.225 46.39125 27.9425 21.11625.7225 39.91875-5.20625 39.91875-5.20625l.8675 19.09s-14.77 7.93125-41.08125 9.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23234 213.82 1.40609 165.31125.20859 116.09125c-.365-14.61375-.14-28.39375-.14-39.91875 0-50.33 32.97625-65.0825 32.97625-65.0825C49.67234 3.45375 78.20359.2425 107.86484 0h.72875c29.66125.2425 58.21125 3.45375 74.8375 11.09 0 0 32.975 14.7525 32.975 65.0825 0 0 .41375 37.13375-4.59875 62.915"/>
|
||||
<path fill="#000000" d="M177.50984 80.077v60.94125h-24.14375v-59.15c0-12.46875-5.24625-18.7975-15.74-18.7975-11.6025 0-17.4175 7.5075-17.4175 22.3525v32.37625H96.20734V85.42325c0-14.845-5.81625-22.3525-17.41875-22.3525-10.49375 0-15.74 6.32875-15.74 18.7975v59.15H38.90484V80.077c0-12.455 3.17125-22.3525 9.54125-29.675 6.56875-7.3225 15.17125-11.07625 25.85-11.07625 12.355 0 21.71125 4.74875 27.8975 14.2475l6.01375 10.08125 6.015-10.08125c6.185-9.49875 15.54125-14.2475 27.8975-14.2475 10.6775 0 19.28 3.75375 25.85 11.07625 6.36875 7.3225 9.54 17.22 9.54 29.675"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 100 100">
|
||||
<g fill="#ffffff" fill-rule="evenodd">
|
||||
<path d="M64.1102,0.1004 C44.259,0.1004 28.1086,16.2486 28.1086,36.0986 C28.1086,55.8884 44.259,71.989 64.1102,71.989 C83.9,71.989 100,55.8884 100,36.0986 C100,16.2486 83.9,0.1004 64.1102,0.1004"/>
|
||||
<polygon points=".012 95.988 17.59 95.988 17.59 .1 .012 .1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 409 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M22,12.14C22,10.92 21,9.96 19.81,9.96C19.22,9.96 18.68,10.19 18.29,10.57C16.79,9.5 14.72,8.79 12.43,8.7L13.43,4L16.7,4.71C16.73,5.53 17.41,6.19 18.25,6.19C19.11,6.19 19.81,5.5 19.81,4.63C19.81,3.77 19.11,3.08 18.25,3.08C17.65,3.08 17.11,3.43 16.86,3.95L13.22,3.18C13.11,3.16 13,3.18 12.93,3.24C12.84,3.29 12.79,3.38 12.77,3.5L11.66,8.72C9.33,8.79 7.23,9.5 5.71,10.58C5.32,10.21 4.78,10 4.19,10C2.97,10 2,10.96 2,12.16C2,13.06 2.54,13.81 3.29,14.15C3.25,14.37 3.24,14.58 3.24,14.81C3.24,18.18 7.16,20.93 12,20.93C16.84,20.93 20.76,18.2 20.76,14.81C20.76,14.6 20.75,14.37 20.71,14.15C21.46,13.81 22,13.04 22,12.14M7,13.7C7,12.84 7.68,12.14 8.54,12.14C9.4,12.14 10.1,12.84 10.1,13.7A1.56,1.56 0 0,1 8.54,15.26C7.68,15.28 7,14.56 7,13.7M15.71,17.84C14.63,18.92 12.59,19 12,19C11.39,19 9.35,18.9 8.29,17.84C8.13,17.68 8.13,17.43 8.29,17.27C8.45,17.11 8.7,17.11 8.86,17.27C9.54,17.95 11,18.18 12,18.18C13,18.18 14.47,17.95 15.14,17.27C15.3,17.11 15.55,17.11 15.71,17.27C15.85,17.43 15.85,17.68 15.71,17.84M15.42,15.28C14.56,15.28 13.86,14.58 13.86,13.72A1.56,1.56 0 0,1 15.42,12.16C16.28,12.16 17,12.86 17,13.72C17,14.56 16.28,15.28 15.42,15.28Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M22.46,6C21.69,6.35 20.86,6.58 20,6.69C20.88,6.16 21.56,5.32 21.88,4.31C21.05,4.81 20.13,5.16 19.16,5.36C18.37,4.5 17.26,4 16,4C13.65,4 11.73,5.92 11.73,8.29C11.73,8.63 11.77,8.96 11.84,9.27C8.28,9.09 5.11,7.38 3,4.79C2.63,5.42 2.42,6.16 2.42,6.94C2.42,8.43 3.17,9.75 4.33,10.5C3.62,10.5 2.96,10.3 2.38,10C2.38,10 2.38,10 2.38,10.03C2.38,12.11 3.86,13.85 5.82,14.24C5.46,14.34 5.08,14.39 4.69,14.39C4.42,14.39 4.15,14.36 3.89,14.31C4.43,16 6,17.26 7.89,17.29C6.43,18.45 4.58,19.13 2.56,19.13C2.22,19.13 1.88,19.11 1.54,19.07C3.44,20.29 5.7,21 8.12,21C16,21 20.33,14.46 20.33,8.79C20.33,8.6 20.33,8.42 20.32,8.23C21.16,7.63 21.88,6.87 22.46,6Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 777 B |
@@ -1,61 +0,0 @@
|
||||
# API documentation
|
||||
|
||||
Methods for using Nova programmatically.
|
||||
|
||||
## Authentication
|
||||
|
||||
All methods which create, modify or delete a resource require an API key. API
|
||||
keys can be obtained from your user account's [API keys page](/user/api_keys).
|
||||
|
||||
To use the API key you need to enter it in the password field of [HTTP Basic
|
||||
Access
|
||||
Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). The
|
||||
username field does not matter, it can be empty or anything else.
|
||||
|
||||
Example usage in JavaScript:
|
||||
|
||||
```js
|
||||
const resp = await fetch(
|
||||
"https://nova.storage/api/user/files",
|
||||
headers: {
|
||||
"Authorization": "Basic "+btoa(":"+api_key),
|
||||
// The btoa function encodes the key to Base64
|
||||
},
|
||||
)
|
||||
if(resp.status >= 400) {
|
||||
throw new Error(await resp.json())
|
||||
}
|
||||
result = await resp.json()
|
||||
```
|
||||
|
||||
Some JSON responses include fields which end in "_href" (some people don't know
|
||||
this, but "href" stands for "Hypertext Reference", the more you know). These
|
||||
point to different places in the API, which you can retrieve with a GET request.
|
||||
The path is to be appended to the API URL, so "/file/someid/thumbnail" becomes
|
||||
"{{apiUrl}}/file/someid/thumbnail".
|
||||
|
||||
The base URL for the API is "{{apiUrl}}", all paths below are relative to that
|
||||
URL.
|
||||
|
||||
## curl example
|
||||
|
||||
To upload files to Nova you will need an API key. Get an API key from the
|
||||
[API keys page](/user/api_keys) and enter it in the command. Replace the example
|
||||
API key here with your own:
|
||||
|
||||
`curl -T "file_name.txt" -u :5f45f184-64bb-4eaa-be19-4a5f0459db49
|
||||
https://nova.storage/api/file/`
|
||||
|
||||
## Form value order
|
||||
|
||||
I recommend you put files at the end of every file upload form. By doing this
|
||||
the Nova server can respond to malformed requests before the file upload
|
||||
finishes and this may save you a lot of time and bandwidth when uploading large
|
||||
files. Make sure your HTTP client has support for premature responses,
|
||||
Nova uses them a lot. If the server responds before your request is
|
||||
finished it will always indicate an error and you may abort the connection.
|
||||
|
||||
|
||||
{{template "api_file.md"}}
|
||||
{{template "api_list.md"}}
|
||||
{{template "api_user.md"}}
|
||||
@@ -1,350 +0,0 @@
|
||||
## File Methods
|
||||
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/file</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Upload a file. I recommend that you use the PUT API instead of the POST API.
|
||||
It's easier to use and the multipart encoding of the POST API can cause
|
||||
performance issues in certain environments.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Type | Required | Maximum Size | Default | Description
|
||||
------|----------------|----------|------------------------------|---------------------|----------------------------
|
||||
name | string | false | 255 characters | multipart file name | Name of the file to upload
|
||||
file | multipart file | true | Depends on user subscription | none | File to upload
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 422: Unprocessable Entity
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "no_file",
|
||||
"message": "The file does not exist or is empty."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 500: Internal Server Error
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "internal",
|
||||
"message": "An internal server error occurred."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload Too Large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_too_large",
|
||||
"message": "The file you tried to upload is too large"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 500: Internal Server Error
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "writing",
|
||||
"message": "Something went wrong while writing the file to disk, the server may be out of storage space."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload Too Large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "name_too_long",
|
||||
"message": "File Name is too long, Max 255 characters allowed."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_put">
|
||||
<summary><span class="method">PUT</span>/file/{name}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Upload a file.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Type | Required | Location | Maximum Size | Default | Description
|
||||
------|--------|----------|--------------|------------------------------|---------|----------------------------
|
||||
name | string | true | URL | 255 characters | none | Name of the file to upload
|
||||
file | file | true | request body | Depends on user subscription | none | File to upload
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 201: OK
|
||||
```
|
||||
{
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 422: Unprocessable Entity
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "no_file",
|
||||
"message": "The file does not exist or is empty."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 500: Internal Server Error
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "internal",
|
||||
"message": "An internal server error occurred."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload Too Large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_too_large",
|
||||
"message": "The file you tried to upload is too large"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 500: Internal Server Error
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "writing",
|
||||
"message": "Something went wrong while writing the file to disk, the server may be out of storage space."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload Too Large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "name_too_long",
|
||||
"message": "File Name is too long, Max 255 characters allowed."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns the full file associated with the ID. Supports byte range requests.
|
||||
|
||||
When '?download' is added to the URL the server will send an attachment header
|
||||
instead of inline rendering, which causes the browser to show a 'Save File'
|
||||
dialog.
|
||||
|
||||
Warning: If a file is using too much bandwidth it can be rate limited. The rate
|
||||
limit will be enabled if a file has three times more downloads than views. The
|
||||
owner of a file can always download it. When a file is rate limited the user
|
||||
will need to fill out a captcha in order to continue downloading the file. The
|
||||
captcha will only appear on the file viewer page (nova.storage/u/{id}). Rate
|
||||
limiting has been added to prevent the spread of viruses and to stop hotlinking.
|
||||
Hotlinking is only allowed when files are uploaded using a Pro account.
|
||||
|
||||
Nova also includes a virus scanner. If a virus has been detected in a file
|
||||
the user will also have to fill in a captcha to download it.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
---------|----------|----------|------------------------------------------
|
||||
id | true | URL | ID of the file to request
|
||||
download | false | URL | Sends attachment header instead of inline
|
||||
|
||||
### Returns
|
||||
|
||||
```
|
||||
HTTP 200: OK
|
||||
|
||||
Requested file data
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "not_found",
|
||||
"message": "The entity you requested could not be found"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 403: Forbidden
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_rate_limited_captcha_required",
|
||||
"message": "This file is using too much bandwidth. For anonymous downloads a captcha is required now. The captcha entry is available on the download page"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 403: Forbidden
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "virus_detected_captcha_required",
|
||||
"message": "This file has been marked as malware by our scanning systems. To avoid infecting other systems through automated downloads we require you to enter a captcha. The captcha entry is available on the download page"
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/info</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns information about one or more files. You can also put a comma separated
|
||||
list of file IDs in the URL and it will return an array of file info, instead of
|
||||
a single object. There's a limit of 1000 files per request.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|---------------
|
||||
id | true | URL | ID of the file
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"id": "1234abcd",
|
||||
"name": "screenshot.png",
|
||||
// Size of the file in bytes
|
||||
"size": 5694837,
|
||||
// Number of unique file views, views are counted once per IP address
|
||||
"views" 1234,
|
||||
// Total bandwidth usage of the file
|
||||
"bandwidth_used": 1234567890,
|
||||
// Premium bandwidth usage, from users with a Pro subscription or bandwidth sharing
|
||||
"bandwidth_used_paid": 1234567890,
|
||||
// Unique downloads per IP address
|
||||
"downloads": 1234,
|
||||
"date_upload": 2020-02-04T18:34:05.706801Z,
|
||||
"date_last_view": 2020-02-04T18:34:05.706801Z,
|
||||
"mime_type" "image/png",
|
||||
// Link to a thumbnail of this file
|
||||
"thumbnail_href": "/file/1234abcd/thumbnail"
|
||||
// SHA256 sum of the file, encoded in hexadecimal
|
||||
"hash_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
// If the current logged in user can edit the file
|
||||
"can_edit": true,
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_not_found"
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/thumbnail?width=x&height=x</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns a PNG thumbnail image representing the file. The thumbnail image will be
|
||||
128x128 px by default. You can specify the width and height with parameters in
|
||||
the URL. The width and height parameters need to be a multiple of 16. So the
|
||||
allowed values are 16, 32, 48, 64, 80, 96, 112 and 128. If a thumbnail cannot be
|
||||
generated for the file you will be redirected to a mime type image of 128x128
|
||||
px.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
-------|----------|----------|--------------------------------------
|
||||
id | true | URL | ID of the file to get a thumbnail for
|
||||
width | false | URL | Width of the thumbnail image
|
||||
height | false | URL | Height of the thumbnail image
|
||||
|
||||
### Returns
|
||||
|
||||
A PNG image if a thumbnail can be generated. If a thumbnail cannot be generated
|
||||
you will get a 301 redirect to an image representing the type of the file.
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/file/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Deletes a file. Only works when the users owns the file.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|-------------------------
|
||||
id | true | URL | ID of the file to delete
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"value": "file_deleted",
|
||||
"message": "The file has been deleted."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_not_found",
|
||||
"message": "File ID was not found in the database."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 401: Unauthorized
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "unauthorized",
|
||||
"message": "You are not logged in."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 403: Forbidden
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "forbidden",
|
||||
"message": "This is not your file."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
@@ -1,267 +0,0 @@
|
||||
## File Methods
|
||||
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/file</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Upload a file.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Type | Required | Maximum Size | Default | Description
|
||||
----------|----------------|----------|------------------------------|---------------------|-----------------------------------
|
||||
name | string | false | 255 characters | multipart file name | Name of the file to upload
|
||||
anonymous | boolean | false | N/A | false | File is not linked to user if true
|
||||
file | multipart file | true | Depends on user subscription | none | File to upload
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 422: Unprocessable Entity
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "no_file",
|
||||
"message": "The file does not exist or is empty."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 500: Internal Server Error
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "internal",
|
||||
"message": "An internal server error occurred."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload Too Large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_too_large",
|
||||
"message": "The file you tried to upload is too large"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 500: Internal Server Error
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "writing",
|
||||
"message": "Something went wrong while writing the file to disk, the server may be out of storage space."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload Too Large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "name_too_long",
|
||||
"message": "File Name is too long, Max 255 characters allowed."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns the full file associated with the ID. Supports byte range requests.
|
||||
|
||||
When '?download' is added to the URL the server will send an attachment header
|
||||
instead of inline rendering, which causes the browser to show a 'Save File'
|
||||
dialog.
|
||||
|
||||
Warning: If a file is using too much bandwidth it can be rate limited. The rate
|
||||
limit will be enabled if a file has ten times more downloads than views. The
|
||||
owner of a file can always download it. When a file is rate limited the user
|
||||
will need to fill out a captcha in order to continue downloading the file. The
|
||||
captcha will only appear on the file viewer page (nova.storage/u/{id}). Rate
|
||||
limiting has been added to prevent the spread of viruses and to stop direct
|
||||
linking.
|
||||
|
||||
Nova also includes a virus scanner. If a virus has been detected in a file
|
||||
the user will also have to fill in a captcha to download it.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
---------|----------|----------|------------------------------------------
|
||||
id | true | URL | ID of the file to request
|
||||
download | false | URL | Sends attachment header instead of inline
|
||||
|
||||
### Returns
|
||||
|
||||
```
|
||||
HTTP 200: OK
|
||||
|
||||
Requested file data
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "not_found",
|
||||
"message": "The entity you requested could not be found"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 403: Forbidden
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_rate_limited_captcha_required",
|
||||
"message": "This file is using too much bandwidth. For anonymous downloads a captcha is required now. The captcha entry is available on the download page"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 403: Forbidden
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "virus_detected_captcha_required",
|
||||
"message": "This file has been marked as malware by our scanning systems. To avoid infecting other systems through automated downloads we require you to enter a captcha. The captcha entry is available on the download page"
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/info</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns information about one or more files. You can also put a comma separated
|
||||
list of file IDs in the URL and it will return an array of file info, instead of
|
||||
a single object.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|---------------
|
||||
id | true | URL | ID of the file
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"id": "1234abcd",
|
||||
"name": "screenshot.png",
|
||||
"date_upload": 2020-02-04T18:34:05.706801Z,
|
||||
"date_last_view": 2020-02-04T18:34:05.706801Z,
|
||||
"size": 5694837, // Bytes
|
||||
"views" 1234, // Amount of unique file views
|
||||
"bandwidth_used": 1234567890, // Bytes
|
||||
"mime_type" "image/png",
|
||||
"thumbnail_href": "/file/1234abcd/thumbnail" // Link to a thumbnail of this file
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_not_found"
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/thumbnail?width=x&height=x</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns a PNG thumbnail image representing the file. The thumbnail image will be
|
||||
128x128 px by default. You can specify the width and height with parameters in
|
||||
the URL. The width and height parameters need to be a multiple of 16. So the
|
||||
allowed values are 16, 32, 48, 64, 80, 96, 112 and 128. If a thumbnail cannot be
|
||||
generated for the file you will be redirected to a mime type image of 128x128
|
||||
px.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
-------|----------|----------|--------------------------------------
|
||||
id | true | URL | ID of the file to get a thumbnail for
|
||||
width | false | URL | Width of the thumbnail image
|
||||
height | false | URL | Height of the thumbnail image
|
||||
|
||||
### Returns
|
||||
|
||||
A PNG image if a thumbnail can be generated. If a thumbnail cannot be generated
|
||||
you will get a 301 redirect to an image representing the type of the file.
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/file/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Deletes a file. Only works when the users owns the file.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|-------------------------
|
||||
id | true | URL | ID of the file to delete
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"value": "file_deleted",
|
||||
"message": "The file has been deleted."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_not_found",
|
||||
"message": "File ID was not found in the database."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 401: Unauthorized
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "unauthorized",
|
||||
"message": "You are not logged in."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 403: Forbidden
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "forbidden",
|
||||
"message": "This is not your file."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
@@ -1,160 +0,0 @@
|
||||
## Filesystem Methods
|
||||
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Creates a new directory or uploads a file to an existing directory.
|
||||
</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<p>
|
||||
The form parameters <b>must</b> be sent in the order displayed below
|
||||
for the realtime error checking to work. If 'name' comes after
|
||||
'file' it will be ignored.
|
||||
</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>Form Values</td>
|
||||
<td>The type of node to create, can either be 'directory', or 'file'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>name</td>
|
||||
<td>Form Values</td>
|
||||
<td>
|
||||
Name of the directory to create, or of file to create. Not
|
||||
required if 'type' is 'file'
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>file</td>
|
||||
<td>Form Values</td>
|
||||
<td>
|
||||
Multipart file to upload to the directory. Will be ignored
|
||||
if 'type' is 'directory'
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}</pre>
|
||||
todo
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Returns information about the requested path.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>path</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>Path to the directory or file to request</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>download</td>
|
||||
<td>false</td>
|
||||
<td>URL</td>
|
||||
<td>
|
||||
If the URL paramater '?download' is passed the requested
|
||||
file will be downloaded (if it is a file)
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<h4>When the requested entity is a directory:</h4>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"name": "some dir",
|
||||
"path": "/some dir",
|
||||
"type": "directory",
|
||||
"child_directories": [
|
||||
{
|
||||
"name": "some other directory",
|
||||
"type": "directory",
|
||||
"path": "/some dir/some other directory"
|
||||
}
|
||||
],
|
||||
"child_files": [
|
||||
{
|
||||
"name": "11. Lenny Kravitz - Fly away.ogg",
|
||||
"type": "file",
|
||||
"path": "/some dir/11. Lenny Kravitz - Fly away.ogg"
|
||||
}
|
||||
]
|
||||
}</pre>
|
||||
<h4>When the requested entity is a file:</h4>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"name": "11. Lenny Kravitz - Fly away.ogg",
|
||||
"path": "/some dir/11. Lenny Kravitz - Fly away.ogg",
|
||||
"type": "file",
|
||||
"file_info": {
|
||||
"success": true,
|
||||
"id": "Jf_u5TI9",
|
||||
"name": "11. Lenny Kravitz - Fly away.ogg",
|
||||
"date_upload": "2018-07-04T22:24:48Z",
|
||||
"date_last_view": "2018-07-04T22:24:48Z",
|
||||
"size": 9757269,
|
||||
"views": 0,
|
||||
"mime_type": "application/ogg",
|
||||
"thumbnail_href": "/file/Jf_u5TI9/thumbnail"
|
||||
}
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Deletes a filesystem node.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>path</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>Path of the entity to delete</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
@@ -1,188 +0,0 @@
|
||||
## List Methods
|
||||
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/list</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Creates a list of files that can be viewed together on the file viewer page.
|
||||
|
||||
### Parameters
|
||||
|
||||
POST body should be a JSON object, example below. A list can contain at most
|
||||
10000 files. If you try to add more the request will fail.
|
||||
|
||||
#### Example
|
||||
```
|
||||
{
|
||||
"title": "My beautiful photos", // Defaults to "Nova List"
|
||||
"anonymous": false / true, // If true this list will not be linked to your user account. Defaults to "false"
|
||||
"files": [ // Ordered array of files to add to the list
|
||||
{
|
||||
"id": "abc123",
|
||||
"description": "First photo of the week, such a beautiful valley"
|
||||
},
|
||||
{
|
||||
"id": "123abc",
|
||||
"description": "The week went by so quickly, here's a photo from the plane back"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"id": "yay137" // ID of the newly created list
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 422: Unprocessable Entity
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "list_file_not_found",
|
||||
"message": "File Oh42No was not found in the database.",
|
||||
"extra": {
|
||||
"file_not_found": "0h42No" // The file you tried to add with this ID does not exist
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload too large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "too_many_files",
|
||||
"message": "This list contains too many files, max 10000 allowed."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 422: Unprocessable Entity
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "json_parse_failed",
|
||||
"message": "The JSON object in the request body could not be read."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload too large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "title_too_long",
|
||||
"message": "The title of this list is too long, max 300 characters allowed."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 413: Payload too large
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "description_too_long",
|
||||
"message": "The description of one of the files in the list is too long, max 3000 characters allowed."
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 422: Unprocessable Entity
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "cannot_create_empty_list",
|
||||
"message": "You cannot make a list with no files."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/list/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns information about a file list and the files in it.
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|---------------
|
||||
id | true | URL | ID of the list
|
||||
|
||||
### Returns
|
||||
|
||||
The API will return some basic information about every file. Every file also has
|
||||
a "detail_href" field which contains a URL to the info API of the file. Follow
|
||||
that link to get more information about the file like size, checksum, mime type,
|
||||
etc. The address is relative to the API URL and should be appended to the end.
|
||||
|
||||
HTTP 200: OK
|
||||
```
|
||||
{
|
||||
"success": true,
|
||||
"id": "L8bhwx",
|
||||
"title": "Rust in Peace",
|
||||
"date_created": 2020-02-04T18:34:13.466276Z,
|
||||
"files": [
|
||||
// These structures are the same as the file info response, except for the detail_href and description fields
|
||||
{
|
||||
"detail_href": "/file/_SqVWi/info",
|
||||
"description": "",
|
||||
"success": true,
|
||||
"id": "_SqVWi",
|
||||
"name": "01 Holy Wars... The Punishment Due.mp3",
|
||||
"size": 123456,
|
||||
"date_created": 2020-02-04T18:34:13.466276Z,
|
||||
"date_last_view": 2020-02-04T18:34:13.466276Z,
|
||||
"mime_type": "audio/mp3",
|
||||
"views": 1,
|
||||
"bandwidth_used": 1234567890,
|
||||
"thumbnail_href": "/file/_SqVWi/thumbnail"
|
||||
},
|
||||
{
|
||||
"detail_href": "/file/RKwgZb/info",
|
||||
"description": "",
|
||||
"success": true,
|
||||
"id": "RKwgZb",
|
||||
"name": "02 Hangar 18.mp3",
|
||||
"size": 123456,
|
||||
"date_created": 2020-02-04T18:34:13.466276Z,
|
||||
"date_last_view": 2020-02-04T18:34:13.466276Z,
|
||||
"mime_type": "audio/mp3",
|
||||
"views": 2,
|
||||
"bandwidth_used": 1234567890,
|
||||
"thumbnail_href": "/file/RKwgZb/thumbnail"
|
||||
},
|
||||
{
|
||||
"detail_href": "/file/DRaL_e/info",
|
||||
"description": "",
|
||||
"success": true,
|
||||
"id": "DRaL_e",
|
||||
"name": "03 Take No Prisoners.mp3",
|
||||
"size": 123456,
|
||||
"date_created": 2020-02-04T18:34:13.466276Z,
|
||||
"date_last_view": 2020-02-04T18:34:13.466276Z,
|
||||
"mime_type": "audio/mp3",
|
||||
"views": 3,
|
||||
"bandwidth_used": 1234567890,
|
||||
"thumbnail_href": "/file/DRaL_e/thumbnail"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
HTTP 404: Not Found
|
||||
```
|
||||
{
|
||||
"success": false,
|
||||
"value": "list_not_found",
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
@@ -1,18 +0,0 @@
|
||||
## User Methods
|
||||
|
||||
These methods all require authentication.
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/user/files</summary>
|
||||
<div>
|
||||
Documentation pending. Click here to see the response for your account:
|
||||
[/user/files](/api/user/files).
|
||||
</div>
|
||||
</details>
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/user/lists</summary>
|
||||
<div>
|
||||
Documentation pending. Click here to see the response for your account:
|
||||
[/user/lists](/api/user/lists).
|
||||
</div>
|
||||
</details>
|
||||
|
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 175 KiB |
29
res/static/img/nova.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="23.47 13.09 31.04 31.04">
|
||||
<defs>
|
||||
<linearGradient id="nbar" x1="27.2" y1="44.04" x2="27.2" y2="16.51" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#45ed52"/>
|
||||
<stop offset=".5" style="stop-color:#11a574"/>
|
||||
<stop offset="1" style="stop-color:#000"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="nbar2" x1="50.8" y1="13.18" x2="50.8" y2="40.72" href="#nbar"/>
|
||||
<linearGradient id="ndiagonal" x1="24.86" y1="28.61" x2="53.14" y2="28.61" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#24b880"/>
|
||||
<stop offset="1" style="stop-color:#39ef3d"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="nedge" x1="27.2" y1="16.42" x2="27.2" y2="44.13" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:currentColor;stop-opacity:0"/>
|
||||
<stop offset="1" style="stop-color:currentColor"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="nedge2" x1="50.8" y1="40.81" x2="50.8" y2="13.09" href="#nedge"/>
|
||||
<linearGradient id="nedge3" x1="24.77" y1="28.61" x2="53.23" y2="28.61" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:currentColor;stop-opacity:0"/>
|
||||
<stop offset=".54" style="stop-color:currentColor"/>
|
||||
<stop offset="1" style="stop-color:currentColor;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g stroke-width=".18" stroke-miterlimit="10">
|
||||
<path fill="url(#nbar)" stroke="url(#nedge)" d="M27.96,16.75c-2.08,0-2.93,1.83-3.11,3v21.81c0,1.37,1.05,2.48,2.34,2.48s2.34-1.11,2.34-2.48v-24.76c-.58-.63-.72-.05-1.57-.05Z"/>
|
||||
<path fill="url(#nbar2)" stroke="url(#nedge2)" d="M50.03,40.48c2.08,0,2.93-1.83,3.11-3v-.54s0-21.28,0-21.28c0-1.37-1.05-2.48-2.34-2.48s-2.34,1.11-2.34,2.48v20.98s0,2.54,0,2.54v1.24c.58.63.72.05,1.57.05Z"/>
|
||||
<path fill="url(#ndiagonal)" stroke="url(#nedge3)" d="M50.03,40.49c-.71,0-1.33-.32-1.86-.77-.18-.15-.33-.33-.45-.53l-1-1.66-12.34-21.84c-.8-1.43-2.19-2.5-3.83-2.5-.34,0-.68.05-1.01.13-2.49.63-4.68,3.44-4.68,5.96h0v.29c.18-1.1,1.03-2.83,3.11-2.83.71,0,1.33.32,1.86.77.18.15.33.33.45.53l1,1.66,12.34,21.84c.8,1.43,2.19,2.5,3.83,2.5.34,0,.68-.05,1.01-.13,2.49-.63,4.68-3.44,4.68-5.96h0v-.29c-.18,1.1-1.03,2.83-3.11,2.83Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -3,8 +3,95 @@
|
||||
Author : Fornax
|
||||
*/
|
||||
|
||||
/* The default theme, a dark and a light variant which follow the browser's
|
||||
preference. Branding colours are applied on top of these by the app, see
|
||||
Branding.ts */
|
||||
:root {
|
||||
--highlight_border: inset 0px 0px 5px 1px var(--highlight_color), 0px 0px 1px 0px var(--highlight_color);
|
||||
--color_scheme: dark;
|
||||
--background_color: #15161c;
|
||||
--background: var(--background_color);
|
||||
--background_text_color: #e6e8ef;
|
||||
--body_color: #1c1d25;
|
||||
--body_background: rgb(28 29 37 / 90%);
|
||||
--shaded_background: rgb(28 29 37 / 90%);
|
||||
--body_text_color: #e6e8ef;
|
||||
--card_color: #252733;
|
||||
--separator: #2e3040;
|
||||
--shadow_color: #0c0d12;
|
||||
--input_background: #2c2e3b;
|
||||
--input_hover_background: #363949;
|
||||
--input_text: #eceef4;
|
||||
--input_disabled_text: #737890;
|
||||
--accent_color: #49dfa0;
|
||||
--accent_shade: #243d32;
|
||||
--accent_background: #49dfa0;
|
||||
--accent_text_color: #05130d;
|
||||
--link_color: #70ebb8;
|
||||
--scrollbar_foreground_color: #33364a;
|
||||
--scrollbar_hover_color: #43475f;
|
||||
|
||||
/* Accents for success, errors, warnings and notices. They're the highlight
|
||||
colour with a different hue, see Branding.ts. The tints are backgrounds
|
||||
for messages */
|
||||
--green_color: #49df7b;
|
||||
--red_color: #df5d49;
|
||||
--yellow_color: #dfba49;
|
||||
--blue_color: #4987df;
|
||||
--green_tint: rgb(73 223 123 / 12%);
|
||||
--red_tint: rgb(223 93 73 / 12%);
|
||||
--yellow_tint: rgb(223 186 73 / 12%);
|
||||
--blue_tint: rgb(73 135 223 / 12%);
|
||||
|
||||
/* The logo's mint colourway, see NovaLogo.svelte */
|
||||
--logo_color_1: #45ed52;
|
||||
--logo_color_2: #11a574;
|
||||
--logo_color_3: #24b880;
|
||||
--logo_color_4: #39ef3d;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--color_scheme: light;
|
||||
--background_color: #e9ebf0;
|
||||
--background_text_color: #1b1d25;
|
||||
--body_color: #f5f6f9;
|
||||
--body_background: rgb(245 246 249 / 90%);
|
||||
--shaded_background: rgb(245 246 249 / 90%);
|
||||
--body_text_color: #1b1d25;
|
||||
--card_color: #ffffff;
|
||||
--separator: #d3d7e0;
|
||||
--shadow_color: #b9bdc9;
|
||||
--input_background: #e2e5ec;
|
||||
--input_hover_background: #d7dbe4;
|
||||
--input_text: #1b1d25;
|
||||
--input_disabled_text: #80859a;
|
||||
--accent_color: #09714b;
|
||||
--accent_shade: #e2eeea;
|
||||
--accent_background: #09714b;
|
||||
--accent_text_color: #ffffff;
|
||||
--link_color: #09714b;
|
||||
--scrollbar_foreground_color: #c6cad5;
|
||||
--scrollbar_hover_color: #b0b5c3;
|
||||
|
||||
/* Accents derived from the accent colour are too light on white,
|
||||
these are the same ones branded light themes get */
|
||||
--green_color: #15793a;
|
||||
--red_color: #ba2c37;
|
||||
--yellow_color: #995c00;
|
||||
--blue_color: #2164ca;
|
||||
--green_tint: rgb(21 121 58 / 12%);
|
||||
--red_tint: rgb(186 44 55 / 12%);
|
||||
--yellow_tint: rgb(153 92 0 / 12%);
|
||||
--blue_tint: rgb(33 100 202 / 12%);
|
||||
}
|
||||
}
|
||||
|
||||
/* Branding can set a different scheme on the body, for a shared directory. The
|
||||
browser draws checkboxes and radio buttons in the accent colour */
|
||||
:root,
|
||||
body {
|
||||
color-scheme: var(--color_scheme);
|
||||
accent-color: var(--accent_color);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
@@ -14,7 +101,7 @@
|
||||
font-display: block;
|
||||
src: local('Material Icons'),
|
||||
local('MaterialIcons-Regular'),
|
||||
url(/res/misc/MaterialIcons.woff2) format('truetype');
|
||||
url(/res/misc/MaterialIcons.woff2) format('woff2');
|
||||
}
|
||||
|
||||
.icon {
|
||||
@@ -117,21 +204,6 @@ pre>code {
|
||||
|
||||
/* Page layout elements */
|
||||
|
||||
.page_navigation {
|
||||
position: fixed;
|
||||
backface-visibility: hidden;
|
||||
background: var(--navigation_background);
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
float: left;
|
||||
padding: 20px 0 10px 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
text-align: left;
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.page_content {
|
||||
background: var(--body_background);
|
||||
text-align: center;
|
||||
@@ -140,10 +212,6 @@ pre>code {
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page_navigation {
|
||||
left: -300px;
|
||||
}
|
||||
|
||||
header>h1 {
|
||||
/* We want the header text to appear below the menu button, so the top
|
||||
margin needs to be fairly large when the screen is small */
|
||||
@@ -173,29 +241,6 @@ section {
|
||||
|
||||
/* Page contents */
|
||||
|
||||
.page_navigation a {
|
||||
float: none;
|
||||
display: block;
|
||||
color: var(--background_text_color);
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
margin: 0.2em 15px 0.2em 15px;
|
||||
font-family: 'Open Sans Light', sans-serif;
|
||||
font-weight: lighter;
|
||||
font-size: 1.5em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: background 0.2s;
|
||||
border-radius: 24px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.page_navigation a:hover {
|
||||
background: var(--input_background);
|
||||
color: var(--input_text);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.highlight_shaded,
|
||||
.highlight_border,
|
||||
.highlight_green,
|
||||
@@ -218,23 +263,23 @@ section {
|
||||
}
|
||||
|
||||
.highlight_green {
|
||||
background-color: rgba(0, 255, 0, 0.1);
|
||||
border-color: #00D000;
|
||||
background-color: var(--green_tint);
|
||||
border-color: var(--green_color);
|
||||
}
|
||||
|
||||
.highlight_blue {
|
||||
background-color: rgba(0, 0, 255, 0.1);
|
||||
border-color: #3636FF;
|
||||
background-color: var(--blue_tint);
|
||||
border-color: var(--blue_color);
|
||||
}
|
||||
|
||||
.highlight_yellow {
|
||||
background-color: rgba(255, 255, 0, 0.1);
|
||||
border-color: #A0A000;
|
||||
background-color: var(--yellow_tint);
|
||||
border-color: var(--yellow_color);
|
||||
}
|
||||
|
||||
.highlight_red {
|
||||
background-color: rgba(255, 0, 0, 0.1);
|
||||
border-color: #B00000;
|
||||
background-color: var(--red_tint);
|
||||
border-color: var(--red_color);
|
||||
}
|
||||
|
||||
.highlight_green,
|
||||
@@ -386,53 +431,6 @@ tr>th {
|
||||
padding: 0.2em 0.5em;
|
||||
}
|
||||
|
||||
/* API documentation markup */
|
||||
|
||||
.api_doc_details {
|
||||
border-top: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
margin: 15px 0 15px 0;
|
||||
}
|
||||
|
||||
.api_doc_details>summary {
|
||||
padding: 2px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.api_doc_details>summary>.method {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.api_doc_details>div {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.api_doc_details.request_get {
|
||||
border-color: #3636ff;
|
||||
background-color: rgba(32, 32, 255, 0.2);
|
||||
}
|
||||
|
||||
.api_doc_details.request_post {
|
||||
border-color: #00d000;
|
||||
background-color: rgba(0, 255, 0, 0.05);
|
||||
}
|
||||
|
||||
.api_doc_details.request_delete {
|
||||
border-color: #B00000;
|
||||
background-color: rgba(255, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.api_doc_details.request_put {
|
||||
border-color: #B06000;
|
||||
background-color: rgba(255, 128, 0, 0.05);
|
||||
}
|
||||
|
||||
.api_doc_details.request_patch {
|
||||
border-color: #6000B0;
|
||||
background-color: rgba(128, 0, 255, 0.1);
|
||||
}
|
||||
|
||||
/* BUTTONS */
|
||||
button,
|
||||
.button,
|
||||
@@ -486,7 +484,7 @@ input[type="color"]:focus {
|
||||
color: var(--input_text);
|
||||
text-decoration: none;
|
||||
background: var(--input_hover_background);
|
||||
box-shadow: 0px 0px 0px 1px var(--highlight_color) !important;
|
||||
box-shadow: 0px 0px 0px 1px var(--accent_color) !important;
|
||||
}
|
||||
|
||||
button:active,
|
||||
@@ -499,13 +497,25 @@ input[type="color"]:active {
|
||||
padding: 4px 0px 0px 4px;
|
||||
}
|
||||
|
||||
/* Selected buttons get the accent colour on a shade of it. The outline shows
|
||||
hover and keyboard focus, so it would be confusing to use it for this too */
|
||||
.button_highlight {
|
||||
box-shadow: 0px 0px 0px 1px var(--highlight_color) !important;
|
||||
color: var(--accent_color) !important;
|
||||
background: var(--accent_shade) !important;
|
||||
}
|
||||
|
||||
.icon.button_highlight {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.button_red {
|
||||
background: var(--danger_color) !important;
|
||||
color: var(--danger_text_color) !important;
|
||||
background: var(--red_tint) !important;
|
||||
color: var(--red_color) !important;
|
||||
}
|
||||
|
||||
.button_red:hover,
|
||||
.button_red:focus {
|
||||
box-shadow: 0px 0px 0px 1px var(--red_color) !important;
|
||||
}
|
||||
|
||||
button:disabled,
|
||||
@@ -631,7 +641,7 @@ input[type="email"]:focus,
|
||||
input[type="number"]:focus,
|
||||
input[type="date"]:focus,
|
||||
input[type="datetime-local"]:focus {
|
||||
box-shadow: inset 0px 0px 0px 1px var(--highlight_color);
|
||||
box-shadow: inset 0px 0px 0px 1px var(--accent_color);
|
||||
}
|
||||
|
||||
textarea:disabled,
|
||||
@@ -657,8 +667,8 @@ input[type=file] {
|
||||
|
||||
/* The selected option in multi select */
|
||||
option:checked {
|
||||
background-color: var(--highlight_background);
|
||||
color: var(--highlight_text_color);
|
||||
background-color: var(--accent_background);
|
||||
color: var(--accent_text_color);
|
||||
}
|
||||
|
||||
/* Webkit Scrollbars */
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{{define "403"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Forbidden"}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>Forbidden</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
<p>
|
||||
You do not have permission to access this resource.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,26 +0,0 @@
|
||||
{{define "404"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Not Found"}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>This page does not exist!</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
<p>
|
||||
There's nothing to see here, so you'll have to
|
||||
<a href='/'>head over to the home page</a>.
|
||||
</p>
|
||||
<p>
|
||||
Bye!
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,23 +0,0 @@
|
||||
{{define "451"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "451, Unavailable For Legal Reasons"}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>451, Unavailable For Legal Reasons</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
<p>
|
||||
Hello. This file has received an abuse report and has been taken
|
||||
down. It cannot be shared anymore.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,32 +0,0 @@
|
||||
{{define "500"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "500, Internal Server Error"}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>You broke Nova</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
<p>
|
||||
Great job.
|
||||
</p>
|
||||
<p>
|
||||
Just kidding, something went wrong on the Nova server and
|
||||
it's my fault. This can happen when the website is overloaded,
|
||||
there is a problem with the software or there is a hardware
|
||||
problem. When there is a large scale outage you can usually find
|
||||
more info on my twitter <a
|
||||
href="https://twitter.com/Fornax96"></a>@Fornax96</a>. You can
|
||||
try again in a few minutes (or hours), or go back to the <a
|
||||
href='/'>home page</a> and start over.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,20 +0,0 @@
|
||||
{{define "markdown_wrapper"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" .Title}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>{{.Title}}</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
{{.Other}}
|
||||
</section>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,43 +0,0 @@
|
||||
{{define "meta_tags"}}
|
||||
<title>{{.}} ~ Nova</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="theme-color" content="#220735" />
|
||||
|
||||
<link id="stylesheet_layout" rel="stylesheet" type="text/css" href="/res/style/layout.css?v{{cacheID}}"/>
|
||||
<link id="stylesheet_theme" rel="stylesheet" type="text/css" href="/theme.css"/>
|
||||
|
||||
<link rel="icon" sizes="32x32" href="/res/img/nova_32.png" />
|
||||
<link rel="icon" sizes="128x128" href="/res/img/nova_128.png" />
|
||||
<link rel="icon" sizes="152x152" href="/res/img/nova_152.png" />
|
||||
<link rel="icon" sizes="180x180" href="/res/img/nova_180.png" />
|
||||
<link rel="icon" sizes="192x192" href="/res/img/nova_192.png" />
|
||||
<link rel="icon" sizes="196x196" href="/res/img/nova_196.png" />
|
||||
<link rel="icon" sizes="256x256" href="/res/img/nova_256.png" />
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/res/img/nova_152.png" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/res/img/nova_180.png" />
|
||||
<link rel="shortcut icon" sizes="196x196" href="/res/img/nova_196.png" />
|
||||
|
||||
<meta name="description" content="Nova is a file transfer service, you
|
||||
can upload any file and you will be given a shareable link right away.
|
||||
Nova also supports previews for images, videos, audio, PDFs and much more." />
|
||||
<meta name="keywords" content="file sharing, free file sharing, file transfer,
|
||||
free file transfer, file hosting, free file hosting, hosting, file upload,
|
||||
free file upload, uploading, send file, large file, free file sharing,
|
||||
free file transfer, 20 GB free, free file sending, file storage, cloud storage,
|
||||
free cloud storage, image hosting, image sharing, photo hosting,
|
||||
photo transfer, photo sharing, video hosting, video sharing, video transfer,
|
||||
document sharing, upload documents, send documents, huge file, large video,
|
||||
large document, pdf, pdf sharing, pdf upload, pdf transfer, pdf reader,
|
||||
free pdf upload, text file upload, text sharing, photo storage,
|
||||
professional file transfer, cheap storage, cheap file storage, send large file,
|
||||
send big file, send huge file, audio sharing, music sharing, audio upload,
|
||||
music upload" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="{{.}} ~ Nova" />
|
||||
<meta property="og:site_name" content="Nova" />
|
||||
<meta property="og:description" content="Instant file and screenshot sharing." />
|
||||
<meta property="og:url" content="http://nova.storage/" />
|
||||
<meta property="og:image" content="/res/img/nova_256.png" />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
{{end}}
|
||||
@@ -1,13 +0,0 @@
|
||||
{{ define "opengraph" }}
|
||||
|
||||
{{ range $kv := .MetaPropRules }}
|
||||
<meta property="{{ $kv.Key }}" content="{{ $kv.Value }}" />
|
||||
{{ end }}
|
||||
{{ range $kv := .MetaNameRules }}
|
||||
<meta name="{{ $kv.Key }}" content="{{ $kv.Value }}" />
|
||||
{{ end }}
|
||||
{{ range $kv := .LinkRules }}
|
||||
<link rel="{{ $kv.Key }}" href="{{ $kv.Value }}" />
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
@@ -1,24 +0,0 @@
|
||||
{{ define "status" }}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Server status"}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<div id="page_content" class="page_content">
|
||||
<script type="text/javascript" src="https://static.hetrix.io/iframeResizer/iframeResizer.min.js"></script>
|
||||
<iframe
|
||||
class="htframe"
|
||||
src="https://wl.hetrixtools.com/r/3e1b7bf5ddf9858527cbf209d3d9ef60/"
|
||||
width="100%"
|
||||
scrolling="no"
|
||||
style="border: none; display: block;"
|
||||
sandbox="allow-scripts allow-same-origin allow-popups"
|
||||
onload="iFrameResize([{log:false}],'.htframe')"
|
||||
></iframe>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
||||
@@ -1,75 +0,0 @@
|
||||
{{define "widgets"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Cloud storage and data transfer services"}}
|
||||
</head>
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>Widget showcase</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
<h2>Size 2 header</h2>
|
||||
<h3>Size 3 header</h3>
|
||||
<h4>Size 4 header</h4>
|
||||
<h5>Size 5 header</h5>
|
||||
<h6>Size 6 header</h6>
|
||||
|
||||
<div class="highlight_shaded">Shaded highlight</div>
|
||||
<br/>
|
||||
Link <a href="#">A link to someplace</a>.
|
||||
<hr/>
|
||||
Buttons <button>Regular ol' button!</button>
|
||||
Width indicator
|
||||
<button class="button_highlight">Important button!</button>
|
||||
Width indicator
|
||||
<button class="button_red">Dangerous button!</button>
|
||||
<hr/>
|
||||
Textarea <textarea>Hello!</textarea>
|
||||
<hr/>
|
||||
Checkbox <input type="checkbox"/>
|
||||
<hr/>
|
||||
Radio
|
||||
<input name="radioform" type="radio"/>
|
||||
<input name="radioform" type="radio"/>
|
||||
<hr/>
|
||||
Text field <input type="text"/>
|
||||
<hr/>
|
||||
Password <input type="password"/>
|
||||
<hr/>
|
||||
Number <input type="number"/>
|
||||
<hr/>
|
||||
Select
|
||||
<select name="select">
|
||||
<option>cherry</option>
|
||||
<option>orange</option>
|
||||
<option>apple</option>
|
||||
</select>
|
||||
<hr/>
|
||||
Select2 <select name="select2" size="3">
|
||||
<option>cherry</option>
|
||||
<option>orange</option>
|
||||
<option>apple</option>
|
||||
</select>
|
||||
<hr/>
|
||||
File <input type="file" name="file">
|
||||
<hr/>
|
||||
Color <input type="color" name="favcolor" value="#ff0000">
|
||||
<hr/>
|
||||
<fieldset>
|
||||
<legend>Legend</legend>
|
||||
<p>
|
||||
Fieldset
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<br/><br/>
|
||||
<iframe src="https://nova.storage/u/Nygt1on4?embed" style="border: none; width: 800px; max-width: 100%; height: 600px; max-height: 100%; border-radius: 16px;"></iframe>
|
||||
</section>
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,35 +1,42 @@
|
||||
{{define "wrap"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{.Title}}</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>{{.Title}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
|
||||
<link id="stylesheet_layout" rel="stylesheet" type="text/css" href="/res/style/layout.css?v{{cacheID}}"/>
|
||||
<link id="stylesheet_theme" rel="stylesheet" type="text/css" href="/theme.css"/>
|
||||
<link rel="stylesheet" href="/res/style/layout.css?v{{.CacheID}}"/>
|
||||
<link rel="preload" href="/res/misc/MaterialIcons.woff2" as="font" type="font/woff2" crossorigin/>
|
||||
|
||||
<link rel="icon" sizes="32x32" href="/res/img/nova_32.png" />
|
||||
<link rel="icon" sizes="64x64" href="/res/img/nova_64.png" />
|
||||
<link rel="icon" sizes="128x128" href="/res/img/nova_128.png" />
|
||||
<link rel="icon" sizes="152x152" href="/res/img/nova_152.png" />
|
||||
<link rel="icon" sizes="180x180" href="/res/img/nova_180.png" />
|
||||
<link rel="icon" sizes="192x192" href="/res/img/nova_192.png" />
|
||||
<link rel="icon" sizes="196x196" href="/res/img/nova_196.png" />
|
||||
<link rel="icon" sizes="256x256" href="/res/img/nova_256.png" />
|
||||
<link rel="apple-touch-icon" sizes="128x128" href="/res/img/nova_128.png" />
|
||||
<link rel="apple-touch-icon" sizes="256x256" href="/res/img/nova_256.png" />
|
||||
<link rel="shortcut icon" sizes="256x256" href="/res/img/nova_256.png" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="32x32"/>
|
||||
<link rel="icon" href="/res/img/nova.svg" type="image/svg+xml"/>
|
||||
<link rel="apple-touch-icon" href="/res/img/nova_180.png"/>
|
||||
|
||||
{{range .OGData.MetaPropRules}}
|
||||
<meta property="{{.Key}}" content="{{.Value}}" />
|
||||
{{end}}
|
||||
{{range .OGData.MetaNameRules}}
|
||||
<meta name="{{.Key}}" content="{{.Value}}" />
|
||||
{{end}}
|
||||
{{range .OGData.LinkRules}}
|
||||
<link rel="{{.Key}}" href="{{.Value}}" />
|
||||
{{end}}
|
||||
|
||||
{{ template "opengraph" .OGData }}
|
||||
<script>
|
||||
// The branding of the user's home directory, saved on the previous
|
||||
// visit. Applying it before the page is drawn prevents a flash of
|
||||
// the default theme while the app loads
|
||||
try {
|
||||
document.documentElement.style.cssText = localStorage.getItem("branding") ?? ""
|
||||
} catch {}
|
||||
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
{{with .User}}window.user = {{.}};{{end}}
|
||||
{{with .Node}}window.initial_node = {{.}};{{end}}
|
||||
</script>
|
||||
|
||||
<script defer src='/res/svelte/wrap.js?v{{cacheID}}' type="module"></script>
|
||||
<script src="/res/svelte/wrap.js" type="module"></script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
{{end}}
|
||||
|
||||