Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23,681 changes: 11,593 additions & 12,088 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 4 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solid-panes",
"version": "4.4.2-4",
"version": "4.4.2-5",
"description": "Solid-compatible Panes: applets and views for the mashlib and databrowser",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -58,7 +58,7 @@
"dependencies": {
"@solid/better-simple-slideshow": "^0.1.0",
"activitystreams-pane": "1.0.3-4",
"chat-pane": "3.0.4-2",
"chat-pane": "3.0.4-3",
"contacts-pane": "3.2.1-5",
"dompurify": "^3.4.4",
"folder-pane": "3.1.1-2",
Expand All @@ -68,18 +68,12 @@
"meeting-pane": "3.0.3-1",
"mime-types": "^3.0.2",
"pane-registry": "3.1.2-2",
"profile-pane": "3.2.3-3",
"profile-pane": "3.2.3-4",
"rdflib": "2.4.0",
"solid-logic": "4.0.8-1",
"solid-namespace": "^0.5.4",
"solid-ui": "3.1.3-13",
"source-pane": "3.1.1-4"
},
"overrides": {
"rdflib": "$rdflib",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because rdflib is not in my solidos setup I didn't have to remove this one. Thought I'd just mention.

"solid-logic": "$solid-logic",
"solid-ui": "$solid-ui",
"pane-registry": "$pane-registry"
"source-pane": "3.1.1-5"
},
"devDependencies": {
"@iconify/json": "2.2.494",
Expand Down
26 changes: 26 additions & 0 deletions src/components/navbar/Navbar.styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
:host {
.navbar {
border: 1px solid var(--color-border,#444);
border-radius: 5px;
display: flex;
background: var(--solid-ui-color-white, #fff);
overflow: hidden;
}

button {
padding: 10px 25px;
border-bottom: 2px solid transparent;
font-weight: 500;
font-size: 90%;
}

button:active,
button:hover,
button:focus {
border-bottom-color: var(--solid-ui-color-primary, #7C4DFF);
border-radius: 0;
color: var(--solid-ui-color-primary, #7C4DFF);
text-transform: capitalize;
background: color-mix(in srgb, currentColor 25%, transparent);
}
}
43 changes: 43 additions & 0 deletions src/components/navbar/Navbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { customElement, WebComponent } from 'solid-ui'
import { html, TemplateResult } from 'lit'
import { property } from 'lit/decorators.js'

import 'solid-ui/components/account'
import 'solid-ui/components/button'
import 'solid-ui/components/menu-item'
import 'solid-ui/components/menu'
import 'solid-ui/components/solid-emblem'
import '~icons/lucide/help-circle'

import styles from './Navbar.styles.css'

export interface NavbarMenuItem {
label: string | TemplateResult
href?: string
selected?: boolean
onSelected?(): void
}

@customElement('solid-panes-navbar')
export default class Navbar extends WebComponent {
static styles = styles

@property({ type: Array })
accessor navbarItems: NavbarMenuItem[] = []

render () {
return html`
<nav class="navbar">
${this.navbarItems.map(menuItem => html`
<button
type="button"
@click=${() => menuItem.onSelected?.()}
title=${typeof menuItem.label === 'string' ? menuItem.label : ''}
>
${menuItem.label}
</button>
`)}
</nav>
`
}
}
4 changes: 4 additions & 0 deletions src/components/navbar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Navbar from './Navbar'

export { Navbar }
export default Navbar
4 changes: 3 additions & 1 deletion src/mainPage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { LiveStore, NamedNode } from 'rdflib'
import type { RenderEnvironment } from 'pane-registry'
import { getOutliner, OutlineManager } from '../index'
import { createHeader } from './header'
import { createNavbar } from './navbar'

// Symbol used to stash the last render-relevant env snapshot on the outliner
// so refreshUI can skip a full GotoSubject re-render when nothing changed.
Expand Down Expand Up @@ -43,7 +44,8 @@ export async function initMainPage (
outliner.GotoSubject(subject, true, undefined, true, undefined)

const header = await createHeader(outliner)
return Promise.all([header])
const navbar = await createNavbar(outliner)
return Promise.all([header, navbar])
}

export async function refreshUI (outliner: OutlineManager) {
Expand Down
86 changes: 86 additions & 0 deletions src/mainPage/navbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { store } from 'solid-logic'
import { html, render } from 'lit-html'
import type { OutlineManager } from '../outline/manager'
import { getPodStorages } from '../outline/podUtils'
import { createFolderPaneItem } from '../outline/folderPaneUtils'

import '~icons/lucide/user'
import '~icons/lucide/users'
import '~icons/lucide/folder-open'
import '../components/navbar'
import { NamedNode } from 'rdflib'
import type { NavbarMenuItem } from '../components/navbar/Navbar'

function createNavItem (label: string, onSelected: () => void): NavbarMenuItem {
return { label, onSelected }
}

async function createNavbarMenuItems (
outliner: OutlineManager,
subject: NamedNode,
OutlineView: HTMLElement | null
): Promise<NavbarMenuItem[]> {
const baseItems: NavbarMenuItem[] = [
createNavItem('Profile', () => {
const profilePane = outliner?.context?.session?.paneRegistry?.byName('profile')
outliner.GotoSubject(subject, true, profilePane, true, undefined, OutlineView)
}),
createNavItem('Friends', () => {
const socialPane = outliner?.context?.session?.paneRegistry?.byName('social')
outliner.GotoSubject(subject, true, socialPane, true, undefined, OutlineView)
})
]

const podStorages = await getPodStorages(subject.uri)
if (podStorages.length === 0) return baseItems

return [
...baseItems,
createNavItem('Storage', () => {
const folderPane = outliner?.context?.session?.paneRegistry?.byName('folder')
if (!folderPane) {
console.warn('Folder pane is not registered')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you should also add this message for profile and social.

return
}
const folderPanes = podStorages.map((pod, index) =>
createFolderPaneItem(folderPane, pod, index)
)
// TODO make storage work for more storage spaces, not just the first one
outliner.GotoSubject(subject, true, folderPanes[0], true, undefined, OutlineView)
})
Comment thread
Copilot marked this conversation as resolved.
]
}

export async function createNavbar (outliner: OutlineManager) {
const existingNavbar = document.querySelector('solid-panes-navbar')

if (existingNavbar) {
return existingNavbar
}

const OutlineView = document.getElementById('OutlineView')
const mainContent = document.getElementById('MainContent')
const tmpContainer = document.createElement('div')
const uri = window.location.href
const subject: NamedNode = typeof uri === 'string' ? store.sym(uri) : uri
const menuItems = await createNavbarMenuItems(outliner, subject, OutlineView)

render(
html`<solid-panes-navbar .navbarItems=${menuItems}></solid-panes-navbar>`,
tmpContainer
)

const navbar = tmpContainer.firstElementChild as HTMLElement | null

if (!navbar) {
throw new Error('Failed to create nav bar')
}

if (mainContent) {
mainContent.insertBefore(navbar, mainContent.firstChild)
} else {
document.body.prepend(navbar)
}

return navbar
}
39 changes: 39 additions & 0 deletions src/outline/folderPaneUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as paneRegistry from 'pane-registry'
import { getPodStorages } from './podUtils'
import folderIcon from '../icons/folder.svg'
import { NamedNode } from 'rdflib'

const FOLDER_ICON = folderIcon

// returns the folder pane of the pods of the given subject (or the current URL subject if none is provided), if any. If not, returns an empty array.
export async function getFolderPaneforStorage (subject?: NamedNode) {
const uri = (new URL(window.location.href)).searchParams.get('uri')
const podUrl = subject?.uri || uri || window.location.href
const podStorages = await getPodStorages(podUrl)
if (!podStorages.length) return []

const folderPane = paneRegistry.byName('folder')
if (!folderPane) return []

return podStorages.map((pod, index) => createFolderPaneItem(folderPane, pod, index))
}

export function createFolderPaneItem (folderPane, pod: NamedNode, index: number) {
return {
name: folderPane.name,
paneName: 'folder',
tabName: `folder-${index}`,
label: function () {
return 'Storage'
},
render: function (_subject, context, options) {
return folderPane.render(pod, context, options)
},
shouldGetFocus: function () {
return false
},
requireQueryButton: !!folderPane.requireQueryButton,
subject: pod,
icon: FOLDER_ICON
}
}
7 changes: 4 additions & 3 deletions src/outline/manager.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,12 @@
}

.tdFlex {
margin: var(--spacing-xxxs, 0.2rem);
border: none;
padding: 0;
border: 1px solid var(--color-border, #444);
border-radius: 5px;
vertical-align: top;
display: flex;
justify-content: space-between;
flex-direction: row;
background: var(--solid-ui-color-white, #fff);
overflow: hidden;
}
Loading
Loading