| signal({kind: 'rpc-needed', value: {kind: 'video', target}}) | signal({kind: 'rpc-needed', value: {kind: 'video', target}}) | ||||
| }) | }) | ||||
| }, | }, | ||||
| reLayout({dom}) { | |||||
| const COUNT = dom.children.length || 1 | |||||
| let [fnx, fny] = [ | |||||
| Math.floor((1 + Math.sqrt(4 * COUNT - 3)) / 2), | |||||
| Math.ceil(Math.sqrt(COUNT)), | |||||
| ] | |||||
| let max = 0 | |||||
| for([nx, ny] of [[1, COUNT], [fnx, fny], [COUNT, 1]]) { | |||||
| let h = dom.clientHeight / ny | |||||
| let w = dom.clientWidth / nx | |||||
| if(w > h) { | |||||
| w = Math.min(w, h * 4/3) | |||||
| } | |||||
| else { | |||||
| h = Math.min(h, w * 3/4) | |||||
| } | |||||
| if(h * w > max) { | |||||
| max = h * w | |||||
| fnx = nx | |||||
| fny = ny | |||||
| } | |||||
| } | |||||
| dom.style['grid-template-columns'] = Array(fnx).fill('1fr').join(' ') | |||||
| dom.style['grid-template-rows'] = Array(fny).fill('1fr').join(' ') | |||||
| }, | |||||
| view() { | view() { | ||||
| const dims = [ | |||||
| Math.floor((1 + Math.sqrt(4 * State.online.length - 3)) / 2), | |||||
| Math.ceil(Math.sqrt(State.online.length)), | |||||
| ].map(n => Array(n || 1).fill('1fr').join(' ')) | |||||
| if(innerHeight > innerWidth) dims.reverse() | |||||
| const style = { | const style = { | ||||
| backgroundColor: 'black', | backgroundColor: 'black', | ||||
| overflow: 'hidden', | overflow: 'hidden', | ||||
| display: 'grid', | display: 'grid', | ||||
| gridTemplateRows: dims[0], | |||||
| gridTemplateColumns: dims[1], | |||||
| } | } | ||||
| return m('.videos', {style}, | |||||
| const oncreate = VideoShare.reLayout | |||||
| const onupdate = VideoShare.reLayout | |||||
| return m('.videos', {style, oncreate, onupdate}, | |||||
| State.online.map(username => m(Video, {key: username, username})) | State.online.map(username => m(Video, {key: username, username})) | ||||
| ) | ) | ||||
| }, | }, |