84 lines
6.3 KiB
JavaScript
84 lines
6.3 KiB
JavaScript
(()=>{
|
||
'use strict';
|
||
if(window.CateriumBranding)return;
|
||
const NAME_KEY='sunPdfBrandNameV1',LOGO_KEY='sunPdfBrandLogoV1';
|
||
const PIXEL='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScLbtAAAAABJRU5ErkJggg==';
|
||
const esc=value=>String(value??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
||
const read=key=>{try{return localStorage.getItem(key)||''}catch(_){return ''}};
|
||
const object=key=>{try{const v=JSON.parse(read(key)||'{}');return v&&typeof v==='object'&&!Array.isArray(v)?v:{}}catch(_){return {}}};
|
||
const safeLogo=src=>/^data:image\/(?:png|jpeg|webp);base64,[a-z0-9+/=\s]+$/i.test(String(src||''))&&String(src).length<=2000000?String(src):'';
|
||
const clean=value=>String(value||'').trim().slice(0,160);
|
||
function identity(){
|
||
const profile=object('sunCompanyProfileV1');
|
||
const storedName=read(NAME_KEY);
|
||
// An explicitly cleared logo must not reappear from an older profile.
|
||
let hasLogo=false;try{hasLogo=localStorage.getItem(LOGO_KEY)!==null}catch(_){}
|
||
return {
|
||
name:clean(storedName||profile.shortName||profile.name)||'Моя компания',
|
||
logo:safeLogo(hasLogo?read(LOGO_KEY):profile.logo),
|
||
city:clean(profile.city),
|
||
contacts:[profile.phone,profile.email,profile.website].map(clean).filter(Boolean).join(' · ')
|
||
};
|
||
}
|
||
function changed(){window.dispatchEvent(new CustomEvent('caterium:document-brand-changed'));}
|
||
function saveName(value){localStorage.setItem(NAME_KEY,clean(value));changed();}
|
||
function clearLogo(){localStorage.setItem(LOGO_KEY,'');changed();}
|
||
async function saveLogo(file){
|
||
const scope=()=>JSON.stringify([window.SunCloudV2?.getSession?.()?.user?.id,window.SunCloudV2?.getWorkspace?.()?.id]);
|
||
const startedIn=scope();
|
||
if(!file||!/^image\/(?:png|jpeg|webp)$/i.test(file.type))throw new Error('Выберите PNG, JPEG или WebP.');
|
||
if(file.size>15*1024*1024)throw new Error('Логотип должен быть меньше 15 МБ.');
|
||
const src=await new Promise((resolve,reject)=>{const reader=new FileReader();reader.onload=()=>resolve(String(reader.result));reader.onerror=()=>reject(new Error('Не удалось прочитать файл.'));reader.readAsDataURL(file)});
|
||
const logo=await new Promise((resolve,reject)=>{const img=new Image();img.onload=()=>resolve(img);img.onerror=()=>reject(new Error('Не удалось открыть изображение.'));img.src=src});
|
||
const scale=Math.min(1,1000/Math.max(logo.naturalWidth,logo.naturalHeight));
|
||
const canvas=document.createElement('canvas');canvas.width=Math.max(1,Math.round(logo.naturalWidth*scale));canvas.height=Math.max(1,Math.round(logo.naturalHeight*scale));
|
||
// Preserve transparency for both light and dark document templates.
|
||
canvas.getContext('2d').drawImage(logo,0,0,canvas.width,canvas.height);
|
||
const data=canvas.toDataURL('image/png');
|
||
if(!safeLogo(data))throw new Error('Изображение слишком сложное. Выберите логотип меньшего размера.');
|
||
if(startedIn!==scope())throw new Error('Аккаунт или компания изменились. Загрузите логотип ещё раз.');
|
||
localStorage.setItem(LOGO_KEY,data);changed();return data;
|
||
}
|
||
const documentName=()=>identity().name;
|
||
const documentLogo=()=>identity().logo;
|
||
const documentImage=()=>documentLogo()||PIXEL;
|
||
const documentContacts=()=>identity().contacts;
|
||
const documentCity=()=>identity().city;
|
||
function snapshot(value){const brand=identity();return {...value,brandName:brand.name,logo:brand.logo,brandContacts:brand.contacts,brandCity:brand.city};}
|
||
|
||
let sidebar={name:'Caterium',logo:'caterium-mark-light.svg',special:false};
|
||
let request=0,checkedUser='',pendingUser='';
|
||
function sidebarHTML(){return `<img class="real-logo${sidebar.special?'':' caterium-product-mark'}" src="${esc(sidebar.logo)}" alt="${esc(sidebar.name)}"><span>${esc(sidebar.name)}</span>`;}
|
||
function renderSidebar(){
|
||
const node=document.querySelector('body > header .brand');if(!node)return;
|
||
const html=sidebarHTML();if(node.innerHTML!==html)node.innerHTML=html;
|
||
node.dataset.cateriumBrand=sidebar.special?'solnce':'caterium';
|
||
}
|
||
function resetSidebar(){request++;checkedUser='';pendingUser='';sidebar={name:'Caterium',logo:'caterium-mark-light.svg',special:false};renderSidebar();}
|
||
async function refreshSidebar(){
|
||
const cloud=window.SunCloudV2,session=cloud?.getSession?.(),uid=session?.user?.id||'';
|
||
if(!uid){resetSidebar();return;}
|
||
if(checkedUser===uid||pendingUser===uid){renderSidebar();return;}
|
||
resetSidebar();pendingUser=uid;const current=request;
|
||
try{
|
||
const result=await cloud.getClient()?.rpc('caterium_my_sidebar_brand');
|
||
if(current!==request||window.SunCloudV2?.getSession?.()?.user?.id!==uid)return;
|
||
if(result?.error||!result?.data)return;
|
||
if(result.data.variant==='solnce')sidebar={name:'Солнце Кейтеринг',logo:'sun-logo.png',special:true};
|
||
checkedUser=uid;renderSidebar();
|
||
}catch(_){/* Until identity is confirmed, show the shared product brand. */}
|
||
finally{if(current===request)pendingUser='';}
|
||
}
|
||
function boot(){
|
||
const style=document.createElement('style');style.id='caterium-company-branding-style';
|
||
style.textContent='body > header .brand .caterium-product-mark{background:#fff7e6;border-radius:14px;padding:6px;filter:none!important}';document.head.appendChild(style);
|
||
renderSidebar();refreshSidebar();
|
||
}
|
||
window.CateriumBranding=Object.freeze({identity,documentName,documentLogo,documentImage,documentContacts,documentCity,
|
||
nameHTML:()=>esc(documentName()),logoHTML:()=>esc(documentImage()),contactsHTML:()=>esc(documentContacts()),cityHTML:()=>esc(documentCity()),
|
||
escapeHTML:esc,snapshot,saveName,saveLogo,clearLogo,sidebarHTML,renderSidebar,refreshSidebar,resetSidebar});
|
||
for(const event of ['sun:cloud-state-applied','sun:cloud-permissions-changed','suncloudsync'])window.addEventListener(event,()=>{refreshSidebar();changed()});
|
||
window.addEventListener('storage',event=>{if([NAME_KEY,LOGO_KEY,'sunCompanyProfileV1'].includes(event.key))changed();if(/^sb-.*-auth-token$/.test(event.key||''))resetSidebar()});
|
||
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot,{once:true});else boot();
|
||
})();
|