A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz

[web] update ContextMenu

+160 -6
+142 -4
apps/web/src/components/ContextMenu/ContextMenu.tsx
··· 1 + import { Folder2, MusicNoteBeamed } from "@styled-icons/bootstrap"; 1 2 import { EllipsisHorizontal } from "@styled-icons/ionicons-sharp"; 3 + import { NestedMenus, StatefulMenu } from "baseui/menu"; 4 + import { StatefulPopover } from "baseui/popover"; 2 5 3 - function ContextMenu() { 6 + export type ContextMenuProps = { 7 + file: { 8 + id: string; 9 + name: string; 10 + type: string; 11 + }; 12 + }; 13 + 14 + function ContextMenu(props: ContextMenuProps) { 15 + const { file } = props; 4 16 return ( 5 17 <> 6 - <div className="text-[var(--color-text)] cursor-pointer"> 7 - <EllipsisHorizontal size={24} /> 8 - </div> 18 + <StatefulPopover 19 + autoFocus={false} 20 + content={({ close }) => ( 21 + <div className="border-[var(--color-border)] w-[240px] border-[1px] bg-[var(--color-background)] rounded-[6px]"> 22 + <div 23 + className="h-[54px] flex flex-row items-center pl-[5px] pr-[5px]" 24 + style={{ 25 + borderBottom: "1px solid var(--color-border)", 26 + }} 27 + > 28 + <div className="h-[43px] flex items-center justify-center ml-[10px] mr-[10px] text-[var(--color-text)]"> 29 + {file.type == "folder" && ( 30 + <div> 31 + <Folder2 size={20} /> 32 + </div> 33 + )} 34 + {file.type !== "folder" && ( 35 + <div> 36 + <MusicNoteBeamed size={20} /> 37 + </div> 38 + )} 39 + </div> 40 + <div className="text-[var(--color-text)] whitespace-nowrap text-ellipsis overflow-hidden"> 41 + {file.name} 42 + </div> 43 + </div> 44 + <NestedMenus> 45 + <StatefulMenu 46 + items={[ 47 + { 48 + id: "0", 49 + label: "Play", 50 + }, 51 + { 52 + id: "1", 53 + label: "Play Next", 54 + }, 55 + { 56 + id: "2", 57 + label: "Add to Playlist", 58 + }, 59 + { 60 + id: "3", 61 + label: "Play Last", 62 + }, 63 + { 64 + id: "4", 65 + label: "Add Shuffled", 66 + }, 67 + ]} 68 + onItemSelect={({ item }) => { 69 + console.log(`Selected item: ${item.label}`); 70 + close(); 71 + }} 72 + overrides={{ 73 + List: { 74 + style: { 75 + boxShadow: "none", 76 + backgroundColor: "var(--color-background)", 77 + }, 78 + }, 79 + ListItem: { 80 + style: { 81 + backgroundColor: "var(--color-background)", 82 + color: "var(--color-text)", 83 + ":hover": { 84 + backgroundColor: "var(--color-menu-hover)", 85 + }, 86 + }, 87 + }, 88 + Option: { 89 + props: { 90 + getChildMenu: (item: { label: string }) => { 91 + if (item.label === "Add to Playlist") { 92 + return ( 93 + <div className="border-[var(--color-border)] w-[205px] border-[1px] bg-[var(--color-background)] rounded-[6px]"> 94 + <StatefulMenu 95 + items={{ 96 + __ungrouped: [ 97 + { 98 + label: "Create new playlist", 99 + }, 100 + ], 101 + }} 102 + overrides={{ 103 + List: { 104 + style: { 105 + boxShadow: "none", 106 + backgroundColor: 107 + "var(--color-background)", 108 + }, 109 + }, 110 + ListItem: { 111 + style: { 112 + backgroundColor: 113 + "var(--color-background)", 114 + color: "var(--color-text)", 115 + ":hover": { 116 + backgroundColor: 117 + "var(--color-menu-hover)", 118 + }, 119 + }, 120 + }, 121 + }} 122 + /> 123 + </div> 124 + ); 125 + } 126 + return null; 127 + }, 128 + }, 129 + }, 130 + }} 131 + /> 132 + </NestedMenus> 133 + </div> 134 + )} 135 + overrides={{ 136 + Inner: { 137 + style: { 138 + backgroundColor: "var(--color-background)", 139 + }, 140 + }, 141 + }} 142 + > 143 + <div className="text-[var(--color-text)] cursor-pointer"> 144 + <EllipsisHorizontal size={24} /> 145 + </div> 146 + </StatefulPopover> 9 147 </> 10 148 ); 11 149 }
+9 -1
apps/web/src/pages/dropbox/Dropbox.tsx
··· 70 70 }), 71 71 columnHelper.accessor("name", { 72 72 header: "", 73 - cell: () => <ContextMenu />, 73 + cell: (info) => ( 74 + <ContextMenu 75 + file={{ 76 + id: info.row.original.id, 77 + name: info.row.original.name, 78 + type: info.row.original.tag, 79 + }} 80 + /> 81 + ), 74 82 }), 75 83 ]; 76 84
+9 -1
apps/web/src/pages/googledrive/GoogleDrive.tsx
··· 57 57 }), 58 58 columnHelper.accessor("name", { 59 59 header: "", 60 - cell: () => <ContextMenu />, 60 + cell: (info) => ( 61 + <ContextMenu 62 + file={{ 63 + id: info.row.original.id, 64 + name: info.row.original.name, 65 + type: info.row.original.tag, 66 + }} 67 + /> 68 + ), 61 69 }), 62 70 ]; 63 71