Fossil SCM
/chat: grouped config settings into categories. Moved config checkboxes back to the left, per /chat feedback, but now clicking anywhere on their row toggles them. Slightly shrunk the main buttons when in non-compact mode. Various look-and-feel and help text tweaks to the config view.
Commit
67e8599874c2401585aa81686cff02f4d51ce18e8e10c7801ef3c6bc7d5d7025
Parent
df0e2ca16877a09…
2 files changed
+79
-64
+15
-8
+79
-64
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -1428,63 +1428,74 @@ | ||
| 1428 | 1428 | events. The checkbox element gets added to the options object |
| 1429 | 1429 | so that the callback() can reference it via this.checkbox. |
| 1430 | 1430 | */ |
| 1431 | 1431 | const settingsOps = [{ |
| 1432 | 1432 | label: "Chat Configuration Options", |
| 1433 | - hint: "Most of these settings are persistent via window.localStorage." | |
| 1434 | - },{ | |
| 1435 | - label: "Chat-only mode", | |
| 1436 | - hint: "Toggle the page between normal fossil view and chat-only view.", | |
| 1437 | - boolValue: 'chat-only-mode' | |
| 1438 | - },{ | |
| 1439 | - label: "Ctrl-enter to Send", | |
| 1440 | - hint: [ | |
| 1441 | - "When on, only Ctrl-Enter will send messages and Enter adds ", | |
| 1442 | - "blank lines. When off, both Enter and Ctrl-Enter send. ", | |
| 1443 | - "When the input field has focus, is empty, and preview ", | |
| 1444 | - "mode is NOT active then Ctrl-Enter toggles this setting." | |
| 1445 | - ].join(''), | |
| 1446 | - boolValue: 'edit-ctrl-send' | |
| 1447 | - },{ | |
| 1448 | - label: "Compact mode", | |
| 1449 | - hint: [ | |
| 1450 | - "Toggle between a space-saving or more spacious writing area. ", | |
| 1451 | - "When the input field has focus, is empty, and preview mode ", | |
| 1452 | - "is NOT active then Shift-Enter toggles this setting."].join(''), | |
| 1453 | - boolValue: 'edit-compact-mode' | |
| 1454 | - },{ | |
| 1455 | - label: "Left-align my posts", | |
| 1456 | - hint: "Default alignment of your own messages is selected " | |
| 1457 | - + "based window width/height relationship.", | |
| 1458 | - boolValue: ()=>!document.body.classList.contains('my-messages-right'), | |
| 1459 | - callback: function f(){ | |
| 1460 | - document.body.classList[ | |
| 1461 | - this.checkbox.checked ? 'remove' : 'add' | |
| 1462 | - ]('my-messages-right'); | |
| 1463 | - } | |
| 1464 | - },{ | |
| 1465 | - label: "Monospace message font", | |
| 1466 | - hint: "Use monospace font for message and input text.", | |
| 1467 | - boolValue: 'monospace-messages', | |
| 1468 | - callback: function(setting){ | |
| 1469 | - document.body.classList[ | |
| 1470 | - setting.value ? 'add' : 'remove' | |
| 1471 | - ]('monospace-messages'); | |
| 1472 | - } | |
| 1473 | - },{ | |
| 1474 | - label: "Show images inline", | |
| 1475 | - hint: "Show attached images inline or as a download link.", | |
| 1476 | - boolValue: 'images-inline' | |
| 1477 | - },{ | |
| 1478 | - label: "Use 'contenteditable' editing mode.", | |
| 1479 | - boolValue: 'edit-widget-x', | |
| 1480 | - hint: [ | |
| 1481 | - "When enabled, chat input uses a so-called 'contenteditable' ", | |
| 1482 | - "field. Though generally more comfortable and modern than ", | |
| 1483 | - "plain-text input fields, browser-specific quirks and bugs ", | |
| 1484 | - "may lead to frustration." | |
| 1485 | - ].join('') | |
| 1433 | + hint: F.storage.isTransient() | |
| 1434 | + ? "Local store is unavailable. These settings are transient." | |
| 1435 | + : ["Most of these settings are persistent via ", | |
| 1436 | + F.storage.storageImplName(), ": ", | |
| 1437 | + F.storage.storageHelpDescription()].join('') | |
| 1438 | + },{ | |
| 1439 | + label: "Editing Options...", | |
| 1440 | + children:[{ | |
| 1441 | + label: "Chat-only mode", | |
| 1442 | + hint: "Toggle the page between normal fossil view and chat-only view.", | |
| 1443 | + boolValue: 'chat-only-mode' | |
| 1444 | + },{ | |
| 1445 | + label: "Ctrl-enter to Send", | |
| 1446 | + hint: [ | |
| 1447 | + "When on, only Ctrl-Enter will send messages and Enter adds ", | |
| 1448 | + "blank lines. When off, both Enter and Ctrl-Enter send. ", | |
| 1449 | + "When the input field has focus and is empty ", | |
| 1450 | + "then Ctrl-Enter toggles this setting." | |
| 1451 | + ].join(''), | |
| 1452 | + boolValue: 'edit-ctrl-send' | |
| 1453 | + },{ | |
| 1454 | + label: "Compact mode", | |
| 1455 | + hint: [ | |
| 1456 | + "Toggle between a space-saving or more spacious writing area. ", | |
| 1457 | + "When the input field has focus, is empty, and preview mode ", | |
| 1458 | + "is NOT active then Shift-Enter toggles this setting."].join(''), | |
| 1459 | + boolValue: 'edit-compact-mode' | |
| 1460 | + },{ | |
| 1461 | + label: "Use 'contenteditable' editing mode", | |
| 1462 | + boolValue: 'edit-widget-x', | |
| 1463 | + hint: [ | |
| 1464 | + "When enabled, chat input uses a so-called 'contenteditable' ", | |
| 1465 | + "field. Though generally more comfortable and modern than ", | |
| 1466 | + "plain-text input fields, browser-specific quirks and bugs ", | |
| 1467 | + "may lead to frustration. Ideal for mobile devices." | |
| 1468 | + ].join('') | |
| 1469 | + }] | |
| 1470 | + },{ | |
| 1471 | + label: "Appearance Options...", | |
| 1472 | + children:[{ | |
| 1473 | + label: "Left-align my posts", | |
| 1474 | + hint: "Default alignment of your own messages is selected " | |
| 1475 | + + "based window width/height ratio.", | |
| 1476 | + boolValue: ()=>!document.body.classList.contains('my-messages-right'), | |
| 1477 | + callback: function f(){ | |
| 1478 | + document.body.classList[ | |
| 1479 | + this.checkbox.checked ? 'remove' : 'add' | |
| 1480 | + ]('my-messages-right'); | |
| 1481 | + } | |
| 1482 | + },{ | |
| 1483 | + label: "Monospace message font", | |
| 1484 | + hint: "Use monospace font for message and input text.", | |
| 1485 | + boolValue: 'monospace-messages', | |
| 1486 | + callback: function(setting){ | |
| 1487 | + document.body.classList[ | |
| 1488 | + setting.value ? 'add' : 'remove' | |
| 1489 | + ]('monospace-messages'); | |
| 1490 | + } | |
| 1491 | + },{ | |
| 1492 | + label: "Show images inline", | |
| 1493 | + hint: "When enabled, attached images are shown inline, "+ | |
| 1494 | + "else they appear as a download link.", | |
| 1495 | + boolValue: 'images-inline' | |
| 1496 | + }] | |
| 1486 | 1497 | }]; |
| 1487 | 1498 | |
| 1488 | 1499 | /** Set up selection list of notification sounds. */ |
| 1489 | 1500 | if(1){ |
| 1490 | 1501 | const selectSound = D.select(); |
| @@ -1515,20 +1526,20 @@ | ||
| 1515 | 1526 | Chat.setNewMessageSound(v); |
| 1516 | 1527 | F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+"."); |
| 1517 | 1528 | if(v) setTimeout(()=>Chat.playNewMessageSound(), 0); |
| 1518 | 1529 | } |
| 1519 | 1530 | },{ |
| 1520 | - label: "Play notification for your own messages.", | |
| 1531 | + label: "Play notification for your own messages", | |
| 1521 | 1532 | hint: "When enabled, the audio notification will be played for all messages, "+ |
| 1522 | 1533 | "including your own. When disabled only messages from other users "+ |
| 1523 | 1534 | "will trigger a notification.", |
| 1524 | 1535 | boolValue: 'alert-own-messages' |
| 1525 | 1536 | }] |
| 1526 | 1537 | }); |
| 1527 | 1538 | }/*audio notification config*/ |
| 1528 | 1539 | settingsOps.push({ |
| 1529 | - label: "Active User List", | |
| 1540 | + label: "Active User List...", | |
| 1530 | 1541 | hint: [ |
| 1531 | 1542 | "/chat cannot track active connections, but it can tell ", |
| 1532 | 1543 | "you who has posted recently..."].join(''), |
| 1533 | 1544 | children:[ |
| 1534 | 1545 | namedOptions.activeUsers,{ |
| @@ -1541,23 +1552,23 @@ | ||
| 1541 | 1552 | }); |
| 1542 | 1553 | /** |
| 1543 | 1554 | Build UI for config options... |
| 1544 | 1555 | */ |
| 1545 | 1556 | settingsOps.forEach(function f(op,indentOrIndex){ |
| 1546 | - const line = D.addClass(D.div(), 'menu-entry'); | |
| 1547 | - if(true===indentOrIndex) D.addClass(line, 'indent'); | |
| 1557 | + const menuEntry = D.addClass(D.div(), 'menu-entry'); | |
| 1558 | + if(true===indentOrIndex) D.addClass(menuEntry, 'child'); | |
| 1548 | 1559 | const label = op.label |
| 1549 | 1560 | ? D.append(D.label(),op.label) : undefined; |
| 1550 | 1561 | const labelWrapper = D.addClass(D.div(), 'label-wrapper'); |
| 1551 | 1562 | var hint; |
| 1552 | 1563 | if(op.hint){ |
| 1553 | - hint = D.append(D.addClass(D.span(),'hint'),op.hint); | |
| 1564 | + hint = D.append(D.addClass(D.label(),'hint'),op.hint); | |
| 1554 | 1565 | } |
| 1555 | 1566 | if(op.hasOwnProperty('select')){ |
| 1556 | 1567 | const col0 = D.addClass(D.span(/*empty, but for spacing*/), |
| 1557 | 1568 | 'toggle-wrapper'); |
| 1558 | - D.append(line, labelWrapper, col0); | |
| 1569 | + D.append(menuEntry, labelWrapper, col0); | |
| 1559 | 1570 | D.append(labelWrapper, op.select); |
| 1560 | 1571 | if(hint) D.append(labelWrapper, hint); |
| 1561 | 1572 | if(label) D.append(label); |
| 1562 | 1573 | if(op.callback){ |
| 1563 | 1574 | op.select.addEventListener('change', (ev)=>op.callback(ev), false); |
| @@ -1576,26 +1587,27 @@ | ||
| 1576 | 1587 | const id = 'cfgopt'+f.$id; |
| 1577 | 1588 | const col0 = D.addClass(D.span(), 'toggle-wrapper'); |
| 1578 | 1589 | check.checked = op.boolValue(); |
| 1579 | 1590 | op.checkbox = check; |
| 1580 | 1591 | D.attr(check, 'id', id); |
| 1581 | - D.append(line, labelWrapper, col0); | |
| 1592 | + if(hint) D.attr(hint, 'for', id); | |
| 1593 | + D.append(menuEntry, labelWrapper, col0); | |
| 1582 | 1594 | D.append(col0, check); |
| 1583 | 1595 | if(label){ |
| 1584 | 1596 | D.attr(label, 'for', id); |
| 1585 | 1597 | D.append(labelWrapper, label); |
| 1586 | 1598 | } |
| 1587 | 1599 | if(hint) D.append(labelWrapper, hint); |
| 1588 | 1600 | }else{ |
| 1589 | 1601 | if(op.callback){ |
| 1590 | - line.addEventListener('click', (ev)=>op.callback(ev)); | |
| 1602 | + menuEntry.addEventListener('click', (ev)=>op.callback(ev)); | |
| 1591 | 1603 | } |
| 1592 | - D.append(line, labelWrapper); | |
| 1604 | + D.append(menuEntry, labelWrapper); | |
| 1593 | 1605 | if(label) D.append(labelWrapper, label); |
| 1594 | 1606 | if(hint) D.append(labelWrapper, hint); |
| 1595 | 1607 | } |
| 1596 | - D.append(optionsMenu, line); | |
| 1608 | + D.append(optionsMenu, menuEntry); | |
| 1597 | 1609 | if(op.persistentSetting){ |
| 1598 | 1610 | Chat.settings.addListener( |
| 1599 | 1611 | op.persistentSetting, |
| 1600 | 1612 | function(setting){ |
| 1601 | 1613 | if(op.checkbox) op.checkbox.checked = !!setting.value; |
| @@ -1610,11 +1622,14 @@ | ||
| 1610 | 1622 | }, false); |
| 1611 | 1623 | } |
| 1612 | 1624 | }else if(op.callback && op.checkbox){ |
| 1613 | 1625 | op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false); |
| 1614 | 1626 | } |
| 1615 | - if(op.children) op.children.forEach((x)=>f(x,true)); | |
| 1627 | + if(op.children){ | |
| 1628 | + D.addClass(menuEntry, 'parent'); | |
| 1629 | + op.children.forEach((x)=>f(x,true)); | |
| 1630 | + } | |
| 1616 | 1631 | }); |
| 1617 | 1632 | })()/*#chat-button-settings setup*/; |
| 1618 | 1633 | |
| 1619 | 1634 | (function(){ |
| 1620 | 1635 | /* Install default settings... must come after |
| 1621 | 1636 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -1428,63 +1428,74 @@ | |
| 1428 | events. The checkbox element gets added to the options object |
| 1429 | so that the callback() can reference it via this.checkbox. |
| 1430 | */ |
| 1431 | const settingsOps = [{ |
| 1432 | label: "Chat Configuration Options", |
| 1433 | hint: "Most of these settings are persistent via window.localStorage." |
| 1434 | },{ |
| 1435 | label: "Chat-only mode", |
| 1436 | hint: "Toggle the page between normal fossil view and chat-only view.", |
| 1437 | boolValue: 'chat-only-mode' |
| 1438 | },{ |
| 1439 | label: "Ctrl-enter to Send", |
| 1440 | hint: [ |
| 1441 | "When on, only Ctrl-Enter will send messages and Enter adds ", |
| 1442 | "blank lines. When off, both Enter and Ctrl-Enter send. ", |
| 1443 | "When the input field has focus, is empty, and preview ", |
| 1444 | "mode is NOT active then Ctrl-Enter toggles this setting." |
| 1445 | ].join(''), |
| 1446 | boolValue: 'edit-ctrl-send' |
| 1447 | },{ |
| 1448 | label: "Compact mode", |
| 1449 | hint: [ |
| 1450 | "Toggle between a space-saving or more spacious writing area. ", |
| 1451 | "When the input field has focus, is empty, and preview mode ", |
| 1452 | "is NOT active then Shift-Enter toggles this setting."].join(''), |
| 1453 | boolValue: 'edit-compact-mode' |
| 1454 | },{ |
| 1455 | label: "Left-align my posts", |
| 1456 | hint: "Default alignment of your own messages is selected " |
| 1457 | + "based window width/height relationship.", |
| 1458 | boolValue: ()=>!document.body.classList.contains('my-messages-right'), |
| 1459 | callback: function f(){ |
| 1460 | document.body.classList[ |
| 1461 | this.checkbox.checked ? 'remove' : 'add' |
| 1462 | ]('my-messages-right'); |
| 1463 | } |
| 1464 | },{ |
| 1465 | label: "Monospace message font", |
| 1466 | hint: "Use monospace font for message and input text.", |
| 1467 | boolValue: 'monospace-messages', |
| 1468 | callback: function(setting){ |
| 1469 | document.body.classList[ |
| 1470 | setting.value ? 'add' : 'remove' |
| 1471 | ]('monospace-messages'); |
| 1472 | } |
| 1473 | },{ |
| 1474 | label: "Show images inline", |
| 1475 | hint: "Show attached images inline or as a download link.", |
| 1476 | boolValue: 'images-inline' |
| 1477 | },{ |
| 1478 | label: "Use 'contenteditable' editing mode.", |
| 1479 | boolValue: 'edit-widget-x', |
| 1480 | hint: [ |
| 1481 | "When enabled, chat input uses a so-called 'contenteditable' ", |
| 1482 | "field. Though generally more comfortable and modern than ", |
| 1483 | "plain-text input fields, browser-specific quirks and bugs ", |
| 1484 | "may lead to frustration." |
| 1485 | ].join('') |
| 1486 | }]; |
| 1487 | |
| 1488 | /** Set up selection list of notification sounds. */ |
| 1489 | if(1){ |
| 1490 | const selectSound = D.select(); |
| @@ -1515,20 +1526,20 @@ | |
| 1515 | Chat.setNewMessageSound(v); |
| 1516 | F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+"."); |
| 1517 | if(v) setTimeout(()=>Chat.playNewMessageSound(), 0); |
| 1518 | } |
| 1519 | },{ |
| 1520 | label: "Play notification for your own messages.", |
| 1521 | hint: "When enabled, the audio notification will be played for all messages, "+ |
| 1522 | "including your own. When disabled only messages from other users "+ |
| 1523 | "will trigger a notification.", |
| 1524 | boolValue: 'alert-own-messages' |
| 1525 | }] |
| 1526 | }); |
| 1527 | }/*audio notification config*/ |
| 1528 | settingsOps.push({ |
| 1529 | label: "Active User List", |
| 1530 | hint: [ |
| 1531 | "/chat cannot track active connections, but it can tell ", |
| 1532 | "you who has posted recently..."].join(''), |
| 1533 | children:[ |
| 1534 | namedOptions.activeUsers,{ |
| @@ -1541,23 +1552,23 @@ | |
| 1541 | }); |
| 1542 | /** |
| 1543 | Build UI for config options... |
| 1544 | */ |
| 1545 | settingsOps.forEach(function f(op,indentOrIndex){ |
| 1546 | const line = D.addClass(D.div(), 'menu-entry'); |
| 1547 | if(true===indentOrIndex) D.addClass(line, 'indent'); |
| 1548 | const label = op.label |
| 1549 | ? D.append(D.label(),op.label) : undefined; |
| 1550 | const labelWrapper = D.addClass(D.div(), 'label-wrapper'); |
| 1551 | var hint; |
| 1552 | if(op.hint){ |
| 1553 | hint = D.append(D.addClass(D.span(),'hint'),op.hint); |
| 1554 | } |
| 1555 | if(op.hasOwnProperty('select')){ |
| 1556 | const col0 = D.addClass(D.span(/*empty, but for spacing*/), |
| 1557 | 'toggle-wrapper'); |
| 1558 | D.append(line, labelWrapper, col0); |
| 1559 | D.append(labelWrapper, op.select); |
| 1560 | if(hint) D.append(labelWrapper, hint); |
| 1561 | if(label) D.append(label); |
| 1562 | if(op.callback){ |
| 1563 | op.select.addEventListener('change', (ev)=>op.callback(ev), false); |
| @@ -1576,26 +1587,27 @@ | |
| 1576 | const id = 'cfgopt'+f.$id; |
| 1577 | const col0 = D.addClass(D.span(), 'toggle-wrapper'); |
| 1578 | check.checked = op.boolValue(); |
| 1579 | op.checkbox = check; |
| 1580 | D.attr(check, 'id', id); |
| 1581 | D.append(line, labelWrapper, col0); |
| 1582 | D.append(col0, check); |
| 1583 | if(label){ |
| 1584 | D.attr(label, 'for', id); |
| 1585 | D.append(labelWrapper, label); |
| 1586 | } |
| 1587 | if(hint) D.append(labelWrapper, hint); |
| 1588 | }else{ |
| 1589 | if(op.callback){ |
| 1590 | line.addEventListener('click', (ev)=>op.callback(ev)); |
| 1591 | } |
| 1592 | D.append(line, labelWrapper); |
| 1593 | if(label) D.append(labelWrapper, label); |
| 1594 | if(hint) D.append(labelWrapper, hint); |
| 1595 | } |
| 1596 | D.append(optionsMenu, line); |
| 1597 | if(op.persistentSetting){ |
| 1598 | Chat.settings.addListener( |
| 1599 | op.persistentSetting, |
| 1600 | function(setting){ |
| 1601 | if(op.checkbox) op.checkbox.checked = !!setting.value; |
| @@ -1610,11 +1622,14 @@ | |
| 1610 | }, false); |
| 1611 | } |
| 1612 | }else if(op.callback && op.checkbox){ |
| 1613 | op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false); |
| 1614 | } |
| 1615 | if(op.children) op.children.forEach((x)=>f(x,true)); |
| 1616 | }); |
| 1617 | })()/*#chat-button-settings setup*/; |
| 1618 | |
| 1619 | (function(){ |
| 1620 | /* Install default settings... must come after |
| 1621 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -1428,63 +1428,74 @@ | |
| 1428 | events. The checkbox element gets added to the options object |
| 1429 | so that the callback() can reference it via this.checkbox. |
| 1430 | */ |
| 1431 | const settingsOps = [{ |
| 1432 | label: "Chat Configuration Options", |
| 1433 | hint: F.storage.isTransient() |
| 1434 | ? "Local store is unavailable. These settings are transient." |
| 1435 | : ["Most of these settings are persistent via ", |
| 1436 | F.storage.storageImplName(), ": ", |
| 1437 | F.storage.storageHelpDescription()].join('') |
| 1438 | },{ |
| 1439 | label: "Editing Options...", |
| 1440 | children:[{ |
| 1441 | label: "Chat-only mode", |
| 1442 | hint: "Toggle the page between normal fossil view and chat-only view.", |
| 1443 | boolValue: 'chat-only-mode' |
| 1444 | },{ |
| 1445 | label: "Ctrl-enter to Send", |
| 1446 | hint: [ |
| 1447 | "When on, only Ctrl-Enter will send messages and Enter adds ", |
| 1448 | "blank lines. When off, both Enter and Ctrl-Enter send. ", |
| 1449 | "When the input field has focus and is empty ", |
| 1450 | "then Ctrl-Enter toggles this setting." |
| 1451 | ].join(''), |
| 1452 | boolValue: 'edit-ctrl-send' |
| 1453 | },{ |
| 1454 | label: "Compact mode", |
| 1455 | hint: [ |
| 1456 | "Toggle between a space-saving or more spacious writing area. ", |
| 1457 | "When the input field has focus, is empty, and preview mode ", |
| 1458 | "is NOT active then Shift-Enter toggles this setting."].join(''), |
| 1459 | boolValue: 'edit-compact-mode' |
| 1460 | },{ |
| 1461 | label: "Use 'contenteditable' editing mode", |
| 1462 | boolValue: 'edit-widget-x', |
| 1463 | hint: [ |
| 1464 | "When enabled, chat input uses a so-called 'contenteditable' ", |
| 1465 | "field. Though generally more comfortable and modern than ", |
| 1466 | "plain-text input fields, browser-specific quirks and bugs ", |
| 1467 | "may lead to frustration. Ideal for mobile devices." |
| 1468 | ].join('') |
| 1469 | }] |
| 1470 | },{ |
| 1471 | label: "Appearance Options...", |
| 1472 | children:[{ |
| 1473 | label: "Left-align my posts", |
| 1474 | hint: "Default alignment of your own messages is selected " |
| 1475 | + "based window width/height ratio.", |
| 1476 | boolValue: ()=>!document.body.classList.contains('my-messages-right'), |
| 1477 | callback: function f(){ |
| 1478 | document.body.classList[ |
| 1479 | this.checkbox.checked ? 'remove' : 'add' |
| 1480 | ]('my-messages-right'); |
| 1481 | } |
| 1482 | },{ |
| 1483 | label: "Monospace message font", |
| 1484 | hint: "Use monospace font for message and input text.", |
| 1485 | boolValue: 'monospace-messages', |
| 1486 | callback: function(setting){ |
| 1487 | document.body.classList[ |
| 1488 | setting.value ? 'add' : 'remove' |
| 1489 | ]('monospace-messages'); |
| 1490 | } |
| 1491 | },{ |
| 1492 | label: "Show images inline", |
| 1493 | hint: "When enabled, attached images are shown inline, "+ |
| 1494 | "else they appear as a download link.", |
| 1495 | boolValue: 'images-inline' |
| 1496 | }] |
| 1497 | }]; |
| 1498 | |
| 1499 | /** Set up selection list of notification sounds. */ |
| 1500 | if(1){ |
| 1501 | const selectSound = D.select(); |
| @@ -1515,20 +1526,20 @@ | |
| 1526 | Chat.setNewMessageSound(v); |
| 1527 | F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+"."); |
| 1528 | if(v) setTimeout(()=>Chat.playNewMessageSound(), 0); |
| 1529 | } |
| 1530 | },{ |
| 1531 | label: "Play notification for your own messages", |
| 1532 | hint: "When enabled, the audio notification will be played for all messages, "+ |
| 1533 | "including your own. When disabled only messages from other users "+ |
| 1534 | "will trigger a notification.", |
| 1535 | boolValue: 'alert-own-messages' |
| 1536 | }] |
| 1537 | }); |
| 1538 | }/*audio notification config*/ |
| 1539 | settingsOps.push({ |
| 1540 | label: "Active User List...", |
| 1541 | hint: [ |
| 1542 | "/chat cannot track active connections, but it can tell ", |
| 1543 | "you who has posted recently..."].join(''), |
| 1544 | children:[ |
| 1545 | namedOptions.activeUsers,{ |
| @@ -1541,23 +1552,23 @@ | |
| 1552 | }); |
| 1553 | /** |
| 1554 | Build UI for config options... |
| 1555 | */ |
| 1556 | settingsOps.forEach(function f(op,indentOrIndex){ |
| 1557 | const menuEntry = D.addClass(D.div(), 'menu-entry'); |
| 1558 | if(true===indentOrIndex) D.addClass(menuEntry, 'child'); |
| 1559 | const label = op.label |
| 1560 | ? D.append(D.label(),op.label) : undefined; |
| 1561 | const labelWrapper = D.addClass(D.div(), 'label-wrapper'); |
| 1562 | var hint; |
| 1563 | if(op.hint){ |
| 1564 | hint = D.append(D.addClass(D.label(),'hint'),op.hint); |
| 1565 | } |
| 1566 | if(op.hasOwnProperty('select')){ |
| 1567 | const col0 = D.addClass(D.span(/*empty, but for spacing*/), |
| 1568 | 'toggle-wrapper'); |
| 1569 | D.append(menuEntry, labelWrapper, col0); |
| 1570 | D.append(labelWrapper, op.select); |
| 1571 | if(hint) D.append(labelWrapper, hint); |
| 1572 | if(label) D.append(label); |
| 1573 | if(op.callback){ |
| 1574 | op.select.addEventListener('change', (ev)=>op.callback(ev), false); |
| @@ -1576,26 +1587,27 @@ | |
| 1587 | const id = 'cfgopt'+f.$id; |
| 1588 | const col0 = D.addClass(D.span(), 'toggle-wrapper'); |
| 1589 | check.checked = op.boolValue(); |
| 1590 | op.checkbox = check; |
| 1591 | D.attr(check, 'id', id); |
| 1592 | if(hint) D.attr(hint, 'for', id); |
| 1593 | D.append(menuEntry, labelWrapper, col0); |
| 1594 | D.append(col0, check); |
| 1595 | if(label){ |
| 1596 | D.attr(label, 'for', id); |
| 1597 | D.append(labelWrapper, label); |
| 1598 | } |
| 1599 | if(hint) D.append(labelWrapper, hint); |
| 1600 | }else{ |
| 1601 | if(op.callback){ |
| 1602 | menuEntry.addEventListener('click', (ev)=>op.callback(ev)); |
| 1603 | } |
| 1604 | D.append(menuEntry, labelWrapper); |
| 1605 | if(label) D.append(labelWrapper, label); |
| 1606 | if(hint) D.append(labelWrapper, hint); |
| 1607 | } |
| 1608 | D.append(optionsMenu, menuEntry); |
| 1609 | if(op.persistentSetting){ |
| 1610 | Chat.settings.addListener( |
| 1611 | op.persistentSetting, |
| 1612 | function(setting){ |
| 1613 | if(op.checkbox) op.checkbox.checked = !!setting.value; |
| @@ -1610,11 +1622,14 @@ | |
| 1622 | }, false); |
| 1623 | } |
| 1624 | }else if(op.callback && op.checkbox){ |
| 1625 | op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false); |
| 1626 | } |
| 1627 | if(op.children){ |
| 1628 | D.addClass(menuEntry, 'parent'); |
| 1629 | op.children.forEach((x)=>f(x,true)); |
| 1630 | } |
| 1631 | }); |
| 1632 | })()/*#chat-button-settings setup*/; |
| 1633 | |
| 1634 | (function(){ |
| 1635 | /* Install default settings... must come after |
| 1636 |
+15
-8
| --- src/style.chat.css | ||
| +++ src/style.chat.css | ||
| @@ -277,12 +277,12 @@ | ||
| 277 | 277 | border-width: 1px; |
| 278 | 278 | border-style: solid; |
| 279 | 279 | border-radius: 0.25em; |
| 280 | 280 | min-width: 4ex; |
| 281 | 281 | max-width: 4ex; |
| 282 | - min-height: 4ex; | |
| 283 | - max-height: 4ex; | |
| 282 | + min-height: 3ex; | |
| 283 | + max-height: 3ex; | |
| 284 | 284 | margin: 0.125em; |
| 285 | 285 | display: inline-flex; |
| 286 | 286 | justify-content: center; |
| 287 | 287 | align-items: center; |
| 288 | 288 | cursor: pointer; |
| @@ -406,35 +406,41 @@ | ||
| 406 | 406 | align-items: stretch; |
| 407 | 407 | } |
| 408 | 408 | body.chat #chat-config #chat-config-options .menu-entry { |
| 409 | 409 | display: flex; |
| 410 | 410 | align-items: center; |
| 411 | - flex-direction: row; | |
| 411 | + flex-direction: row-reverse; | |
| 412 | 412 | flex-wrap: nowrap; |
| 413 | 413 | padding: 1em; |
| 414 | 414 | flex: 1 1 auto; |
| 415 | 415 | align-self: stretch; |
| 416 | 416 | } |
| 417 | -body.chat #chat-config #chat-config-options .menu-entry.indent { | |
| 418 | - padding-left: 2.5em; | |
| 417 | +body.chat #chat-config #chat-config-options .menu-entry.parent{ | |
| 418 | + border-radius: 1em 1em 0 1em; | |
| 419 | + margin-top: 1em; | |
| 420 | +} | |
| 421 | +body.chat #chat-config #chat-config-options .menu-entry.child { | |
| 422 | + /*padding-left: 2.5em;*/ | |
| 423 | + margin-left: 2em; | |
| 419 | 424 | } |
| 420 | 425 | body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){ |
| 421 | - background-color: rgba(175,175,175,0.1); | |
| 426 | + background-color: rgba(175,175,175,0.15); | |
| 422 | 427 | } |
| 423 | 428 | body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){ |
| 424 | - background-color: rgba(175,175,175,0.25); | |
| 429 | + background-color: rgba(175,175,175,0.35); | |
| 425 | 430 | } |
| 426 | 431 | body.chat #chat-config #chat-config-options .menu-entry:first-child { |
| 427 | 432 | /* Config list header */ |
| 433 | + border-radius: 0 0 1em 1em; | |
| 428 | 434 | } |
| 429 | 435 | body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper { |
| 430 | 436 | align-items: start; |
| 431 | 437 | } |
| 432 | 438 | body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper { |
| 433 | 439 | /* Holder for a checkbox, if any */ |
| 434 | 440 | min-width: 1.5rem; |
| 435 | - margin-left: 1rem; | |
| 441 | + margin-right: 1rem; | |
| 436 | 442 | } |
| 437 | 443 | body.chat #chat-config #chat-config-options .menu-entry .label-wrapper { |
| 438 | 444 | /* Wrapper for a LABEL and a .hint element. */ |
| 439 | 445 | display: flex; |
| 440 | 446 | flex-direction: column; |
| @@ -450,10 +456,11 @@ | ||
| 450 | 456 | cursor: pointer; |
| 451 | 457 | } |
| 452 | 458 | body.chat #chat-config #chat-config-options .menu-entry .hint { |
| 453 | 459 | /* Config menu hint text */ |
| 454 | 460 | font-size: 85%; |
| 461 | + font-weight: normal; | |
| 455 | 462 | white-space: pre-wrap; |
| 456 | 463 | display: inline-block; |
| 457 | 464 | opacity: 0.85; |
| 458 | 465 | } |
| 459 | 466 | body.chat #chat-config #chat-config-options .menu-entry select { |
| 460 | 467 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -277,12 +277,12 @@ | |
| 277 | border-width: 1px; |
| 278 | border-style: solid; |
| 279 | border-radius: 0.25em; |
| 280 | min-width: 4ex; |
| 281 | max-width: 4ex; |
| 282 | min-height: 4ex; |
| 283 | max-height: 4ex; |
| 284 | margin: 0.125em; |
| 285 | display: inline-flex; |
| 286 | justify-content: center; |
| 287 | align-items: center; |
| 288 | cursor: pointer; |
| @@ -406,35 +406,41 @@ | |
| 406 | align-items: stretch; |
| 407 | } |
| 408 | body.chat #chat-config #chat-config-options .menu-entry { |
| 409 | display: flex; |
| 410 | align-items: center; |
| 411 | flex-direction: row; |
| 412 | flex-wrap: nowrap; |
| 413 | padding: 1em; |
| 414 | flex: 1 1 auto; |
| 415 | align-self: stretch; |
| 416 | } |
| 417 | body.chat #chat-config #chat-config-options .menu-entry.indent { |
| 418 | padding-left: 2.5em; |
| 419 | } |
| 420 | body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){ |
| 421 | background-color: rgba(175,175,175,0.1); |
| 422 | } |
| 423 | body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){ |
| 424 | background-color: rgba(175,175,175,0.25); |
| 425 | } |
| 426 | body.chat #chat-config #chat-config-options .menu-entry:first-child { |
| 427 | /* Config list header */ |
| 428 | } |
| 429 | body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper { |
| 430 | align-items: start; |
| 431 | } |
| 432 | body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper { |
| 433 | /* Holder for a checkbox, if any */ |
| 434 | min-width: 1.5rem; |
| 435 | margin-left: 1rem; |
| 436 | } |
| 437 | body.chat #chat-config #chat-config-options .menu-entry .label-wrapper { |
| 438 | /* Wrapper for a LABEL and a .hint element. */ |
| 439 | display: flex; |
| 440 | flex-direction: column; |
| @@ -450,10 +456,11 @@ | |
| 450 | cursor: pointer; |
| 451 | } |
| 452 | body.chat #chat-config #chat-config-options .menu-entry .hint { |
| 453 | /* Config menu hint text */ |
| 454 | font-size: 85%; |
| 455 | white-space: pre-wrap; |
| 456 | display: inline-block; |
| 457 | opacity: 0.85; |
| 458 | } |
| 459 | body.chat #chat-config #chat-config-options .menu-entry select { |
| 460 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -277,12 +277,12 @@ | |
| 277 | border-width: 1px; |
| 278 | border-style: solid; |
| 279 | border-radius: 0.25em; |
| 280 | min-width: 4ex; |
| 281 | max-width: 4ex; |
| 282 | min-height: 3ex; |
| 283 | max-height: 3ex; |
| 284 | margin: 0.125em; |
| 285 | display: inline-flex; |
| 286 | justify-content: center; |
| 287 | align-items: center; |
| 288 | cursor: pointer; |
| @@ -406,35 +406,41 @@ | |
| 406 | align-items: stretch; |
| 407 | } |
| 408 | body.chat #chat-config #chat-config-options .menu-entry { |
| 409 | display: flex; |
| 410 | align-items: center; |
| 411 | flex-direction: row-reverse; |
| 412 | flex-wrap: nowrap; |
| 413 | padding: 1em; |
| 414 | flex: 1 1 auto; |
| 415 | align-self: stretch; |
| 416 | } |
| 417 | body.chat #chat-config #chat-config-options .menu-entry.parent{ |
| 418 | border-radius: 1em 1em 0 1em; |
| 419 | margin-top: 1em; |
| 420 | } |
| 421 | body.chat #chat-config #chat-config-options .menu-entry.child { |
| 422 | /*padding-left: 2.5em;*/ |
| 423 | margin-left: 2em; |
| 424 | } |
| 425 | body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){ |
| 426 | background-color: rgba(175,175,175,0.15); |
| 427 | } |
| 428 | body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){ |
| 429 | background-color: rgba(175,175,175,0.35); |
| 430 | } |
| 431 | body.chat #chat-config #chat-config-options .menu-entry:first-child { |
| 432 | /* Config list header */ |
| 433 | border-radius: 0 0 1em 1em; |
| 434 | } |
| 435 | body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper { |
| 436 | align-items: start; |
| 437 | } |
| 438 | body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper { |
| 439 | /* Holder for a checkbox, if any */ |
| 440 | min-width: 1.5rem; |
| 441 | margin-right: 1rem; |
| 442 | } |
| 443 | body.chat #chat-config #chat-config-options .menu-entry .label-wrapper { |
| 444 | /* Wrapper for a LABEL and a .hint element. */ |
| 445 | display: flex; |
| 446 | flex-direction: column; |
| @@ -450,10 +456,11 @@ | |
| 456 | cursor: pointer; |
| 457 | } |
| 458 | body.chat #chat-config #chat-config-options .menu-entry .hint { |
| 459 | /* Config menu hint text */ |
| 460 | font-size: 85%; |
| 461 | font-weight: normal; |
| 462 | white-space: pre-wrap; |
| 463 | display: inline-block; |
| 464 | opacity: 0.85; |
| 465 | } |
| 466 | body.chat #chat-config #chat-config-options .menu-entry select { |
| 467 |