()
| 475 | } |
| 476 | |
| 477 | function FallbackOrderSettings() { |
| 478 | const update = useForceUpdater(); |
| 479 | const { store } = settings; |
| 480 | const [dragIndex, setDragIndex] = React.useState<number | null>(null); |
| 481 | const [order, setOrder] = React.useState<ServiceType[]>(() => { |
| 482 | const configured = (store.fallbackOrder || defaultFallbackOrder) |
| 483 | .split(/[\n,]/) |
| 484 | .map(entry => entry.trim()) |
| 485 | .filter((entry): entry is ServiceType => Object.values(ServiceType).includes(entry as ServiceType)); |
| 486 | |
| 487 | return configured.length === fallbackServiceOrder.length && new Set(configured).size === fallbackServiceOrder.length |
| 488 | ? configured |
| 489 | : fallbackServiceOrder; |
| 490 | }); |
| 491 | |
| 492 | const commitOrder = (nextOrder: ServiceType[]) => { |
| 493 | setOrder(nextOrder); |
| 494 | store.fallbackOrder = nextOrder.join(","); |
| 495 | update(); |
| 496 | }; |
| 497 | |
| 498 | return ( |
| 499 | <SettingsSection id="fallback-order" name="Fallback Order" description="Drag hosts to reorder fallback attempts. The selected host is tried first, then this order is used."> |
| 500 | <div className={cl("fallback-order-list")}> |
| 501 | {order.map((service, index) => ( |
| 502 | <div |
| 503 | key={service} |
| 504 | className={cl("fallback-order-item")} |
| 505 | draggable |
| 506 | onDragStart={event => { |
| 507 | setDragIndex(index); |
| 508 | event.dataTransfer.effectAllowed = "move"; |
| 509 | event.dataTransfer.setData("text/plain", String(index)); |
| 510 | }} |
| 511 | onDragOver={event => event.preventDefault()} |
| 512 | onDrop={event => { |
| 513 | event.preventDefault(); |
| 514 | const sourceIndex = dragIndex ?? Number(event.dataTransfer.getData("text/plain")); |
| 515 | if (!Number.isInteger(sourceIndex) || sourceIndex === index || sourceIndex < 0 || sourceIndex >= order.length) { |
| 516 | setDragIndex(null); |
| 517 | return; |
| 518 | } |
| 519 | |
| 520 | const nextOrder = [...order]; |
| 521 | const [moved] = nextOrder.splice(sourceIndex, 1); |
| 522 | nextOrder.splice(index, 0, moved); |
| 523 | setDragIndex(null); |
| 524 | commitOrder(nextOrder); |
| 525 | }} |
| 526 | onDragEnd={() => setDragIndex(null)} |
| 527 | data-dragging={dragIndex === index} |
| 528 | > |
| 529 | <span className={cl("fallback-order-label")}>{serviceLabels[service]}</span> |
| 530 | <span className={cl("fallback-order-handle")}>Drag</span> |
| 531 | </div> |
| 532 | ))} |
| 533 | </div> |
| 534 | <div className={cl("fallback-order-actions")}> |
nothing calls this directly
no test coverage detected