Update.
This commit is contained in:
parent
803ad3dfc6
commit
0c0742fce7
@ -44,6 +44,7 @@ from snek.view.avatar import AvatarView
|
|||||||
from snek.view.channel import ChannelAttachmentView,ChannelAttachmentUploadView, ChannelView
|
from snek.view.channel import ChannelAttachmentView,ChannelAttachmentUploadView, ChannelView
|
||||||
from snek.view.docs import DocsHTMLView, DocsMDView
|
from snek.view.docs import DocsHTMLView, DocsMDView
|
||||||
from snek.view.drive import DriveApiView, DriveView
|
from snek.view.drive import DriveApiView, DriveView
|
||||||
|
from snek.view.channel import ChannelDriveApiView
|
||||||
from snek.view.index import IndexView
|
from snek.view.index import IndexView
|
||||||
from snek.view.login import LoginView
|
from snek.view.login import LoginView
|
||||||
from snek.view.logout import LogoutView
|
from snek.view.logout import LogoutView
|
||||||
@ -286,6 +287,9 @@ class Application(BaseApplication):
|
|||||||
self.router.add_view(
|
self.router.add_view(
|
||||||
"/channel/{channel_uid}/attachment.bin", ChannelAttachmentView
|
"/channel/{channel_uid}/attachment.bin", ChannelAttachmentView
|
||||||
)
|
)
|
||||||
|
self.router.add_view(
|
||||||
|
"/channel/{channel_uid}/drive.json", ChannelDriveApiView
|
||||||
|
)
|
||||||
self.router.add_view(
|
self.router.add_view(
|
||||||
"/channel/{channel_uid}/attachment.sock", ChannelAttachmentUploadView
|
"/channel/{channel_uid}/attachment.sock", ChannelAttachmentUploadView
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/* A <file-browser> custom element that talks to /api/files */
|
/* A <file-browser> custom element that talks to /api/files */
|
||||||
|
import { NjetComponent } from "/njet.js";
|
||||||
|
|
||||||
class FileBrowser extends HTMLElement {
|
class FileBrowser extends HTMLElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -6,9 +8,11 @@ class FileBrowser extends HTMLElement {
|
|||||||
this.path = ""; // current virtual path ("" = ROOT)
|
this.path = ""; // current virtual path ("" = ROOT)
|
||||||
this.offset = 0; // pagination offset
|
this.offset = 0; // pagination offset
|
||||||
this.limit = 40; // items per request
|
this.limit = 40; // items per request
|
||||||
|
this.url = '/drive.json'
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
|
this.url = this.getAttribute("url") || this.url;
|
||||||
this.path = this.getAttribute("path") || "";
|
this.path = this.getAttribute("path") || "";
|
||||||
this.renderShell();
|
this.renderShell();
|
||||||
this.load();
|
this.load();
|
||||||
@ -58,7 +62,7 @@ class FileBrowser extends HTMLElement {
|
|||||||
// ---------- Networking ----------------------------------------------
|
// ---------- Networking ----------------------------------------------
|
||||||
async load() {
|
async load() {
|
||||||
const r = await fetch(
|
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) {
|
if (!r.ok) {
|
||||||
console.error(await r.text());
|
console.error(await r.text());
|
||||||
|
@ -134,11 +134,26 @@ class Njet extends HTMLElement {
|
|||||||
get rest() {
|
get rest() {
|
||||||
return Njet._root._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 = {}
|
_subscriptions = {}
|
||||||
_elements = []
|
_elements = []
|
||||||
_rest = null
|
_rest = null
|
||||||
|
_attachedTo = null
|
||||||
match(args) {
|
match(args) {
|
||||||
return Object.entries(args).every(([key, value]) => this[key] === value);
|
return Object.entries(args).every(([key, value]) => this[key] === value);
|
||||||
}
|
}
|
||||||
@ -312,15 +327,6 @@ class NjetDialog extends Component {
|
|||||||
this.innerHTML = '';
|
this.innerHTML = '';
|
||||||
const { title, content, primaryButton, secondaryButton } = this.config;
|
const { title, content, primaryButton, secondaryButton } = this.config;
|
||||||
this.classList.add('njet-dialog');
|
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) {
|
if (title) {
|
||||||
const header = document.createElement('h2');
|
const header = document.createElement('h2');
|
||||||
header.textContent = title;
|
header.textContent = title;
|
||||||
@ -357,22 +363,14 @@ class NjetWindow extends Component {
|
|||||||
render() {
|
render() {
|
||||||
this.innerHTML = '';
|
this.innerHTML = '';
|
||||||
const { title, content, primaryButton, secondaryButton } = this.config;
|
const { title, content, primaryButton, secondaryButton } = this.config;
|
||||||
this.classList.add('njet-dialog');
|
this.classList.add('njet-window');
|
||||||
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) {
|
if (title) {
|
||||||
const header = document.createElement('h2');
|
const header = document.createElement('h2');
|
||||||
header.textContent = title;
|
header.textContent = title;
|
||||||
this.appendChild(header);
|
this.appendChild(header);
|
||||||
}
|
}
|
||||||
|
this.config.items.forEach(item => this.appendChild(item));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
import { njet } from "/njet.js"
|
import { njet } from "/njet.js"
|
||||||
|
|
||||||
function deleteChannel(channelUid){
|
app.channel = {}
|
||||||
|
|
||||||
|
|
||||||
|
app.channel.remove = function(channelUid){
|
||||||
|
|
||||||
const dialog = new njet.showDialog({
|
const dialog = new njet.showDialog({
|
||||||
title: 'Upload in progress',
|
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>
|
</script>
|
||||||
|
@ -13,6 +13,17 @@ from snek.system.view import BaseView
|
|||||||
|
|
||||||
register_heif_opener()
|
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):
|
class ChannelAttachmentView(BaseView):
|
||||||
async def get(self):
|
async def get(self):
|
||||||
relative_path = self.request.match_info.get("relative_url")
|
relative_path = self.request.match_info.get("relative_url")
|
||||||
|
@ -28,8 +28,19 @@ class DriveView(BaseView):
|
|||||||
|
|
||||||
|
|
||||||
class DriveApiView(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"))
|
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", "")
|
rel = self.request.query.get("path", "")
|
||||||
offset = int(self.request.query.get("offset", 0))
|
offset = int(self.request.query.get("offset", 0))
|
||||||
limit = int(self.request.query.get("limit", 20))
|
limit = int(self.request.query.get("limit", 20))
|
||||||
@ -40,6 +51,9 @@ class DriveApiView(BaseView):
|
|||||||
if not target.exists():
|
if not target.exists():
|
||||||
return web.json_response({"error": "Not found"}, status=404)
|
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():
|
if target.is_dir():
|
||||||
entries = []
|
entries = []
|
||||||
for p in sorted(
|
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(
|
return web.json_response(
|
||||||
{
|
{
|
||||||
"name": target.name,
|
"name": target.name,
|
||||||
|
Loading…
Reference in New Issue
Block a user