Update.
This commit is contained in:
parent
803ad3dfc6
commit
0c0742fce7
src/snek
@ -44,6 +44,7 @@ from snek.view.avatar import AvatarView
|
||||
from snek.view.channel import ChannelAttachmentView,ChannelAttachmentUploadView, ChannelView
|
||||
from snek.view.docs import DocsHTMLView, DocsMDView
|
||||
from snek.view.drive import DriveApiView, DriveView
|
||||
from snek.view.channel import ChannelDriveApiView
|
||||
from snek.view.index import IndexView
|
||||
from snek.view.login import LoginView
|
||||
from snek.view.logout import LogoutView
|
||||
@ -286,6 +287,9 @@ class Application(BaseApplication):
|
||||
self.router.add_view(
|
||||
"/channel/{channel_uid}/attachment.bin", ChannelAttachmentView
|
||||
)
|
||||
self.router.add_view(
|
||||
"/channel/{channel_uid}/drive.json", ChannelDriveApiView
|
||||
)
|
||||
self.router.add_view(
|
||||
"/channel/{channel_uid}/attachment.sock", ChannelAttachmentUploadView
|
||||
)
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* A <file-browser> custom element that talks to /api/files */
|
||||
import { NjetComponent } from "/njet.js";
|
||||
|
||||
class FileBrowser extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
@ -6,9 +8,11 @@ class FileBrowser extends HTMLElement {
|
||||
this.path = ""; // current virtual path ("" = ROOT)
|
||||
this.offset = 0; // pagination offset
|
||||
this.limit = 40; // items per request
|
||||
this.url = '/drive.json'
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.url = this.getAttribute("url") || this.url;
|
||||
this.path = this.getAttribute("path") || "";
|
||||
this.renderShell();
|
||||
this.load();
|
||||
@ -58,7 +62,7 @@ class FileBrowser extends HTMLElement {
|
||||
// ---------- Networking ----------------------------------------------
|
||||
async load() {
|
||||
const r = await fetch(
|
||||
`/drive.json?path=${encodeURIComponent(this.path)}&offset=${this.offset}&limit=${this.limit}`,
|
||||
this.url + `?path=${encodeURIComponent(this.path)}&offset=${this.offset}&limit=${this.limit}`
|
||||
);
|
||||
if (!r.ok) {
|
||||
console.error(await r.text());
|
||||
|
@ -134,11 +134,26 @@ class Njet extends HTMLElement {
|
||||
get rest() {
|
||||
return Njet._root._rest
|
||||
}
|
||||
|
||||
attach(element) {
|
||||
this._attachedTo = element
|
||||
this._attachedTo.addEventListener("resize", () => {
|
||||
this.updatePosition()
|
||||
})
|
||||
}
|
||||
updatePosition(){
|
||||
if(this._attachedTo)
|
||||
{
|
||||
this.style.width = `${this._attachedTo.offsetWidth}`
|
||||
this.style.height = `${this._attachedTo.offsetHeight}`
|
||||
this.style.left = `${this._attachedTo.offsetLeft}`
|
||||
this.style.top = `${this._attachedTo.offsetTop}`
|
||||
this.style.position = 'fixed'
|
||||
}
|
||||
}
|
||||
_subscriptions = {}
|
||||
_elements = []
|
||||
_rest = null
|
||||
|
||||
_attachedTo = null
|
||||
match(args) {
|
||||
return Object.entries(args).every(([key, value]) => this[key] === value);
|
||||
}
|
||||
@ -312,15 +327,6 @@ class NjetDialog extends Component {
|
||||
this.innerHTML = '';
|
||||
const { title, content, primaryButton, secondaryButton } = this.config;
|
||||
this.classList.add('njet-dialog');
|
||||
this.style.position = 'fixed';
|
||||
this.style.top = '50%';
|
||||
this.style.left = '50%';
|
||||
this.style.transform = 'translate(-50%, -50%)';
|
||||
this.style.padding = '20px';
|
||||
this.style.border = '1px solid #444';
|
||||
this.style.backgroundColor = '#fff';
|
||||
this.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
|
||||
this.style.minWidth = '300px';
|
||||
if (title) {
|
||||
const header = document.createElement('h2');
|
||||
header.textContent = title;
|
||||
@ -357,22 +363,14 @@ class NjetWindow extends Component {
|
||||
render() {
|
||||
this.innerHTML = '';
|
||||
const { title, content, primaryButton, secondaryButton } = this.config;
|
||||
this.classList.add('njet-dialog');
|
||||
this.style.position = 'fixed';
|
||||
this.style.top = '50%';
|
||||
this.style.left = '50%';
|
||||
this.style.transform = 'translate(-50%, -50%)';
|
||||
this.style.padding = '20px';
|
||||
this.style.border = '1px solid #444';
|
||||
this.style.backgroundColor = '#fff';
|
||||
this.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
|
||||
this.style.minWidth = '300px';
|
||||
this.classList.add('njet-window');
|
||||
|
||||
if (title) {
|
||||
const header = document.createElement('h2');
|
||||
header.textContent = title;
|
||||
this.appendChild(header);
|
||||
}
|
||||
|
||||
this.config.items.forEach(item => this.appendChild(item));
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,10 @@
|
||||
<script type="module">
|
||||
import { njet } from "/njet.js"
|
||||
|
||||
function deleteChannel(channelUid){
|
||||
app.channel = {}
|
||||
|
||||
|
||||
app.channel.remove = function(channelUid){
|
||||
|
||||
const dialog = new njet.showDialog({
|
||||
title: 'Upload in progress',
|
||||
@ -14,8 +17,24 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
app.channel._fileManager = null
|
||||
app.channel.toggleDrive = function(channelUid){
|
||||
if(app._fileManager){
|
||||
app._fileManager.remove()
|
||||
app._fileManager = null
|
||||
document.querySelector('message-list').style.display = 'block'
|
||||
return
|
||||
}
|
||||
app.channel._fileManager = document.createElement("file-manager")
|
||||
app.channel._fileManager.style.padding = '10px'
|
||||
app.channel._fileManager.setAttribute("url",`/channel/${app.channelUid}/drive.json`)
|
||||
document.querySelector(".chat-area").insertBefore(app.channel._fileManager,document.querySelector(".chat-area").firstChild)
|
||||
document.querySelector("message-list").style.display = 'none'
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -13,6 +13,17 @@ from snek.system.view import BaseView
|
||||
|
||||
register_heif_opener()
|
||||
|
||||
from snek.view.drive import DriveApiView
|
||||
|
||||
class ChannelDriveApiView(DriveApiView):
|
||||
async def get_target(self):
|
||||
target = await self.services.channel.get_home_folder(self.request.match_info.get("channel_uid"))
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
return target
|
||||
|
||||
async def get_download_url(self, rel):
|
||||
return f"/channel/{self.request.match_info.get('channel_uid')}/drive/{urllib.parse.quote(rel)}"
|
||||
|
||||
class ChannelAttachmentView(BaseView):
|
||||
async def get(self):
|
||||
relative_path = self.request.match_info.get("relative_url")
|
||||
|
@ -28,8 +28,19 @@ class DriveView(BaseView):
|
||||
|
||||
|
||||
class DriveApiView(BaseView):
|
||||
async def get(self):
|
||||
|
||||
login_required = True
|
||||
|
||||
async def get_target(self):
|
||||
target = await self.services.user.get_home_folder(self.session.get("uid"))
|
||||
return target
|
||||
|
||||
async def get_download_url(self, rel):
|
||||
return f"/drive/{urllib.parse.quote(rel)}"
|
||||
|
||||
async def get(self):
|
||||
target = await self.get_target()
|
||||
original_target = target
|
||||
rel = self.request.query.get("path", "")
|
||||
offset = int(self.request.query.get("offset", 0))
|
||||
limit = int(self.request.query.get("limit", 20))
|
||||
@ -40,6 +51,9 @@ class DriveApiView(BaseView):
|
||||
if not target.exists():
|
||||
return web.json_response({"error": "Not found"}, status=404)
|
||||
|
||||
if not target.relative_to(original_target):
|
||||
return web.json_response({"error": "Not found"}, status=404)
|
||||
|
||||
if target.is_dir():
|
||||
entries = []
|
||||
for p in sorted(
|
||||
@ -79,7 +93,7 @@ class DriveApiView(BaseView):
|
||||
}
|
||||
)
|
||||
|
||||
url = self.request.url.with_path(f"/drive/{urllib.parse.quote(rel)}")
|
||||
url = self.request.url.with_path(await self.get_download_url(rel))
|
||||
return web.json_response(
|
||||
{
|
||||
"name": target.name,
|
||||
|
Loading…
Reference in New Issue
Block a user