-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #170 from radio4000/feat/r4-user-channels-select
re-add and fix the r4-user-channels-select
- Loading branch information
Showing
6 changed files
with
132 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import {LitElement, html, nothing} from 'lit' | ||
|
||
/** | ||
* The primary menu for a User of the <r4-app> | ||
*/ | ||
export default class R4AppUserMenu extends LitElement { | ||
createRenderRoot() { | ||
return this | ||
} | ||
static properties = { | ||
href: {type: String}, | ||
channel: {type: Object || null}, | ||
channels: {type: Array || null}, | ||
} | ||
constructor() { | ||
super() | ||
window?.navigation?.addEventListener('navigate', (e) => { | ||
this.path = e.destination.url.replace(this.href, '').split('?')[0] | ||
}) | ||
} | ||
|
||
isCurrent(path) { | ||
return this.path === path ? 'page' : nothing | ||
} | ||
onChannelSelect(event) { | ||
event.stopPropagation() | ||
event.preventDefault() | ||
this.dispatchEvent( | ||
new CustomEvent('select', { | ||
bubbles: true, | ||
detail: event.detail, | ||
}), | ||
) | ||
} | ||
|
||
render() { | ||
console.log('channels', this.channels, this.channel) | ||
const {href, path} = this | ||
return html` | ||
<menu> | ||
<li>${this.renderChannel()}</li> | ||
<li>${this.channel ? this.renderAdd() : null}</li> | ||
</menu> | ||
` | ||
} | ||
renderChannel() { | ||
if (this.channels) { | ||
return html`<r4-user-channels-select | ||
.channels=${this.channels} | ||
.channel=${this.channel} | ||
@select=${this.onChannelSelect} | ||
></r4-user-channels-select>` | ||
} else if (this.channel) { | ||
return html`<a aria-current=${this.isCurrent(`/${this.channel.slug}`)} href=${this.href + '/' + this.channel.slug} | ||
>@${this.channel.slug}</a | ||
>` | ||
} else { | ||
return html`<a aria-current=${this.isCurrent('/new')} href=${this.href + '/new'}>New radio</a>` | ||
} | ||
} | ||
renderAdd() { | ||
return html`<a aria-current=${this.isCurrent('/add')} href=${this.href + '/add?slug=' + this.channel.slug}>Add</a>` | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,40 @@ | ||
import {LitElement, html} from 'lit' | ||
import {sdk} from '../libs/sdk.js' | ||
|
||
export default class R4UserChannelsSelect extends HTMLElement { | ||
static get observedAttributes() { | ||
return ['channels', 'channel'] | ||
export default class R4UserChannelsSelect extends LitElement { | ||
createRenderRoot() { | ||
return this | ||
} | ||
|
||
get channel() { | ||
return this.getAttribute('channel') | ||
} | ||
set channel(str) { | ||
this.setAttribute('channel', str) | ||
} | ||
|
||
get channels() { | ||
return JSON.parse(this.getAttribute('channels')) || [] | ||
} | ||
set channels(obj) { | ||
if (obj) { | ||
this.setAttribute('channels', JSON.stringify(obj)) | ||
} else { | ||
this.removeAttribute('channels') | ||
} | ||
} | ||
|
||
/* if any observed attribute changed, re-render */ | ||
attributeChangedCallback(attrName, newVal) { | ||
if (this.constructor.observedAttributes.indexOf(attrName) > -1) { | ||
this.render() | ||
if (attrName === 'channel') { | ||
this.refreshOptions(newVal) | ||
} | ||
} | ||
static properties = { | ||
channel: {type: Object || null}, | ||
channels: {type: Array || null}, | ||
} | ||
|
||
connectedCallback() { | ||
sdk.supabase.auth.onAuthStateChange(this.onAuthStateChange.bind(this)) | ||
|
||
this.$select = document.createElement('select') | ||
this.$select.addEventListener('input', this.onInput.bind(this)) | ||
|
||
this.$defaultOptroup = document.createElement('optgroup') | ||
this.$defaultOptroup.label = 'Selected' | ||
|
||
this.$defaultOption = document.createElement('option') | ||
this.$defaultOption.defaultValue = true | ||
this.$defaultOption.value = '' | ||
this.$defaultOption.innerText = this.channel ? this.channel : '…' | ||
|
||
this.$defaultOptroup.append(this.$defaultOption) | ||
|
||
this.$channelsOptgroup = document.createElement('optgroup') | ||
this.$channelsOptgroup.label = 'All' | ||
this.$select.append(this.$defaultOptroup) | ||
this.$select.append(this.$channelsOptgroup) | ||
|
||
this.append(this.$select) | ||
|
||
if (this.channels && this.channels.length) { | ||
this.refreshOptions(this.channels[0].slug) | ||
} else { | ||
this.refreshUserChannels() | ||
} | ||
} | ||
onInput(event) { | ||
onSelect(event) { | ||
event.stopPropagation() | ||
/* event.preventDefault() */ | ||
this.channel = event.target.value | ||
const selectedChannel = this.channels.find((channel) => { | ||
return channel.slug === this.channel | ||
}) | ||
const inputEvent = new CustomEvent('input', { | ||
bubbles: true, | ||
detail: { | ||
channels: this.channels, | ||
channel: selectedChannel, | ||
} | ||
}) | ||
this.dispatchEvent(inputEvent) | ||
this.refreshOptions(this.channel) | ||
} | ||
|
||
onAuthStateChange() { | ||
this.refreshUserChannels() | ||
} | ||
|
||
async refreshUserChannels() { | ||
const { data: user } = await sdk.users.readUser() | ||
if (user) { | ||
const { | ||
error, | ||
data, | ||
} = await sdk.channels.readUserChannels() | ||
|
||
this.error = error | ||
this.channels = data | ||
if (this.channels && this.channels.length) { | ||
if (this.channel) { | ||
this.refreshOptions(this.channel) | ||
} else { | ||
this.refreshOptions(this.channels[0].slug) | ||
} | ||
} | ||
} else { | ||
this.channels = [] | ||
} | ||
event.preventDefault() | ||
const {value: id} = event.target | ||
this.dispatchEvent( | ||
new CustomEvent('select', { | ||
bubbles: true, | ||
detail: this.channels.find((c) => c.id === id), | ||
}), | ||
) | ||
} | ||
|
||
render() { | ||
this.$channelsOptgroup.innerHTML = '' | ||
this.channels.map((channel) => { | ||
const $option = document.createElement('option') | ||
$option.value = channel.slug | ||
$option.innerText = channel.slug | ||
this.$channelsOptgroup.append($option) | ||
return html` | ||
<label> | ||
<select @change=${this.onSelect} title="Selected Radio"> | ||
<optgroup label="Selected"> | ||
<option>${this.channel.slug}</option> | ||
</optgroup> | ||
<optgroup label="Channels">${this._renderOptions()}</optgroup> | ||
</select> | ||
</label> | ||
` | ||
} | ||
_renderOptions() { | ||
return this.channels?.map((channel) => { | ||
return html` <option value=${channel.id}>${channel.slug}</option> ` | ||
}) | ||
} | ||
refreshOptions(channelSlug) { | ||
this.$defaultOption.innerText = channelSlug | ||
} | ||
} |
Oops, something went wrong.