Add user selection modal for playlist sharing

Introduces a modal dialog to select a user when sharing a playlist, improving the user experience. Updates the PlaylistView to use the new BaseModal for sharing, and enhances BaseModal to support select components and store their values.
This commit is contained in:
Choco
2025-11-29 11:20:21 +08:00
parent 9201ee730f
commit 8fdceef4db
3 changed files with 30 additions and 4 deletions

View File

@@ -473,7 +473,7 @@ class Playlists(commands.Cog, name="playlist"):
])
@app_commands.autocomplete(name=playlist_autocomplete)
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
async def permission(self, ctx: commands.Context, name: str, member: discord.Member, permission: str, action: str):
async def permission(self, ctx: commands.Context, member: discord.Member, name: str, permission: str, action: str):
"Grant or revoke permissions for a playlist."
if member.id == ctx.author.id:
return await send_localized_message(ctx, 'playlist.permissions.cannotModifySelf', ephemeral=True)

View File

@@ -28,7 +28,7 @@ from tldextract import extract
from discord.ext import commands
from typing import Any
from .utils import DynamicViewManager, Pagination
from .utils import DynamicViewManager, Pagination, BaseModal
from .pagination import PaginationView
from ..config import Config
from ..utils import format_ms, truncate_string, dispatch_message
@@ -144,7 +144,9 @@ class PlaylistView(PaginationView):
async def on_error(self, interaction: discord.Interaction, error: Exception, item: discord.ui.Item) -> None:
if isinstance(error, VoicelinkException):
return await dispatch_message(interaction, content=getattr(error, 'original', error), ephemeral=True)
return await super().on_error(interaction, error, item)
async def update_message(self, interaction: discord.Interaction) -> None:
"""Update the view and edit the message with the new embed."""
self.update_view()
@@ -168,7 +170,29 @@ class PlaylistView(PaginationView):
@discord.ui.button(label="Share", custom_id="share", style=discord.ButtonStyle.gray)
async def share(self, interaction: discord.Interaction[commands.Bot], button: discord.ui.Button) -> None:
await interaction.response.defer()
modal = BaseModal(
title="Share Playlist",
custom_id="share_modal",
items=[
discord.ui.Label(
text="User to share with",
description="Select a user to share with",
component=discord.ui.UserSelect(
custom_id="user_select",
placeholder="Select a user to share with",
required=True
),
)
]
)
await interaction.response.send_modal(modal)
await modal.wait()
user = modal.values.get("user_select")
if not user:
return
await interaction.client.get_command("playlist share")(self.primary_view.ctx, user[0], self.name)
@discord.ui.button(label="Export", custom_id="export", style=discord.ButtonStyle.gray)
async def export(self, interaction: discord.Interaction[commands.Bot], button: discord.ui.Button) -> None:

View File

@@ -42,3 +42,5 @@ class BaseModal(discord.ui.Modal):
for item in self.walk_children():
if isinstance(item, discord.ui.TextInput):
self.values[item.custom_id] = item.value
elif isinstance(item, (discord.ui.Select, discord.ui.UserSelect, discord.ui.RoleSelect, discord.ui.ChannelSelect, discord.ui.MentionableSelect)):
self.values[item.custom_id] = item.values