-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
16 lines (16 loc) · 37 KB
/
Copy pathmain.js
File metadata and controls
16 lines (16 loc) · 37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var I=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var Y=(c,i)=>{for(var e in i)I(c,e,{get:i[e],enumerable:!0})},X=(c,i,e,t)=>{if(i&&typeof i=="object"||typeof i=="function")for(let s of K(i))!J.call(c,s)&&s!==e&&I(c,s,{get:()=>i[s],enumerable:!(t=j(i,s))||t.enumerable});return c};var Q=c=>X(I({},"__esModule",{value:!0}),c);var ie={};Y(ie,{default:()=>C});module.exports=Q(ie);var n=require("obsidian"),f="gw-drive-view",y="gw-chat-view",b="gw-docs-view",k="gw-sheets-view",S="gw-notebooklm-view",E="gw-hub-view",Z=["https://www.googleapis.com/auth/drive","https://www.googleapis.com/auth/chat.spaces.readonly","https://www.googleapis.com/auth/chat.messages","https://www.googleapis.com/auth/chat.memberships","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/contacts.readonly"].join(" "),x="application/vnd.google-apps.folder",W="application/vnd.google-apps.document",q="application/vnd.google-apps.spreadsheet",H={clientId:"",clientSecret:"",accessToken:"",refreshToken:"",tokenExpiry:0,activeSpaceName:""},ee={"gw-drive":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M1.72 18.53 6.13 11l4.31 7.53zm11.55 0H3.49l2.23-3.88h9.55zM12 10.48 7.67 3h8.66zm1.23.52 4.41-7.53L21.89 11zm-1.95 3.4h8.82l-2.23 3.88H9.05z"/></svg>',"gw-chat":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></svg>',"gw-keep":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7z"/></svg>',"gw-docs":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg>',"gw-sheets":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3h5v2h-5V6zm0 3h5v2h-5V9zm0 3h5v2h-5v-2zm-5-6h3v8H7V6zm0 9h10v2H7v-2z"/></svg>',"gw-nlm":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/></svg>',"gw-hub":'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></svg>'};function _(c){let i=new Date(c),e=new Date,t=Math.floor((e.getTime()-i.getTime())/864e5);return t===0?i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):t===1?"Yesterday":t<7?i.toLocaleDateString([],{weekday:"short"}):i.toLocaleDateString([],{month:"short",day:"numeric",year:i.getFullYear()!==e.getFullYear()?"numeric":void 0})}function te(c){if(!c)return"";let i=parseInt(c);return i<1024?i+" B":i<1048576?(i/1024).toFixed(1)+" KB":i<1073741824?(i/1048576).toFixed(1)+" MB":(i/1073741824).toFixed(2)+" GB"}function $(c){return c===x?"folder":c===W?"file-text":c===q?"table":c==="application/vnd.google-apps.presentation"?"gallery-thumbnails":c==="application/vnd.google-apps.form"?"list-checks":c.startsWith("image/")?"image":c==="application/pdf"?"file-text":c.startsWith("video/")?"film":c.startsWith("audio/")?"music":"file"}function se(c){var e,t;let i=(t=(e=c.spaceType)!=null?e:c.type)!=null?t:"";return i==="DIRECT_MESSAGE"?"user":i==="GROUP_CHAT"?"users":"hash"}function U(c){return c.split(" ").map(i=>i[0]).join("").slice(0,2).toUpperCase()}function R(c){let i=["#4285F4","#EA4335","#FBBC04","#34A853","#9C27B0","#FF5722","#009688","#2196F3"],e=0;for(let t of c)e=e*31+t.charCodeAt(0)&268435455;return i[e%i.length]}function O(c){let i=new Date(c),e=new Date;return i.toDateString()===e.toDateString()?i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):i.toLocaleDateString([],{month:"short",day:"numeric"})+" "+i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}var D=class{constructor(i){this._meResourceName=null;this._userNameCache=new Map;this.driveFields="files(id,name,mimeType,modifiedTime,size,webViewLink,parents)";this.plugin=i}async getMyResourceName(){var i;if(this._meResourceName)return this._meResourceName;try{let e=await this.get("https://people.googleapis.com/v1/people/me?personFields=names");this._meResourceName=(i=e.resourceName)!=null?i:null}catch(e){}return this._meResourceName}get settings(){return this.plugin.settings}isAuthed(){return!!this.settings.accessToken}authUrl(){return"https://accounts.google.com/o/oauth2/v2/auth?"+new URLSearchParams({client_id:this.settings.clientId,redirect_uri:"http://localhost",response_type:"code",scope:Z,access_type:"offline",prompt:"consent"})}async exchangeCode(i){var t,s;let e=await(0,n.requestUrl)({url:"https://oauth2.googleapis.com/token",method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code:i,client_id:this.settings.clientId,client_secret:this.settings.clientSecret,redirect_uri:"http://localhost",grant_type:"authorization_code"}).toString()});if(e.status>=400)throw new Error((s=(t=e.json)==null?void 0:t.error_description)!=null?s:e.text);this.applyTokens(e.json),await this.plugin.saveSettings()}async refreshAccessToken(){if(!this.settings.refreshToken)throw new Error("Not authenticated.");let i=await(0,n.requestUrl)({url:"https://oauth2.googleapis.com/token",method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:this.settings.clientId,client_secret:this.settings.clientSecret,refresh_token:this.settings.refreshToken,grant_type:"refresh_token"}).toString()});if(i.status>=400)throw new Error("Token refresh failed. Re-authenticate in settings.");this.applyTokens(i.json),await this.plugin.saveSettings()}applyTokens(i){this.settings.accessToken=i.access_token,this.settings.tokenExpiry=Date.now()+i.expires_in*1e3,i.refresh_token&&(this.settings.refreshToken=i.refresh_token)}async token(){if(!this.settings.accessToken)throw new Error("Not signed in. Go to Settings \u2192 Google Workspace.");return Date.now()>this.settings.tokenExpiry-6e4&&await this.refreshAccessToken(),this.settings.accessToken}async get(i){let e=await this.token(),t=await(0,n.requestUrl)({url:i,headers:{Authorization:`Bearer ${e}`},throw:!1});if(t.status===401)return await this.refreshAccessToken(),this.get(i);if(t.status>=400)throw new Error(`${t.status}: ${t.text}`);return t.json}async patch(i,e){let t=await this.token(),s=await(0,n.requestUrl)({url:i,method:"PATCH",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(e)});if(s.status>=400)throw new Error(`${s.status}: ${s.text}`);return s.json}async post(i,e){let t=await this.token(),s=await(0,n.requestUrl)({url:i,method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(e)});if(s.status>=400)throw new Error(`${s.status}: ${s.text}`);return s.json}async listFiles(i="root"){var a;let e=encodeURIComponent(`'${i}' in parents and trashed=false`),t=encodeURIComponent(this.driveFields);return(a=(await this.get(`https://www.googleapis.com/drive/v3/files?q=${e}&fields=${t}&orderBy=folder,name&pageSize=200`)).files)!=null?a:[]}async searchFiles(i){var r;let e=i.replace(/'/g,"\\'"),t=encodeURIComponent(`name contains '${e}' and trashed=false`),s=encodeURIComponent(this.driveFields);return(r=(await this.get(`https://www.googleapis.com/drive/v3/files?q=${t}&fields=${s}&orderBy=modifiedTime desc&pageSize=100`)).files)!=null?r:[]}async listFilesOfType(i){var a;let e=encodeURIComponent(`mimeType='${i}' and trashed=false`),t=encodeURIComponent("files(id,name,mimeType,modifiedTime,webViewLink)");return(a=(await this.get(`https://www.googleapis.com/drive/v3/files?q=${e}&fields=${t}&orderBy=modifiedByMeTime desc&pageSize=200`)).files)!=null?a:[]}async getRecentFiles(i=20){var a;let e=encodeURIComponent(`trashed=false and mimeType!='${x}'`),t=encodeURIComponent("files(id,name,mimeType,modifiedTime,webViewLink)");return(a=(await this.get(`https://www.googleapis.com/drive/v3/files?q=${e}&fields=${t}&orderBy=modifiedByMeTime desc&pageSize=${i}`)).files)!=null?a:[]}async getFileName(i){return(await this.get(`https://www.googleapis.com/drive/v3/files/${i}?fields=name`)).name}async createFolder(i,e="root"){return this.post("https://www.googleapis.com/drive/v3/files",{name:i,mimeType:x,parents:[e]})}async createGoogleFile(i,e){return this.post("https://www.googleapis.com/drive/v3/files?fields=id,name,mimeType,webViewLink",{name:i,mimeType:e})}async renameFile(i,e){await this.patch(`https://www.googleapis.com/drive/v3/files/${i}`,{name:e})}async trashFile(i){await this.patch(`https://www.googleapis.com/drive/v3/files/${i}`,{trashed:!0})}async uploadFile(i,e,t,s="root"){let a=await this.token(),r="gwb"+Math.random().toString(36).slice(2),l=JSON.stringify({name:i,parents:[s]}),h=new TextEncoder,p=h.encode(`--${r}\r
Content-Type: application/json; charset=UTF-8\r
\r
${l}\r
`),o=h.encode(`--${r}\r
Content-Type: ${e}\r
\r
`),g=h.encode(`\r
--${r}--`),d=new Uint8Array(p.length+o.length+t.byteLength+g.length);d.set(p,0),d.set(o,p.length),d.set(new Uint8Array(t),p.length+o.length),d.set(g,p.length+o.length+t.byteLength);let m=await fetch("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,mimeType,webViewLink",{method:"POST",headers:{Authorization:`Bearer ${a}`,"Content-Type":`multipart/related; boundary=${r}`},body:d.buffer});if(!m.ok)throw new Error(`Upload failed: ${m.status} ${await m.text()}`);return m.json()}async listSpaces(){var e;return(e=(await this.get("https://chat.googleapis.com/v1/spaces?pageSize=100")).spaces)!=null?e:[]}async getMessages(i){var t;return((t=(await this.get(`https://chat.googleapis.com/v1/${i}/messages?pageSize=50&orderBy=createTime desc`)).messages)!=null?t:[]).reverse()}async getNewMessages(i,e){var a;let t=encodeURIComponent(`createTime > "${e}"`);return(a=(await this.get(`https://chat.googleapis.com/v1/${i}/messages?pageSize=50&filter=${t}&orderBy=createTime asc`)).messages)!=null?a:[]}async sendMessage(i,e){return this.post(`https://chat.googleapis.com/v1/${i}/messages`,{text:e})}async getUserDisplayName(i){var t,s,a;if(this._userNameCache.has(i))return this._userNameCache.get(i);let e=i.replace(/^(people|users)\//,"");try{let l=(a=(s=(t=(await this.get(`https://people.googleapis.com/v1/people/${e}?personFields=names`)).names)==null?void 0:t[0])==null?void 0:s.displayName)!=null?a:"";return l&&this._userNameCache.set(i,l),l||"Direct Message"}catch(r){return"Direct Message"}}async getDmDisplayName(i){var l,h;let[e,t]=await Promise.all([this.get(`https://chat.googleapis.com/v1/${i}/members?pageSize=20`),this.getMyResourceName()]),s=t==null?void 0:t.replace(/^(people|users)\//,""),r=((l=e.memberships)!=null?l:[]).find(p=>{var o,g;return((o=p.member)==null?void 0:o.type)==="HUMAN"&&((g=p.member)==null?void 0:g.name)&&p.member.name.replace("users/","")!==s});return(h=r==null?void 0:r.member)!=null&&h.name?this.getUserDisplayName(r.member.name):"Direct Message"}};function T(c,...i){let e=c.children[1];e.empty(),e.style.padding="0";for(let s of i)e.addClass(s);let t=c;for(;t&&!t.classList.contains("workspace-split");)t.style.height="100%",t.style.minHeight="0",t=t.parentElement;return e}function G(c,i){c.empty();let e=c.createEl("div",{cls:"gw-empty-state"}),t=e.createEl("div",{cls:"gw-empty-icon"});(0,n.setIcon)(t,"log-in"),e.createEl("div",{cls:"gw-empty-title",text:"Sign in to Google"}),e.createEl("div",{cls:"gw-empty-sub",text:"Connect your Google account in Settings \u2192 Google Workspace."}),e.createEl("button",{cls:"gw-cta-btn",text:"Open Settings"}).addEventListener("click",()=>{var a;(a=i.app.setting)==null||a.openTabById(i.manifest.id)})}var v=class extends n.Modal{constructor(i,e,t,s,a){super(i),this.label=e,this.placeholder=t,this.initial=s,this.onSubmit=a}onOpen(){let{contentEl:i}=this;i.createEl("h3",{text:this.label,cls:"gw-modal-title"});let e=i.createEl("input",{cls:"gw-modal-input",attr:{type:"text",placeholder:this.placeholder,value:this.initial}});e.select();let t=i.createEl("div",{cls:"gw-modal-row"}),s=t.createEl("button",{cls:"gw-cta-btn",text:"OK"}),a=t.createEl("button",{cls:"gw-btn",text:"Cancel"}),r=()=>{let l=e.value.trim();l&&(this.close(),this.onSubmit(l))};s.addEventListener("click",r),a.addEventListener("click",()=>this.close()),e.addEventListener("keydown",l=>{l.key==="Enter"&&r(),l.key==="Escape"&&this.close()}),setTimeout(()=>e.focus(),50)}onClose(){this.contentEl.empty()}},M=class extends n.Modal{constructor(i,e,t){super(i),this.authUrl=e,this.onCode=t,this.modalEl.addClass("gw-auth-modal")}onOpen(){let{contentEl:i}=this;i.createEl("div",{cls:"gw-auth-header",text:"Sign in with Google"});let e=document.createElement("webview");e.setAttribute("src",this.authUrl),e.setAttribute("partition","persist:gw-auth"),e.style.width="100%",e.style.height="520px",e.style.border="none",i.appendChild(e);let t=s=>{if(s.startsWith("http://localhost"))try{let a=new URL(s).searchParams.get("code");a&&(this.close(),this.onCode(a))}catch(a){}};e.addEventListener("did-navigate",s=>t(s.url)),e.addEventListener("will-navigate",s=>t(s.url)),e.addEventListener("did-navigate-in-page",s=>t(s.url)),e.addEventListener("did-fail-load",s=>{var a;(a=s.validatedURL)!=null&&a.startsWith("http://localhost")&&t(s.validatedURL)})}onClose(){this.contentEl.empty()}},F=class extends n.ItemView{constructor(e,t){super(e);this.breadcrumb=[{id:"root",name:"My Drive"}];this.allFiles=[];this.isSearching=!1;this.plugin=t}getViewType(){return f}getDisplayText(){return"Google Drive"}getIcon(){return"gw-drive"}async onOpen(){this.build(),this.plugin.api.isAuthed()?await this.loadFiles():G(this.listEl,this.plugin)}build(){let e=T(this.containerEl,"gw-root"),t=e.createEl("div",{cls:"gw-toolbar"}),s=t.createEl("button",{cls:"gw-action-btn",attr:{title:"New folder"}});(0,n.setIcon)(s.createEl("span",{cls:"gw-btn-icon"}),"folder-plus"),s.appendChild(document.createTextNode(" New folder")),s.addEventListener("click",()=>this.newFolder());let a=t.createEl("button",{cls:"gw-action-btn",attr:{title:"Upload file"}});(0,n.setIcon)(a.createEl("span",{cls:"gw-btn-icon"}),"upload"),a.appendChild(document.createTextNode(" Upload")),a.addEventListener("click",()=>this.uploadFile()),t.createEl("div",{cls:"gw-spacer"});let r=t.createEl("div",{cls:"gw-search-wrap"}),l=r.createEl("span",{cls:"gw-search-icon"});(0,n.setIcon)(l,"search"),this.searchInput=r.createEl("input",{cls:"gw-search-input",attr:{placeholder:"Search Drive\u2026",type:"text"}});let h;this.searchInput.addEventListener("input",()=>{clearTimeout(h);let o=this.searchInput.value.trim();if(!o){this.isSearching=!1,this.renderFiles(this.allFiles);return}this.isSearching=!0,h=window.setTimeout(()=>this.doSearch(o),400)}),this.searchInput.addEventListener("keydown",o=>{o.key==="Escape"&&(this.searchInput.value="",this.isSearching=!1,this.renderFiles(this.allFiles))});let p=t.createEl("button",{cls:"gw-icon-btn",attr:{title:"Refresh"}});(0,n.setIcon)(p,"refresh-cw"),p.addEventListener("click",()=>this.loadFiles()),this.breadcrumbEl=e.createEl("div",{cls:"gw-breadcrumb"}),this.renderBreadcrumb(),this.listEl=e.createEl("div",{cls:"gw-file-list"})}renderBreadcrumb(){this.breadcrumbEl.empty(),this.breadcrumb.forEach((e,t)=>{let s=this.breadcrumbEl.createEl("span",{cls:"gw-crumb",text:e.name});t<this.breadcrumb.length-1&&(s.addClass("gw-crumb-link"),s.addEventListener("click",()=>{this.breadcrumb=this.breadcrumb.slice(0,t+1),this.loadFiles()}),this.breadcrumbEl.createEl("span",{cls:"gw-crumb-sep",text:" \u203A "}))})}currentFolderId(){return this.breadcrumb[this.breadcrumb.length-1].id}async loadFiles(){this.listEl.empty(),this.listEl.createEl("div",{cls:"gw-loading",text:"Loading\u2026"}),this.renderBreadcrumb();try{this.allFiles=await this.plugin.api.listFiles(this.currentFolderId()),this.renderFiles(this.allFiles)}catch(e){this.listEl.empty(),this.listEl.createEl("div",{cls:"gw-error",text:String(e)})}}async doSearch(e){this.listEl.empty(),this.listEl.createEl("div",{cls:"gw-loading",text:"Searching\u2026"});try{let t=await this.plugin.api.searchFiles(e);this.renderFiles(t)}catch(t){this.listEl.empty(),this.listEl.createEl("div",{cls:"gw-error",text:String(t)})}}renderFiles(e){if(this.listEl.empty(),!e.length){let s=this.listEl.createEl("div",{cls:"gw-empty-state"});(0,n.setIcon)(s.createEl("div",{cls:"gw-empty-icon"}),"folder-open"),s.createEl("div",{cls:"gw-empty-title",text:this.isSearching?"No results":"This folder is empty"});return}let t=this.listEl.createEl("div",{cls:"gw-file-header"});t.createEl("span",{cls:"gw-fh-name",text:"Name"}),t.createEl("span",{cls:"gw-fh-date",text:"Modified"}),t.createEl("span",{cls:"gw-fh-size",text:"Size"});for(let s of e){let a=this.listEl.createEl("div",{cls:"gw-file-row"}),r=a.createEl("span",{cls:"gw-file-icon"});(0,n.setIcon)(r,$(s.mimeType));let l=a.createEl("span",{cls:"gw-file-name",text:s.name});a.createEl("span",{cls:"gw-file-date",text:_(s.modifiedTime)}),a.createEl("span",{cls:"gw-file-size",text:te(s.size)}),s.mimeType===x?(a.addClass("is-folder"),l.addEventListener("click",()=>{this.breadcrumb.push({id:s.id,name:s.name}),this.loadFiles()}),a.addEventListener("dblclick",()=>{this.breadcrumb.push({id:s.id,name:s.name}),this.loadFiles()})):(a.addEventListener("dblclick",()=>{s.webViewLink&&window.open(s.webViewLink,"_blank")}),l.addEventListener("click",()=>{s.webViewLink&&window.open(s.webViewLink,"_blank")})),a.addEventListener("contextmenu",h=>{h.preventDefault();let p=new n.Menu;s.webViewLink&&p.addItem(o=>o.setIcon("external-link").setTitle("Open in browser").onClick(()=>window.open(s.webViewLink,"_blank"))),p.addItem(o=>o.setIcon("pencil").setTitle("Rename").onClick(()=>new v(this.app,"Rename","New name",s.name,async g=>{try{await this.plugin.api.renameFile(s.id,g),await this.loadFiles()}catch(d){new n.Notice("Rename failed: "+d)}}).open())),p.addItem(o=>o.setIcon("trash").setTitle("Move to trash").onClick(async()=>{try{await this.plugin.api.trashFile(s.id),await this.loadFiles(),new n.Notice(`"${s.name}" moved to trash.`)}catch(g){new n.Notice("Error: "+g)}})),s.webViewLink&&(p.addSeparator(),p.addItem(o=>o.setIcon("link").setTitle("Copy link").onClick(()=>{navigator.clipboard.writeText(s.webViewLink),new n.Notice("Link copied")}))),p.showAtMouseEvent(h)})}}newFolder(){new v(this.app,"New folder","Folder name","",async e=>{try{await this.plugin.api.createFolder(e,this.currentFolderId()),await this.loadFiles()}catch(t){new n.Notice("Error creating folder: "+t)}}).open()}uploadFile(){let e=document.createElement("input");e.type="file",e.multiple=!0,e.addEventListener("change",async()=>{var s;let t=Array.from((s=e.files)!=null?s:[]);if(t.length){for(let a of t){let r=new n.Notice(`Uploading ${a.name}\u2026`,0);try{let l=await a.arrayBuffer();await this.plugin.api.uploadFile(a.name,a.type||"application/octet-stream",l,this.currentFolderId()),r.hide(),new n.Notice(`\u2713 Uploaded ${a.name}`)}catch(l){r.hide(),new n.Notice(`Upload failed: ${l}`)}}await this.loadFiles()}}),e.click()}},L=class extends n.ItemView{constructor(e,t){super(e);this.files=[];this.plugin=t}async onOpen(){this.build(),this.plugin.api.isAuthed()?await this.loadList():G(this.listEl,this.plugin)}build(){let e=T(this.containerEl,"gw-root"),t=e.createEl("div",{cls:"gw-toolbar"}),s=t.createEl("button",{cls:"gw-action-btn"});(0,n.setIcon)(s.createEl("span",{cls:"gw-btn-icon"}),"plus"),s.appendChild(document.createTextNode(" "+this.getNewLabel())),s.addEventListener("click",()=>this.createNew()),t.createEl("div",{cls:"gw-spacer"});let a=t.createEl("div",{cls:"gw-search-wrap"});(0,n.setIcon)(a.createEl("span",{cls:"gw-search-icon"}),"search");let r=a.createEl("input",{cls:"gw-search-input",attr:{placeholder:`Filter ${this.getDisplayText()}\u2026`,type:"text"}});r.addEventListener("input",()=>{let h=r.value.toLowerCase();this.renderFiles(h?this.files.filter(p=>p.name.toLowerCase().includes(h)):this.files)});let l=t.createEl("button",{cls:"gw-icon-btn",attr:{title:"Refresh"}});(0,n.setIcon)(l,"refresh-cw"),l.addEventListener("click",()=>this.loadList()),this.listEl=e.createEl("div",{cls:"gw-file-list"})}async loadList(){this.listEl.empty(),this.listEl.createEl("div",{cls:"gw-loading",text:"Loading\u2026"});try{this.files=await this.plugin.api.listFilesOfType(this.getMimeType()),this.renderFiles(this.files)}catch(e){this.listEl.empty(),this.listEl.createEl("div",{cls:"gw-error",text:String(e)})}}renderFiles(e){if(this.listEl.empty(),!e.length){let s=this.listEl.createEl("div",{cls:"gw-empty-state"});(0,n.setIcon)(s.createEl("div",{cls:"gw-empty-icon"}),"file"),s.createEl("div",{cls:"gw-empty-title",text:`No ${this.getDisplayText()} found`});return}let t=this.listEl.createEl("div",{cls:"gw-file-header"});t.createEl("span",{cls:"gw-fh-name",text:"Name"}),t.createEl("span",{cls:"gw-fh-date",text:"Modified"}),t.createEl("span",{cls:"gw-fh-size"});for(let s of e){let a=this.listEl.createEl("div",{cls:"gw-file-row"});(0,n.setIcon)(a.createEl("span",{cls:"gw-file-icon"}),$(s.mimeType));let r=a.createEl("span",{cls:"gw-file-name",text:s.name});a.createEl("span",{cls:"gw-file-date",text:_(s.modifiedTime)}),a.createEl("span",{cls:"gw-file-size"});let l=()=>{s.webViewLink&&window.open(s.webViewLink,"_blank")};r.addEventListener("click",l),a.addEventListener("dblclick",l),a.addEventListener("contextmenu",h=>{h.preventDefault();let p=new n.Menu;s.webViewLink&&p.addItem(o=>o.setIcon("external-link").setTitle("Open in browser").onClick(l)),p.addItem(o=>o.setIcon("pencil").setTitle("Rename").onClick(()=>new v(this.app,"Rename","New name",s.name,async g=>{try{await this.plugin.api.renameFile(s.id,g),await this.loadList()}catch(d){new n.Notice("Rename failed: "+d)}}).open())),p.addItem(o=>o.setIcon("trash").setTitle("Move to trash").onClick(async()=>{try{await this.plugin.api.trashFile(s.id),await this.loadList()}catch(g){new n.Notice("Error: "+g)}})),s.webViewLink&&(p.addSeparator(),p.addItem(o=>o.setIcon("link").setTitle("Copy link").onClick(()=>{navigator.clipboard.writeText(s.webViewLink),new n.Notice("Link copied")}))),p.showAtMouseEvent(h)})}}async createNew(){new v(this.app,this.getNewLabel(),"Untitled","",async e=>{try{let t=await this.plugin.api.createGoogleFile(e,this.getMimeType());t.webViewLink&&window.open(t.webViewLink,"_blank"),await this.loadList()}catch(t){new n.Notice("Error: "+t)}}).open()}},N=class extends L{getViewType(){return b}getDisplayText(){return"Google Docs"}getIcon(){return"gw-docs"}getMimeType(){return W}getNewLabel(){return"New Doc"}},P=class extends L{getViewType(){return k}getDisplayText(){return"Google Sheets"}getIcon(){return"gw-sheets"}getMimeType(){return q}getNewLabel(){return"New Sheet"}};var A=class extends n.ItemView{constructor(i,e){super(i),this.plugin=e}getViewType(){return S}getDisplayText(){return"NotebookLM"}getIcon(){return"gw-nlm"}async onOpen(){let i=T(this.containerEl,"gw-nlm-root");i.style.position="relative";let e=document.createElement("webview");e.setAttribute("src","https://notebooklm.google.com"),e.setAttribute("partition","persist:gw-nlm"),e.style.cssText="position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;border:none;",i.appendChild(e);let t=()=>{try{e.insertCSS(":root, html, body { color-scheme: dark !important; }"),e.executeJavaScript(`
try {
document.documentElement.setAttribute('data-theme','dark');
document.body.setAttribute('data-theme','dark');
document.documentElement.classList.add('dark-theme','dark');
document.body.classList.add('dark-theme','dark');
} catch(e){}
`).catch(()=>{})}catch(s){}};e.addEventListener("did-finish-load",()=>{t(),setTimeout(t,1500)})}},B=class extends n.ItemView{constructor(e,t){super(e);this.spaces=[];this.activeSpace=null;this.messages=[];this.pollTimer=null;this.plugin=t}getViewType(){return y}getDisplayText(){return"Google Chat"}getIcon(){return"gw-chat"}async onOpen(){this.buildUI(),this.plugin.api.isAuthed()?await this.loadSpaces():this.showSignIn()}buildUI(){let e=T(this.containerEl,"gw-chat-root"),t=e.createEl("div",{cls:"gw-chat-sidebar"}),s=t.createEl("div",{cls:"gw-chat-side-header"});s.createEl("span",{cls:"gw-chat-side-title",text:"Google Chat"});let a=s.createEl("button",{cls:"gw-icon-btn"});(0,n.setIcon)(a,"refresh-cw"),a.addEventListener("click",()=>this.loadSpaces());let r=t.createEl("div",{cls:"gw-chat-search"});(0,n.setIcon)(r.createEl("span",{cls:"gw-search-icon"}),"search");let l=r.createEl("input",{cls:"gw-search-input",attr:{placeholder:"Search spaces\u2026",type:"text"}});l.addEventListener("input",()=>{let w=l.value.toLowerCase();this.renderSpaces(w?this.spaces.filter(u=>(u.displayName||"").toLowerCase().includes(w)):this.spaces)}),this.spaceListEl=t.createEl("div",{cls:"gw-chat-space-list"});let h=e.createEl("div",{cls:"gw-chat-main"}),p=h.createEl("div",{cls:"gw-chat-header"}),o=p.createEl("div",{cls:"gw-chat-header-left"});(0,n.setIcon)(o.createEl("span",{cls:"gw-chat-header-icon"}),"hash"),this.headerTitleEl=o.createEl("span",{cls:"gw-chat-header-title",text:"Select a space"});let g=p.createEl("button",{cls:"gw-icon-btn"});(0,n.setIcon)(g,"refresh-cw"),g.addEventListener("click",()=>{this.activeSpace&&this.loadMessages(this.activeSpace)}),this.messagesEl=h.createEl("div",{cls:"gw-chat-messages"});let m=h.createEl("div",{cls:"gw-chat-input-area"}).createEl("div",{cls:"gw-chat-input-wrap"});this.inputEl=m.createEl("textarea",{cls:"gw-chat-input",attr:{placeholder:"Message\u2026",rows:"1"}}),this.inputEl.addEventListener("input",()=>{this.inputEl.style.height="auto",this.inputEl.style.height=Math.min(this.inputEl.scrollHeight,120)+"px",this.sendBtn.disabled=!this.inputEl.value.trim()}),this.inputEl.addEventListener("keydown",w=>{w.key==="Enter"&&!w.shiftKey&&(w.preventDefault(),this.send())}),this.sendBtn=m.createEl("button",{cls:"gw-chat-send-btn",attr:{disabled:"true",title:"Send (Enter)"}}),(0,n.setIcon)(this.sendBtn,"send"),this.sendBtn.addEventListener("click",()=>this.send())}showSignIn(){this.messagesEl.empty(),G(this.messagesEl,this.plugin)}async loadSpaces(){this.spaceListEl.empty(),this.spaceListEl.createEl("div",{cls:"gw-loading",text:"Loading spaces\u2026"});try{if(this.spaces=await this.plugin.api.listSpaces(),this.renderSpaces(this.spaces),this.plugin.settings.activeSpaceName){let t=this.spaces.find(s=>s.name===this.plugin.settings.activeSpaceName);t&&this.selectSpace(t)}let e=this.spaces.filter(t=>{var s;return((s=t.spaceType)!=null?s:t.type)==="DIRECT_MESSAGE"&&!t.displayName});e.length&&(await Promise.all(e.map(async t=>{try{t.displayName=await this.plugin.api.getDmDisplayName(t.name)}catch(s){}})),this.renderSpaces(this.spaces))}catch(e){this.spaceListEl.empty(),this.spaceListEl.createEl("div",{cls:"gw-error",text:String(e)})}}renderSpaces(e){this.spaceListEl.empty();let t=e.filter(r=>{var l;return!["DIRECT_MESSAGE","GROUP_CHAT"].includes((l=r.spaceType)!=null?l:r.type)}),s=e.filter(r=>{var l;return((l=r.spaceType)!=null?l:r.type)==="GROUP_CHAT"}),a=e.filter(r=>{var l;return((l=r.spaceType)!=null?l:r.type)==="DIRECT_MESSAGE"});t.length&&this.renderSpaceGroup("Spaces",t),s.length&&this.renderSpaceGroup("Group chats",s),a.length&&this.renderSpaceGroup("Direct messages",a),e.length||this.spaceListEl.createEl("div",{cls:"gw-loading",text:"No spaces found."})}renderSpaceGroup(e,t){var s;this.spaceListEl.createEl("div",{cls:"gw-chat-group-label",text:e});for(let a of t){let r=this.spaceListEl.createEl("div",{cls:`gw-chat-space-row${a.name===((s=this.activeSpace)==null?void 0:s.name)?" is-active":""}`,attr:{"data-name":a.name}});(0,n.setIcon)(r.createEl("span",{cls:"gw-chat-space-icon"}),se(a)),r.createEl("span",{cls:"gw-chat-space-name",text:a.displayName||"Direct Message"}),r.addEventListener("click",()=>this.selectSpace(a))}}async selectSpace(e){this.activeSpace=e,this.plugin.settings.activeSpaceName=e.name,await this.plugin.saveSettings(),this.spaceListEl.querySelectorAll(".gw-chat-space-row").forEach(t=>t.toggleClass("is-active",t.getAttribute("data-name")===e.name)),this.headerTitleEl.textContent=e.displayName||"Direct Message",this.stopPoll(),await this.loadMessages(e),this.startPoll(e)}async resolveSenderNames(e){let t=[...new Set(e.map(s=>{var a;return(a=s.sender)==null?void 0:a.name}).filter(Boolean))];await Promise.all(t.map(async s=>{let a=await this.plugin.api.getUserDisplayName(s);e.filter(r=>{var l;return((l=r.sender)==null?void 0:l.name)===s}).forEach(r=>{r.sender.displayName=a})}))}async loadMessages(e){this.messagesEl.empty(),this.messagesEl.createEl("div",{cls:"gw-loading",text:"Loading messages\u2026"});try{this.messages=await this.plugin.api.getMessages(e.name),await this.resolveSenderNames(this.messages),this.renderMessages()}catch(t){this.messagesEl.empty(),this.messagesEl.createEl("div",{cls:"gw-error",text:String(t)})}}renderMessages(){var s,a,r,l;if(this.messagesEl.empty(),!this.messages.length){this.messagesEl.createEl("div",{cls:"gw-loading",text:"No messages yet."});return}let e="",t="";for(let h of this.messages){let p=new Date(h.createTime).toDateString();p!==t&&(this.messagesEl.createEl("div",{cls:"gw-chat-date-divider",text:new Date(h.createTime).toLocaleDateString([],{weekday:"long",month:"long",day:"numeric"})}),t=p,e="");let o=(a=(s=h.sender)==null?void 0:s.displayName)!=null?a:"Unknown",g=o===e;e=o;let d=this.messagesEl.createEl("div",{cls:`gw-chat-msg-row${g?" is-grouped":""}`});if(g)d.createEl("div",{cls:"gw-chat-avatar-spacer"});else{let u=d.createEl("div",{cls:"gw-chat-avatar"});u.style.background=R(o),u.textContent=U(o)}let m=d.createEl("div",{cls:"gw-chat-bubble"});if(!g){let u=m.createEl("div",{cls:"gw-chat-msg-meta"});u.createEl("span",{cls:"gw-chat-msg-sender",text:o}),u.createEl("span",{cls:"gw-chat-msg-time",text:O(h.createTime)})}let w=(l=(r=h.text)!=null?r:h.formattedText)!=null?l:"";m.createEl("div",{cls:"gw-chat-msg-body",text:w})}this.messagesEl.scrollTop=this.messagesEl.scrollHeight}async appendNewMessages(e){var s,a,r,l;if(!e.length)return;await this.resolveSenderNames(e),this.messages.push(...e);let t=this.messagesEl.scrollHeight-this.messagesEl.scrollTop-this.messagesEl.clientHeight<80;for(let h of e){let p=(a=(s=h.sender)==null?void 0:s.displayName)!=null?a:"Unknown",o=this.messagesEl.createEl("div",{cls:"gw-chat-msg-row gw-chat-msg-new"}),g=o.createEl("div",{cls:"gw-chat-avatar"});g.style.background=R(p),g.textContent=U(p);let d=o.createEl("div",{cls:"gw-chat-bubble"}),m=d.createEl("div",{cls:"gw-chat-msg-meta"});m.createEl("span",{cls:"gw-chat-msg-sender",text:p}),m.createEl("span",{cls:"gw-chat-msg-time",text:O(h.createTime)});let w=(l=(r=h.text)!=null?r:h.formattedText)!=null?l:"";d.createEl("div",{cls:"gw-chat-msg-body",text:w})}t&&(this.messagesEl.scrollTop=this.messagesEl.scrollHeight)}async send(){let e=this.inputEl.value.trim();if(!(!e||!this.activeSpace)){this.inputEl.value="",this.inputEl.style.height="auto",this.sendBtn.disabled=!0;try{let t=await this.plugin.api.sendMessage(this.activeSpace.name,e);this.appendNewMessages([t])}catch(t){new n.Notice(`Failed to send: ${t}`),this.inputEl.value=e,this.sendBtn.disabled=!1}}}startPoll(e){this.pollTimer=window.setInterval(async()=>{if(!this.messages.length)return;let t=this.messages[this.messages.length-1].createTime;try{let s=await this.plugin.api.getNewMessages(e.name,t);this.appendNewMessages(s)}catch(s){}},8e3)}stopPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null)}async onClose(){this.stopPoll()}},z=class extends n.ItemView{constructor(i,e){super(i),this.plugin=e}getViewType(){return E}getDisplayText(){return"Google Workspace"}getIcon(){return"gw-hub"}async onOpen(){let i=T(this.containerEl,"gw-root","gw-hub-root");i.createEl("div",{cls:"gw-hub-title",text:"Google Workspace"});let e=i.createEl("div",{cls:"gw-hub-grid"}),t=[{view:f,icon:"gw-drive",label:"Drive",sub:"File storage"},{view:b,icon:"gw-docs",label:"Docs",sub:"Documents"},{view:k,icon:"gw-sheets",label:"Sheets",sub:"Spreadsheets"},{view:y,icon:"gw-chat",label:"Chat",sub:"Messaging"},{view:S,icon:"gw-nlm",label:"NotebookLM",sub:"AI notebooks"}];for(let r of t){let l=e.createEl("div",{cls:"gw-hub-btn"});(0,n.setIcon)(l.createEl("div",{cls:"gw-hub-btn-icon"}),r.icon),l.createEl("div",{cls:"gw-hub-btn-label",text:r.label}),l.createEl("div",{cls:"gw-hub-btn-sub",text:r.sub}),l.addEventListener("click",()=>this.plugin.openService(r.view))}if(!this.plugin.api.isAuthed())return;let s=i.createEl("div",{cls:"gw-hub-section"});s.createEl("div",{cls:"gw-hub-section-title",text:"Recent files"});let a=s.createEl("div",{cls:"gw-hub-recent"});a.createEl("div",{cls:"gw-loading",text:"Loading recent files\u2026"});try{let r=await this.plugin.api.getRecentFiles(10);if(a.empty(),!r.length)a.createEl("div",{cls:"gw-loading",text:"No recent files."});else for(let l of r){let h=a.createEl("div",{cls:"gw-file-row"});(0,n.setIcon)(h.createEl("span",{cls:"gw-file-icon"}),$(l.mimeType));let p=h.createEl("span",{cls:"gw-file-name",text:l.name});h.createEl("span",{cls:"gw-file-date",text:_(l.modifiedTime)}),h.createEl("span",{cls:"gw-file-size"});let o=()=>{l.webViewLink&&window.open(l.webViewLink,"_blank")};p.addEventListener("click",o),h.addEventListener("dblclick",o)}}catch(r){a.empty(),a.createEl("div",{cls:"gw-error",text:String(r)})}}},V=class extends n.PluginSettingTab{constructor(i,e){super(i,e),this.plugin=e}display(){let{containerEl:i}=this;i.empty(),i.createEl("p",{cls:"gw-settings-note",text:"Create a project in Google Cloud Console, enable the Drive API, Chat API, and People API, then create OAuth 2.0 credentials (Desktop app type). Paste your Client ID and Secret below."}),new n.Setting(i).setName("Client ID").addText(e=>e.setPlaceholder("123\u2026.apps.googleusercontent.com").setValue(this.plugin.settings.clientId).onChange(async t=>{this.plugin.settings.clientId=t.trim(),await this.plugin.saveSettings()})),new n.Setting(i).setName("Client Secret").addText(e=>{e.inputEl.type="password",e.setPlaceholder("GOCSPX-\u2026").setValue(this.plugin.settings.clientSecret).onChange(async t=>{this.plugin.settings.clientSecret=t.trim(),await this.plugin.saveSettings()})}),this.plugin.settings.accessToken?new n.Setting(i).setName("Status").setDesc("\u2713 Connected to Google").addButton(e=>e.setButtonText("Sign out").onClick(async()=>{this.plugin.settings.accessToken="",this.plugin.settings.refreshToken="",this.plugin.settings.tokenExpiry=0,await this.plugin.saveSettings(),this.display(),new n.Notice("Signed out.")})):new n.Setting(i).setName("Sign in").setDesc("Connect your Google account (Drive, Chat, Docs, Sheets).").addButton(e=>e.setButtonText("Sign in with Google").setCta().onClick(()=>{if(!this.plugin.settings.clientId||!this.plugin.settings.clientSecret){new n.Notice("Enter Client ID and Secret first.");return}new M(this.app,this.plugin.api.authUrl(),async t=>{try{await this.plugin.api.exchangeCode(t),new n.Notice("Connected to Google Workspace!"),this.display()}catch(s){new n.Notice(`Auth failed: ${s}`,8e3)}}).open()})),new n.Setting(i).setName("Reload plugin").setDesc("Applies credential changes.").addButton(e=>e.setButtonText("Reload").onClick(async()=>{e.setButtonText("Reloading\u2026").setDisabled(!0),await this.app.plugins.disablePlugin(this.plugin.manifest.id),await this.app.plugins.enablePlugin(this.plugin.manifest.id)}))}},C=class extends n.Plugin{constructor(){super(...arguments);this.settings=H}async onload(){await this.loadSettings(),this.api=new D(this),Object.entries(ee).forEach(([t,s])=>(0,n.addIcon)(t,s)),this.registerView(f,t=>new F(t,this)),this.registerView(b,t=>new N(t,this)),this.registerView(k,t=>new P(t,this)),this.registerView(y,t=>new B(t,this)),this.registerView(S,t=>new A(t,this)),this.registerView(E,t=>new z(t,this));let e=this.addRibbonIcon("gw-hub","Google Workspace",()=>this.openService(E));e.addClass("gw-ribbon-icon"),e.addEventListener("contextmenu",t=>{let s=new n.Menu;s.addItem(a=>a.setIcon("gw-hub").setTitle("Workspace Hub").onClick(()=>this.openService(E))),s.addSeparator(),s.addItem(a=>a.setIcon("gw-drive").setTitle("Drive").onClick(()=>this.openService(f))),s.addItem(a=>a.setIcon("gw-docs").setTitle("Docs").onClick(()=>this.openService(b))),s.addItem(a=>a.setIcon("gw-sheets").setTitle("Sheets").onClick(()=>this.openService(k))),s.addItem(a=>a.setIcon("gw-chat").setTitle("Chat").onClick(()=>this.openService(y))),s.addItem(a=>a.setIcon("gw-nlm").setTitle("NotebookLM").onClick(()=>this.openService(S))),s.showAtMouseEvent(t)}),this.addCommand({id:"open-hub",name:"Open Workspace Hub",callback:()=>this.openService(E)}),this.addCommand({id:"open-drive",name:"Open Google Drive",callback:()=>this.openService(f)}),this.addCommand({id:"open-docs",name:"Open Google Docs",callback:()=>this.openService(b)}),this.addCommand({id:"open-sheets",name:"Open Google Sheets",callback:()=>this.openService(k)}),this.addCommand({id:"open-chat",name:"Open Google Chat",callback:()=>this.openService(y)}),this.addCommand({id:"open-notebooklm",name:"Open NotebookLM",callback:()=>this.openService(S)}),this.addSettingTab(new V(this.app,this))}async openService(e){let{workspace:t}=this.app,s=t.getLeavesOfType(e);if(s.length){t.revealLeaf(s[0]);return}let a=t.getLeaf("tab");await a.setViewState({type:e,active:!0}),t.revealLeaf(a)}async loadSettings(){this.settings=Object.assign({},H,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}};