Projects / snek / src / snek / templates / dialog_channel_settings.html

git clone https://molodetz.nl/retoor/snek.git

Raw source file available here .

<dialog id="channel-settings-dialog">
<div class="dialog-backdrop">
<div class="dialog-box dialog-box-wide">
<div class="dialog-title"><h2>Channel Settings</h2></div>
<div class="dialog-content">
<div class="dialog-form">
<label class="dialog-label">Name</label>
<input type="text" id="settings-channel-name" class="dialog-input" placeholder="Channel name" autocomplete="off">

<label class="dialog-label">Description</label>
<input type="text" id="settings-channel-description" class="dialog-input" placeholder="Description (optional)" autocomplete="off">

<label class="dialog-checkbox-label">
<input type="checkbox" id="settings-channel-private">
<span>Private channel</span>
</label>

<div class="dialog-divider"></div>

<div class="dialog-danger-zone">
<label class="dialog-label dialog-label-danger">Danger Zone</label>
<button class="dialog-button danger btn-delete-channel">Delete Channel</button>
</div>
</div>
</div>
<div class="dialog-actions">
<button class="dialog-button secondary btn-cancel">Cancel</button>
<button class="dialog-button primary btn-save">Save</button>
</div>
</div>
</div>
</dialog>

<dialog id="delete-channel-dialog">
<div class="dialog-backdrop">
<div class="dialog-box">
<div class="dialog-title"><h2>Delete Channel</h2></div>
<div class="dialog-content">
<p>This action cannot be undone. Type the channel name to confirm:</p>
<div class="dialog-form">
<input type="text" id="delete-channel-confirm" class="dialog-input" placeholder="Channel name" autocomplete="off">
</div>
</div>
<div class="dialog-actions">
<button class="dialog-button secondary btn-cancel">Cancel</button>
<button class="dialog-button danger btn-confirm-delete" disabled>Delete</button>
</div>
</div>
</div>
</dialog>

<script>
class ChannelSettingsDialog {
constructor() {
this.dialog = document.getElementById('channel-settings-dialog');
this.nameInput = document.getElementById('settings-channel-name');
this.descriptionInput = document.getElementById('settings-channel-description');
this.privateInput = document.getElementById('settings-channel-private');
this.saveButton = this.dialog.querySelector('.btn-save');
this.cancelButton = this.dialog.querySelector('.btn-cancel');
this.deleteButton = this.dialog.querySelector('.btn-delete-channel');
this.channelUid = null;
this.channelName = null;
this.isModerator = false;
this._initEventListeners();
}

_initEventListeners() {
this.cancelButton.addEventListener('click', () => this.close());
this.saveButton.addEventListener('click', () => this.save());
this.deleteButton.addEventListener('click', () => this.showDeleteConfirm());
}

async show(channelUid) {
this.channelUid = channelUid;
const channels = await window.app.rpc.getChannels();
const channel = channels.find(c => c.uid === channelUid);
if (!channel) {
alert('Channel not found');
return;
}
this.channelName = channel.name;
this.isModerator = channel.is_moderator;
this.nameInput.value = channel.name.replace(/^#/, '');
this.descriptionInput.value = '';
this.privateInput.checked = false;

if (!this.isModerator) {
this.nameInput.disabled = true;
this.descriptionInput.disabled = true;
this.privateInput.disabled = true;
this.saveButton.disabled = true;
this.deleteButton.disabled = true;
} else {
this.nameInput.disabled = false;
this.descriptionInput.disabled = false;
this.privateInput.disabled = false;
this.saveButton.disabled = false;
this.deleteButton.disabled = false;
}

this.dialog.showModal();
this.nameInput.focus();
}

close() {
this.dialog.close();
}

async save() {
const name = this.nameInput.value.trim();
if (!name) {
this.nameInput.classList.add('error');
return;
}
this.nameInput.classList.remove('error');
this.saveButton.disabled = true;
try {
const result = await window.app.rpc.updateChannel(
this.channelUid,
name,
this.descriptionInput.value.trim() || null,
this.privateInput.checked
);
if (result && result.success) {
this.close();
window.location.reload();
} else if (result && result.error) {
alert(result.error);
}
} catch (err) {
alert('Failed to update channel');
} finally {
this.saveButton.disabled = false;
}
}

showDeleteConfirm() {
this.close();
deleteChannelDialog.show(this.channelUid, this.channelName);
}
}

class DeleteChannelDialog {
constructor() {
this.dialog = document.getElementById('delete-channel-dialog');
this.confirmInput = document.getElementById('delete-channel-confirm');
this.deleteButton = this.dialog.querySelector('.btn-confirm-delete');
this.cancelButton = this.dialog.querySelector('.btn-cancel');
this.channelUid = null;
this.channelName = null;
this._initEventListeners();
}

_initEventListeners() {
this.cancelButton.addEventListener('click', () => this.close());
this.deleteButton.addEventListener('click', () => this.delete());
this.confirmInput.addEventListener('input', () => this.validateInput());
}

validateInput() {
const input = this.confirmInput.value.trim();
const name = this.channelName.replace(/^#/, '');
this.deleteButton.disabled = input !== name;
}

show(channelUid, channelName) {
this.channelUid = channelUid;
this.channelName = channelName;
this.confirmInput.value = '';
this.deleteButton.disabled = true;
this.dialog.showModal();
this.confirmInput.focus();
}

close() {
this.dialog.close();
}

async delete() {
this.deleteButton.disabled = true;
try {
const result = await window.app.rpc.deleteChannel(this.channelUid);
if (result && result.success) {
this.close();
window.location.href = '/';
} else if (result && result.error) {
alert(result.error);
}
} catch (err) {
alert('Failed to delete channel');
} finally {
this.deleteButton.disabled = false;
}
}
}

const channelSettingsDialog = new ChannelSettingsDialog();
const deleteChannelDialog = new DeleteChannelDialog();

function showChannelSettings() {
channelSettingsDialog.show('{{ channel.uid.value }}');
}
</script>