Skip to content

Commit bec9209

Browse files
committed
Merge branch 'master' into scuttle-shell
2 parents 2a5c069 + 1c2926f commit bec9209

32 files changed

+3797
-2904
lines changed

.github/stale.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Number of days of inactivity before an issue becomes stale
2+
daysUntilStale: 60
3+
# Number of days of inactivity before a stale issue is closed
4+
daysUntilClose: 7
5+
# Issues with these labels will never be considered stale
6+
exemptLabels:
7+
- pinned
8+
- security
9+
# Label to use when marking an issue as stale
10+
staleLabel: stale
11+
# Comment to post when marking an issue as stale. Set to `false` to disable
12+
markComment: >
13+
This issue has been automatically marked as stale because it has not had
14+
recent activity. It will be closed if no further activity occurs. Thank you
15+
for your contributions.
16+
# Comment to post when closing a stale issue. Set to `false` to disable
17+
closeComment: false

README.md

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,7 @@ If you'd like to hack on Patchbay, check out the Developer Install below.
2626

2727
## Keyboard shortcuts
2828

29-
`CmdOrCtrl` is the `command` key on Apple keyboards or the `ctrl` key on PC keyboards.
30-
31-
### Tabs and window
32-
33-
- `h` / `CmdOrCtrl+Shift+]` : tabs left
34-
- `j` / `CmdOrCtrl+Shift+[`: tabs right
35-
- `x` / `CmdOrCtrl+w` : close tab
36-
- `CmdOrCtrl+Shift+w` will close the current window
37-
38-
### Message feeds
39-
40-
`j` : next message (down)
41-
`k` : previous message
42-
`o` : open message thread (and scroll to position of this message in that thread)
43-
` ` ` : toggle raw message view for currently selected message (` ` ` = backtick, lives on the same key as `~`)
44-
45-
composing : cttrl + enter = post
46-
47-
### Nav bar thing
48-
49-
`@` : start a person query
50-
`#` : start a channel query
51-
`?` : start a search query
52-
`/` : start a navigation (e.g. /public) - need to re-instate suggestions for this
53-
54-
you can also paste a message id (starts with `%`) in here to navigate to it. Same with blobs (`&`)
55-
29+
[See here](./app/page/SHORTCUTS.md) or in patchbay for to the page `/shortcuts`
5630
---
5731

5832
## Developer Install
@@ -164,6 +138,29 @@ This is ultimately reduced along with all other `router.sync.router` modules int
164138
Giving modules here will add settings sections to the settings page (`app.page.settings`).
165139

166140

141+
### Requiring the core of patchbay
142+
143+
If you don't want the default modules, you can grab the main part of patchbay and pick and choose modules like this:
144+
145+
```js
146+
const patchcore = require('patchcore')
147+
const patchbay = require('patchbay/main')
148+
const combine = require('depject')
149+
const entry = require('depject/entry')
150+
const nest = require('depnest')
151+
152+
const sockets = combine(
153+
require('patchbay-dark-crystal'), // the module(s) you want
154+
patchbay,
155+
patchcore // required
156+
)
157+
158+
const api = entry(sockets, nest('app.html.app', 'first'))
159+
document.body.appendChild(api.app.html.app())
160+
```
161+
162+
You'll need to be running your own sbot and launch this with electro / electron. See `index.js` to see that
163+
167164
### How to add a new page
168165

169166
e.g. to add a 'cats' page to the app:

about/html/edit.js

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ const nest = require('depnest')
22
const dataurl = require('dataurl-')
33
const hyperfile = require('hyperfile')
44
const hypercrop = require('hypercrop')
5-
const hyperlightbox = require('hyperlightbox')
65
const {
76
h, Value, Dict, Struct,
87
map, computed, when, dictToCollection, onceTrue
@@ -20,6 +19,7 @@ exports.needs = nest({
2019
latestValue: 'first',
2120
groupedValues: 'first'
2221
},
22+
'app.html.modal': 'first',
2323
'blob.sync.url': 'first',
2424
'keys.sync.id': 'first',
2525
'message.html.confirm': 'first',
@@ -74,8 +74,6 @@ exports.create = function (api) {
7474
new: Value(api.about.obs.latestValue(id, 'publicWebHosting')())
7575
})
7676

77-
var lightbox = hyperlightbox()
78-
7977
var isPossibleUpdate = computed([name.new, avatar.new, publicWebHosting.new], (name, avatar, publicWebHostingValue) => {
8078
return name || avatar.link || (isMe && publicWebHostingValue !== publicWebHosting.current())
8179
})
@@ -102,8 +100,12 @@ exports.create = function (api) {
102100
})
103101
})
104102

103+
const modalContent = Value()
104+
const isOpen = Value(false)
105+
const modal = api.app.html.modal(modalContent, { isOpen })
106+
105107
return h('AboutEditor', [
106-
lightbox,
108+
modal,
107109
h('section.avatar', [
108110
h('section', [
109111
h('img', { src: avatarSrc })
@@ -162,9 +164,9 @@ exports.create = function (api) {
162164
])
163165

164166
function dataUrlCallback (data) {
165-
const cropCallback = (err, cropData) => {
167+
const cropEl = Crop(data, (err, cropData) => {
166168
if (err) throw err
167-
if (!cropData) return lightbox.close()
169+
if (!cropData) return isOpen.set(false)
168170

169171
var _data = dataurl.parse(cropData)
170172
api.sbot.async.addBlob(pull.once(_data.data), (err, hash) => {
@@ -178,17 +180,17 @@ exports.create = function (api) {
178180
height: 512
179181
})
180182
})
181-
lightbox.close()
182-
}
183+
isOpen.set(false)
184+
})
183185

184-
const cropEl = Crop(data, cropCallback)
185-
lightbox.show(cropEl)
186+
modalContent.set(cropEl)
187+
isOpen.set(true)
186188
}
187189

188190
function Crop (data, cb) {
189-
var img = h('img', {src: data})
191+
var img = h('img', { src: data })
190192

191-
var crop = h('div')
193+
var crop = Value()
192194

193195
waitForImg()
194196

@@ -206,7 +208,7 @@ exports.create = function (api) {
206208
}
207209

208210
var canvas = hypercrop(img)
209-
crop = (
211+
crop.set(
210212
h('PatchProfileCrop', [
211213
h('header', 'click and drag to crop your image'),
212214
canvas,

app/html/app.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ exports.needs = nest({
1717
exports.create = function (api) {
1818
return nest('app.html.app', app)
1919

20-
function app () {
20+
function app (initialTabs) {
2121
console.log('STARTING app')
2222

2323
window = api.app.sync.window(window) // eslint-disable-line no-global-assign
2424

25-
const initialTabs = api.settings.sync.get('patchbay.defaultTabs')
26-
const App = h('App', api.app.html.tabs(initialTabs))
25+
const App = h('App', api.app.html.tabs({
26+
initial: initialTabs || api.settings.sync.get('patchbay.defaultTabs')
27+
}))
2728

2829
api.app.sync.initialise(App)
2930
// runs all the functions in app/sync/initialise

app/html/modal.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,41 @@ exports.create = (api) => {
77
return nest('app.html.modal', (content, { isOpen, onClose, className = '' } = {}) => {
88
if (typeof isOpen !== 'function') isOpen = Value(false)
99

10-
const openMe = () => isOpen.set(true)
10+
const openMe = () => {
11+
isOpen.set(true)
12+
}
1113
const closeMe = () => {
1214
isOpen.set(false)
1315
if (typeof onClose === 'function') onClose()
1416
}
1517

16-
const lb = h('Modal', { classList: [when(isOpen, '-open', '-close'), className], 'ev-click': closeMe },
17-
h('div.content', {'ev-click': (ev) => ev.stopPropagation()}, [
18-
content
19-
]))
18+
const lb = h('Modal',
19+
{
20+
classList: [ className, when(isOpen, '-open', '-close') ],
21+
'ev-click': closeMe,
22+
'ev-keydown': ev => {
23+
if (ev.keyCode === 27) closeMe() // Escape
24+
}
25+
},
26+
[
27+
h('div.content', { 'ev-click': (ev) => ev.stopPropagation() }, [
28+
content
29+
])
30+
]
31+
)
32+
33+
isOpen(state => {
34+
if (!state) return
35+
36+
focus()
37+
function focus () {
38+
if (!lb.isConnected) setTimeout(focus, 200)
39+
else {
40+
const target = lb.querySelector('input') || lb.querySelector('textarea')
41+
if (target) target.focus()
42+
}
43+
}
44+
})
2045

2146
lb.open = openMe
2247
lb.close = closeMe

app/html/scroller.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ exports.create = function (api) {
77
return nest('app.html.scroller', Scroller)
88

99
function Scroller (opts = {}) {
10-
const { prepend, content = null, append, classList = [], className = '', title = '' } = opts
10+
const { prepend, content = null, append, classList = [], className = '', title = '', scrollIntoView } = opts
1111

1212
const contentSection = h('section.content', { title: '' }, content)
1313

@@ -20,7 +20,7 @@ exports.create = function (api) {
2020
]
2121
)
2222

23-
container.scroll = keyscroll(contentSection)
23+
container.scroll = keyscroll(contentSection, scrollIntoView)
2424

2525
return {
2626
content: contentSection,
@@ -29,7 +29,7 @@ exports.create = function (api) {
2929
}
3030
}
3131

32-
function keyscroll (content) {
32+
function keyscroll (content, scrollIntoView = false) {
3333
var curMsgEl
3434

3535
if (!content) return () => {}
@@ -60,9 +60,14 @@ function keyscroll (content) {
6060
function selectChild (el) {
6161
if (!el) { return }
6262

63-
if (!el.scrollIntoViewIfNeeded && !el.scrollIntoView) return
64-
;(el.scrollIntoViewIfNeeded || el.scrollIntoView).call(el)
65-
el.focus()
63+
if (scrollIntoView) {
64+
if (!el.scrollIntoViewIfNeeded && !el.scrollIntoView) return
65+
;(el.scrollIntoViewIfNeeded || el.scrollIntoView).call(el)
66+
} else {
67+
content.parentElement.scrollTop = el.offsetTop - content.parentElement.offsetTop - 10
68+
}
69+
70+
if (el.focus) el.focus()
6671
curMsgEl = el
6772
}
6873
}

app/html/search-bar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ exports.create = function (api) {
7373
// TODO extract
7474
function getPagesSuggestions (word) {
7575
const pages = [
76-
'blogs', 'calendar', 'posts', 'public', 'private', 'inbox', 'profile', 'notifications', 'settings',
77-
'gatherings', 'chess', 'books', 'imageSearch', 'polls', 'query', 'dark-crystal', 'postRank', 'scry/new'
76+
'blogs', 'calendar', 'posts', 'public', 'private', 'inbox', 'profile', 'notifications', 'settings', 'shortcuts',
77+
'gatherings', 'chess', 'books', 'imageSearch', 'polls', 'query', 'dark-crystal', 'postRank', 'scry', 'scry/new'
7878
]
7979

8080
return pages

app/html/tabs.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ exports.create = function (api) {
2222
'app.html.tabs': tabs
2323
})
2424

25-
function tabs (initialTabs = []) {
25+
function tabs ({ initial = [], prepend, append } = {}) {
2626
if (_tabs) return _tabs
2727

2828
const onSelect = (indexes) => {
@@ -47,12 +47,9 @@ exports.create = function (api) {
4747

4848
const search = api.app.html.searchBar()
4949
const menu = api.app.html.menu()
50+
if (append === undefined) append = h('div.navExtra', [ search, menu ])
5051

51-
_tabs = Tabs({
52-
onSelect,
53-
onClose,
54-
append: h('div.navExtra', [ search, menu ])
55-
})
52+
_tabs = Tabs({ onSelect, onClose, prepend, append })
5653
_tabs.currentPage = () => {
5754
const currentPage = _tabs.get(_tabs.selected[0])
5855
return currentPage && currentPage.firstChild
@@ -62,8 +59,8 @@ exports.create = function (api) {
6259
_tabs.closeCurrentTab = () => { _tabs.currentPage() && _tabs.remove(_tabs.selected[0]) }
6360

6461
// # TODO: review - this works but is strange
65-
initialTabs.forEach(p => api.app.sync.goTo(p))
66-
if (initialTabs[0]) api.app.sync.goTo(initialTabs[0])
62+
initial.forEach(p => api.app.sync.goTo(p))
63+
if (initial[0]) api.app.sync.goTo(initial[0])
6764
return _tabs
6865
}
6966
}

app/html/tabs.mcss

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/* TODO depricate this carefully (see styles/mcss/hypertabs.mcss) */
2+
/* NOTE there are some active styles in here still */
3+
14
Hypertabs {
25
position: fixed
36
top: 0
@@ -38,22 +41,13 @@ Hypertabs {
3841
border: 1px gainsboro solid
3942
border-bottom: none
4043

41-
:hover {
42-
a.close {
43-
visibility: visible
44-
}
45-
}
46-
4744
-selected {
4845
color: #222
4946
$backgroundPrimary
5047

5148
a.link {
5249
max-width: calc(100% - 2rem)
5350
}
54-
a.close {
55-
visibility: visible
56-
}
5751
}
5852

5953
-notify {
@@ -82,26 +76,6 @@ Hypertabs {
8276
padding: .5rem 0 .5rem .6rem
8377
}
8478

85-
a.close {
86-
visibility: hidden
87-
font-family: monospace
88-
line-height: 1rem
89-
width: .9rem
90-
height: .9rem
91-
/* border-radius: 1rem */
92-
93-
margin-right: .3rem
94-
95-
display: flex
96-
justify-content: center
97-
98-
:hover {
99-
background: #aaaaaa
100-
color: #fff
101-
font-weight: 600
102-
}
103-
}
104-
10579
}
10680

10781
}

0 commit comments

Comments
 (0)