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.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