diff --git a/assets/styles/_utils.scss b/assets/styles/_utils.scss
new file mode 100644
index 00000000..cf3dc274
--- /dev/null
+++ b/assets/styles/_utils.scss
@@ -0,0 +1,31 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+@use "variables";
+
+.peertube-plugin-livechat-experimental,
+.peertube-plugin-livechat-warning {
+ color: orange;
+}
+
+.peertube-plugin-livechat-error {
+ color: variables.$error-color;
+}
+
+.peertube-plugin-livechat-error-message {
+ /* display an error block (page not found, ...) */
+ display: block;
+ font-size: 20px;
+ padding-top: 50px;
+ text-align: center;
+ width: 100%;
+}
+
+.peertube-plugin-livechat-container {
+ .peertube-plugin-livechat-error-message {
+ max-width: 30vw;
+ }
+}
diff --git a/assets/styles/_variables.scss b/assets/styles/_variables.scss
new file mode 100644
index 00000000..e302d820
--- /dev/null
+++ b/assets/styles/_variables.scss
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+$error-color: red;
+
+/*
+ Here we are getting some Peertube variables (see _variables.scss in Peertube source code):
+ */
+
+$font-size: 13px;
+$button-calc-line-height: 19px; // $font-size + math.round(math.div($font-size, 2));
+$button-font-size: 15px;
+$font-bold: 700;
+$font-semibold: 600;
+$grey-actor-name: #777272;
+$sub-menu-margin-bottom: 30px;
diff --git a/assets/styles/configuration.scss b/assets/styles/configuration.scss
deleted file mode 100644
index 4cd1c76f..00000000
--- a/assets/styles/configuration.scss
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2024 John Livingston
- *
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-/* stylelint-disable custom-property-pattern */
-
-@use "sass:color";
-
-/*
- Here we are getting some Peertube variables (see _variables.scss in Peertube source code):
- We are disabling stylelint-disable custom-property-pattern so we can use Peertube var without warnings.
-*/
-$font-size: 13px;
-$button-calc-line-height: 19px; // $font-size + math.round(math.div($font-size, 2));
-$button-font-size: 15px;
-$font-bold: 700;
-$font-semibold: 600;
-$grey-actor-name: #777272;
-$grey-background-color: var(--greyBackgroundColor);
-$sub-menu-margin-bottom: 30px;
-$small-view: 800px;
-
-livechat-help-button {
- a {
- height: 18px !important;
- margin: 2px !important;
- padding: 1px !important;
- vertical-align: middle;
- }
-
- svg {
- display: block;
- height: auto;
- }
-}
-
-/*
- These are styles to apply for the channel configuration pages.
-*/
-.peertube-plugin-livechat-configuration {
- h1 {
- padding-top: 40px;
-
- /* See Peertube sub-menu-h1 mixin */
- font-size: 1.3rem;
- border-bottom: 2px solid $grey-background-color;
- padding-bottom: 15px;
- }
-
- livechat-channel-tabs {
- display: block;
-
- /* See Peertube sub-menu-h1 mixin */
- margin-bottom: $sub-menu-margin-bottom;
- }
-
- /* Channel configuration page */
- &.peertube-plugin-livechat-configuration-channel {
- .peertube-plugin-livechat-configuration-channel-info {
- /* stylelint-disable-next-line value-keyword-case */
- color: var(--mainForegroundColor);
-
- span:first-child {
- /* See Peertube .video-channel-display-name */
- font-weight: $font-semibold;
- font-size: 18px;
- }
-
- span:not(:first-child) {
- /* See Peertube .video-channel-name */
- margin-left: 5px;
- font-size: 14px;
- color: $grey-actor-name;
- }
- }
-
- h2 {
- // See Peertube settings-big-title mixin
- text-transform: uppercase;
- color: var(--mainColor);
- font-weight: $font-bold;
- font-size: 1rem;
- margin-bottom: 10px;
- }
-
- input[type="submit"],
- input[type="reset"],
- button[type="submit"],
- button[type="reset"],
- .peertube-plugin-livechat-configuration-actions button,
- .peertube-plugin-livechat-tags-input-copy {
- // Peertube rounded-line-height-1-5 mixins
- line-height: $button-calc-line-height;
-
- // Peertube peertube-button mixin
- padding: 4px 13px;
- border: 0;
- font-weight: $font-semibold;
- border-radius: 3px !important;
- text-align: center;
- cursor: pointer;
- font-size: $button-font-size;
- }
-
- input[type="submit"],
- button[type="submit"],
- .peertube-plugin-livechat-configuration-actions button,
- .peertube-plugin-livechat-tags-input-copy {
- // Peertube orange-button mixin
- &,
- &:active,
- &:focus {
- color: #fff;
- background-color: var(--mainColor);
- }
-
- &:hover {
- color: #fff;
- background-color: var(--mainHoverColor);
- }
-
- &[disabled],
- &.disabled {
- cursor: default;
- color: #fff;
- background-color: var(--inputBorderColor);
- }
- }
-
- input[type="reset"],
- button[type="reset"] {
- // Peertube grey-button mixin
- background-color: var(--greyBackgroundColor);
- color: var(--greyForegroundColor);
-
- &:hover,
- &:active,
- &:focus,
- &[disabled],
- &.disabled {
- color: var(--greyForegroundColor);
- background-color: var(--greySecondaryBackgroundColor);
- }
-
- &[disabled],
- &.disabled {
- cursor: default;
- }
- }
- }
-
- /* Channel selection page */
- &.peertube-plugin-livechat-configuration-home {
- ul.peertube-plugin-livechat-configuration-home-channels {
- list-style-type: none;
-
- li {
- align-items: center;
- gap: 15px;
-
- /* See Peertube row-blocks mixin, used in video-channel */
- display: flex;
- min-height: 130px;
- padding-bottom: 20px;
- margin-bottom: 20px;
- /* stylelint-disable-next-line value-keyword-case */
- border-bottom: 1px solid var(--inputBorderColor);
-
- @media screen and (max-width: $small-view) {
- flex-direction: column;
- height: auto;
- align-items: center;
- }
-
- .avatar {
- /* See Peertube CSS, class avatar and avatar-80 */
- width: 80px;
- height: 80px;
- min-width: 80px;
- min-height: 80px;
-
- &.channel {
- border-radius: 5px;
- }
-
- &.initial {
- /* See Peertube actor-avatar.component.scss */
- background-color: #3c2109;
- color: #fff;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: var(--initialFontSize);
-
- &.gray {
- background-color: #939393;
- }
- }
- }
-
- .peertube-plugin-livechat-configuration-home-info {
- flex-grow: 1;
-
- a {
- /* See Peertube .video-channel-names */
- &:hover,
- &:focus,
- &:active {
- text-decoration: none !important;
- }
-
- &:focus:not(.focus-visible) {
- outline: none !important;
- }
-
- width: fit-content;
- display: flex;
- align-items: baseline;
- /* stylelint-disable-next-line value-keyword-case */
- color: var(--mainForegroundColor);
-
- div:first-child {
- /* See Peertube .video-channel-display-name */
- font-weight: $font-semibold;
- font-size: 18px;
- }
-
- div:not(:first-child) {
- /* See Peertube .video-channel-name */
- margin-left: 5px;
- font-size: 14px;
- color: $grey-actor-name;
- }
- }
- }
- }
- }
- }
-
- .peertube-livechat-emojis-col-sn {
- width: 30%;
- }
-
- .peertube-livechat-emojis-col-file {
- width: 65%;
- }
-
- .peertube-plugin-livechat-configuration-actions {
- margin-bottom: 1rem;
- text-align: right;
- }
-}
-
-livechat-dynamic-table-form {
- // We need this variable to be known at that time
- $bs-green: #39cc0b;
-
- display: block;
- margin-bottom: 3rem;
-
- table {
- table-layout: fixed;
- text-align: center;
-
- tr {
- border: 1px var(--greyBackgroundColor) solid;
- }
-
- td,
- th {
- word-wrap: break-word;
- vertical-align: top;
- padding: 5px 7px;
- }
-
- td:last-child {
- vertical-align: middle;
- min-width: 28px;
-
- > input:not([type="checkbox"]),
- textarea {
- min-width: 150px;
- }
- }
-
- tbody tr:nth-child(odd) {
- background-color: var(--greySecondaryBackgroundColor);
- }
-
- .livechat-dynamic-table-form-description-header {
- font-size: small;
- font-weight: lighter;
- }
- }
-
- .dynamic-table-add-row-cell {
- text-align: left;
- }
-
- .dynamic-table-add-row,
- .dynamic-table-remove-row {
- // Peertube rounded-line-height-1-5 mixins
- line-height: $button-calc-line-height;
-
- // Peertube peertube-button mixin (but with less horizontal padding)
- padding: 4px;
- border: 0;
- font-weight: $font-semibold;
- border-radius: 3px !important;
- text-align: center;
- cursor: pointer;
- font-size: $button-font-size;
- }
-
- .dynamic-table-add-row {
- background-color: var(--bs-green);
-
- &,
- &:active,
- &:focus {
- color: #fff;
- background-color: color.adjust($bs-green, $lightness: 5%);
- }
-
- &:focus,
- &.focus-visible {
- box-shadow: 0 0 0 0.2rem color.adjust($bs-green, $lightness: 20%);
- }
-
- &:hover {
- color: #fff;
- background-color: color.adjust($bs-green, $lightness: 10%);
- }
-
- &[disabled],
- &.disabled {
- cursor: default;
- color: #fff;
- background-color: var(--inputBorderColor);
- }
- }
-
- .dynamic-table-remove-row {
- background-color: var(--bs-orange);
-
- &,
- &:active,
- &:focus {
- color: #fff;
- background-color: var(--mainColor);
- }
-
- &:focus,
- &.focus-visible {
- box-shadow: 0 0 0 0.2rem var(--mainHoverColor);
- }
-
- &:hover {
- color: #fff;
- background-color: var(--mainHoverColor);
- }
-
- &[disabled],
- &.disabled {
- cursor: default;
- color: #fff;
- background-color: var(--inputBorderColor);
- }
- }
-}
-
-livechat-tags-input {
- --tag-padding-vertical: 3px;
- --tag-padding-horizontal: 6px;
-
- display: flex;
- align-items: flex-start;
- flex-wrap: wrap;
- max-width: 320px;
-
- .livechat-tags-container {
- align-items: center;
- display: flex;
- flex-flow: row;
- justify-content: space-between;
- }
-
- // stylelint trying to rearrange unrelated root blocks because of smaller blocks in them
- /* stylelint-disable-next-line no-descending-specificity */
- input {
- flex: 1;
- border: none;
- padding: 0;
- color: inherit;
- background-color: inherit;
- width: 100%;
-
- /* stylelint-disable-next-line no-descending-specificity */
- &:focus {
- outline: transparent;
- }
- }
-
- .livechat-tags,
- .livechat-tags-searched {
- display: flex;
- flex-wrap: wrap;
- padding: 0;
- margin: var(--tag-padding-vertical) 0;
- max-height: 150px;
- overflow-y: auto;
- transition-property: height, margin;
- transition-duration: 0.3s;
-
- @supports (scrollbar-width: auto) {
- scrollbar-color: var(--greyForegroundColor) transparent;
- scrollbar-width: thin;
- }
- }
-
- .livechat-tags-container,
- .livechat-tags-searched {
- border-bottom: 1px dashed var(--greyForegroundColor);
-
- &.livechat-empty {
- height: 0;
- margin: 0;
- border: none;
- }
- }
-
- .livechat-tags-searched {
- &::after {
- content: "\1F50D";
- flex-grow: 1;
- text-align: right;
- }
-
- &.livechat-empty {
- &::after {
- display: none;
- }
- }
- }
-
- .livechat-tag,
- .livechat-tag-searched {
- width: auto;
- height: 24px;
- display: flex;
- align-items: center;
- justify-content: center;
- color: #fff;
- padding: 0 var(--tag-padding-horizontal);
- font-size: 14px;
- list-style: none;
- border-radius: 3px;
- margin: 0 3px 3px 0;
- transition: 0.3s filter;
-
- .livechat-tag-close {
- display: block;
- width: 12px;
- height: 12px;
- line-height: 12px;
- text-align: center;
- font-size: 10px;
- margin-left: var(--tag-padding-horizontal);
- color: var(--mainColor);
- border-radius: 50%;
- background: #fff;
- cursor: pointer;
-
- &::before {
- content: "\2715";
- }
- }
-
- &,
- &:active,
- &:focus {
- color: #fff;
- background-color: var(--mainColor);
-
- .livechat-tag-close {
- color: var(--mainColor);
- }
- }
-
- &:hover {
- color: #fff;
- background-color: var(--mainHoverColor);
-
- .livechat-tag-close {
- color: var(--mainHoverColor);
- }
- }
-
- &[disabled],
- &.disabled {
- cursor: default;
- color: #fff;
- background-color: var(--inputBorderColor);
-
- .livechat-tag-close {
- color: var(--inputBorderColor);
- }
- }
-
- .livechat-tag-name {
- margin-top: 3px;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- max-width: 250px;
- }
- }
-
- .livechat-tags.livechat-unfocused .livechat-tag {
- filter: opacity(50%) grayscale(80%);
- }
-}
-
-livechat-image-file-input {
- img {
- cursor: pointer;
-
- // width and height are values coming from ConverseJS custom emojis.
- // If we want to upload something else, we should add options on the field to customize.
- max-height: 3em !important; // and no max-width
- }
-}
-
-livechat-configuration-section-header {
- margin-top: 3rem;
-}
diff --git a/assets/styles/configuration/_configuration.scss b/assets/styles/configuration/_configuration.scss
new file mode 100644
index 00000000..99094c4b
--- /dev/null
+++ b/assets/styles/configuration/_configuration.scss
@@ -0,0 +1,223 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+/* stylelint-disable custom-property-pattern */
+
+@use "sass:color";
+@use "elements/index";
+@use "../variables";
+
+$small-view: 800px;
+
+/*
+ These are styles to apply for the channel configuration pages.
+*/
+.peertube-plugin-livechat-configuration {
+ h1 {
+ padding-top: 40px;
+
+ /* See Peertube sub-menu-h1 mixin */
+ font-size: 1.3rem;
+ border-bottom: 2px solid var(--greyBackgroundColor);
+ padding-bottom: 15px;
+ }
+
+ /* Channel configuration page */
+ &.peertube-plugin-livechat-configuration-channel {
+ .peertube-plugin-livechat-configuration-channel-info {
+ /* stylelint-disable-next-line value-keyword-case */
+ color: var(--mainForegroundColor);
+
+ span:first-child {
+ /* See Peertube .video-channel-display-name */
+ font-weight: variables.$font-semibold;
+ font-size: 18px;
+ }
+
+ span:not(:first-child) {
+ /* See Peertube .video-channel-name */
+ margin-left: 5px;
+ font-size: 14px;
+ color: variables.$grey-actor-name;
+ }
+ }
+
+ h2 {
+ // See Peertube settings-big-title mixin
+ text-transform: uppercase;
+ color: var(--mainColor);
+ font-weight: variables.$font-bold;
+ font-size: 1rem;
+ margin-bottom: 10px;
+ }
+
+ input[type="submit"],
+ input[type="reset"],
+ button[type="submit"],
+ button[type="reset"],
+ .peertube-plugin-livechat-configuration-actions button,
+ .peertube-plugin-livechat-tags-input-copy {
+ // Peertube rounded-line-height-1-5 mixins
+ line-height: variables.$button-calc-line-height;
+
+ // Peertube peertube-button mixin
+ padding: 4px 13px;
+ border: 0;
+ font-weight: variables.$font-semibold;
+ border-radius: 3px !important;
+ text-align: center;
+ cursor: pointer;
+ font-size: variables.$button-font-size;
+ }
+
+ input[type="submit"],
+ button[type="submit"],
+ .peertube-plugin-livechat-configuration-actions button,
+ .peertube-plugin-livechat-tags-input-copy {
+ // Peertube orange-button mixin
+ &,
+ &:active,
+ &:focus {
+ color: #fff;
+ background-color: var(--mainColor);
+ }
+
+ &:hover {
+ color: #fff;
+ background-color: var(--mainHoverColor);
+ }
+
+ &[disabled],
+ &.disabled {
+ cursor: default;
+ color: #fff;
+ background-color: var(--inputBorderColor);
+ }
+ }
+
+ input[type="reset"],
+ button[type="reset"] {
+ // Peertube grey-button mixin
+ background-color: var(--greyBackgroundColor);
+ color: var(--greyForegroundColor);
+
+ &:hover,
+ &:active,
+ &:focus,
+ &[disabled],
+ &.disabled {
+ color: var(--greyForegroundColor);
+ background-color: var(--greySecondaryBackgroundColor);
+ }
+
+ &[disabled],
+ &.disabled {
+ cursor: default;
+ }
+ }
+ }
+
+ /* Channel selection page */
+ &.peertube-plugin-livechat-configuration-home {
+ ul.peertube-plugin-livechat-configuration-home-channels {
+ list-style-type: none;
+
+ li {
+ align-items: center;
+ gap: 15px;
+
+ /* See Peertube row-blocks mixin, used in video-channel */
+ display: flex;
+ min-height: 130px;
+ padding-bottom: 20px;
+ margin-bottom: 20px;
+ /* stylelint-disable-next-line value-keyword-case */
+ border-bottom: 1px solid var(--inputBorderColor);
+
+ @media screen and (max-width: $small-view) {
+ flex-direction: column;
+ height: auto;
+ align-items: center;
+ }
+
+ .avatar {
+ /* See Peertube CSS, class avatar and avatar-80 */
+ width: 80px;
+ height: 80px;
+ min-width: 80px;
+ min-height: 80px;
+
+ &.channel {
+ border-radius: 5px;
+ }
+
+ &.initial {
+ /* See Peertube actor-avatar.component.scss */
+ background-color: #3c2109;
+ color: #fff;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: var(--initialFontSize);
+
+ &.gray {
+ background-color: #939393;
+ }
+ }
+ }
+
+ .peertube-plugin-livechat-configuration-home-info {
+ flex-grow: 1;
+
+ a {
+ /* See Peertube .video-channel-names */
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: none !important;
+ }
+
+ &:focus:not(.focus-visible) {
+ outline: none !important;
+ }
+
+ width: fit-content;
+ display: flex;
+ align-items: baseline;
+ /* stylelint-disable-next-line value-keyword-case */
+ color: var(--mainForegroundColor);
+
+ div:first-child {
+ /* See Peertube .video-channel-display-name */
+ font-weight: variables.$font-semibold;
+ font-size: 18px;
+ }
+
+ div:not(:first-child) {
+ /* See Peertube .video-channel-name */
+ margin-left: 5px;
+ font-size: 14px;
+ color: variables.$grey-actor-name;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .peertube-livechat-emojis-col-sn {
+ width: 30%;
+ }
+
+ .peertube-livechat-emojis-col-file {
+ width: 65%;
+ }
+
+ .peertube-plugin-livechat-configuration-actions {
+ margin-bottom: 1rem;
+ text-align: right;
+ }
+}
diff --git a/assets/styles/configuration/elements/_channel-tabs.scss b/assets/styles/configuration/elements/_channel-tabs.scss
new file mode 100644
index 00000000..d6b30c23
--- /dev/null
+++ b/assets/styles/configuration/elements/_channel-tabs.scss
@@ -0,0 +1,14 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+@use "../../variables";
+
+livechat-channel-tabs {
+ display: block;
+
+ /* See Peertube sub-menu-h1 mixin */
+ margin-bottom: variables.$sub-menu-margin-bottom;
+}
diff --git a/assets/styles/configuration/elements/_index.scss b/assets/styles/configuration/elements/_index.scss
new file mode 100644
index 00000000..479df38f
--- /dev/null
+++ b/assets/styles/configuration/elements/_index.scss
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+@use "channel-tabs";
+@use "section-header";
diff --git a/assets/styles/configuration/elements/_section-header.scss b/assets/styles/configuration/elements/_section-header.scss
new file mode 100644
index 00000000..50244871
--- /dev/null
+++ b/assets/styles/configuration/elements/_section-header.scss
@@ -0,0 +1,11 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+/* stylelint-disable custom-property-pattern */
+
+livechat-configuration-section-header {
+ margin-top: 3rem;
+}
diff --git a/assets/styles/elements/_dynamic-table-form.scss b/assets/styles/elements/_dynamic-table-form.scss
new file mode 100644
index 00000000..4ac017e4
--- /dev/null
+++ b/assets/styles/elements/_dynamic-table-form.scss
@@ -0,0 +1,130 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Mehdi Benadel
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+/* We are disabling stylelint-disable custom-property-pattern so we can use Peertube var without warnings. */
+/* stylelint-disable custom-property-pattern */
+
+@use "sass:color";
+@use "../variables";
+
+livechat-dynamic-table-form {
+ // We need this variable to be known at that time
+ $bs-green: #39cc0b;
+
+ display: block;
+ margin-bottom: 3rem;
+
+ table {
+ table-layout: fixed;
+ text-align: center;
+
+ tr {
+ border: 1px var(--greyBackgroundColor) solid;
+ }
+
+ td,
+ th {
+ word-wrap: break-word;
+ vertical-align: top;
+ padding: 5px 7px;
+ }
+
+ td:last-child {
+ vertical-align: middle;
+ min-width: 28px;
+
+ > input:not([type="checkbox"]),
+ textarea {
+ min-width: 150px;
+ }
+ }
+
+ tbody tr:nth-child(odd) {
+ background-color: var(--greySecondaryBackgroundColor);
+ }
+
+ .livechat-dynamic-table-form-description-header {
+ font-size: small;
+ font-weight: lighter;
+ }
+ }
+
+ .dynamic-table-add-row-cell {
+ text-align: left;
+ }
+
+ .dynamic-table-add-row,
+ .dynamic-table-remove-row {
+ // Peertube rounded-line-height-1-5 mixins
+ line-height: variables.$button-calc-line-height;
+
+ // Peertube peertube-button mixin (but with less horizontal padding)
+ padding: 4px;
+ border: 0;
+ font-weight: variables.$font-semibold;
+ border-radius: 3px !important;
+ text-align: center;
+ cursor: pointer;
+ font-size: variables.$button-font-size;
+ }
+
+ .dynamic-table-add-row {
+ background-color: var(--bs-green);
+
+ &,
+ &:active,
+ &:focus {
+ color: #fff;
+ background-color: color.adjust($bs-green, $lightness: 5%);
+ }
+
+ &:focus,
+ &.focus-visible {
+ box-shadow: 0 0 0 0.2rem color.adjust($bs-green, $lightness: 20%);
+ }
+
+ &:hover {
+ color: #fff;
+ background-color: color.adjust($bs-green, $lightness: 10%);
+ }
+
+ &[disabled],
+ &.disabled {
+ cursor: default;
+ color: #fff;
+ background-color: var(--inputBorderColor);
+ }
+ }
+
+ .dynamic-table-remove-row {
+ background-color: var(--bs-orange);
+
+ &,
+ &:active,
+ &:focus {
+ color: #fff;
+ background-color: var(--mainColor);
+ }
+
+ &:focus,
+ &.focus-visible {
+ box-shadow: 0 0 0 0.2rem var(--mainHoverColor);
+ }
+
+ &:hover {
+ color: #fff;
+ background-color: var(--mainHoverColor);
+ }
+
+ &[disabled],
+ &.disabled {
+ cursor: default;
+ color: #fff;
+ background-color: var(--inputBorderColor);
+ }
+ }
+}
diff --git a/assets/styles/elements/_error.scss b/assets/styles/elements/_error.scss
new file mode 100644
index 00000000..00e87587
--- /dev/null
+++ b/assets/styles/elements/_error.scss
@@ -0,0 +1,14 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+@use "../variables";
+
+livechat-error {
+ color: variables.$error-color;
+ display: block;
+ padding: 50px;
+ text-align: center;
+}
diff --git a/assets/styles/elements/_help-button.scss b/assets/styles/elements/_help-button.scss
new file mode 100644
index 00000000..e1221b53
--- /dev/null
+++ b/assets/styles/elements/_help-button.scss
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+livechat-help-button {
+ a {
+ height: 18px !important;
+ margin: 2px !important;
+ padding: 1px !important;
+ vertical-align: middle;
+ }
+
+ svg {
+ display: block;
+ height: auto;
+ }
+}
diff --git a/assets/styles/elements/_image-file-input.scss b/assets/styles/elements/_image-file-input.scss
new file mode 100644
index 00000000..918d4839
--- /dev/null
+++ b/assets/styles/elements/_image-file-input.scss
@@ -0,0 +1,18 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Mehdi Benadel
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+/* stylelint-disable custom-property-pattern */
+
+livechat-image-file-input {
+ img {
+ cursor: pointer;
+
+ // width and height are values coming from ConverseJS custom emojis.
+ // If we want to upload something else, we should add options on the field to customize.
+ max-height: 3em !important; // and no max-width
+ }
+}
diff --git a/assets/styles/elements/_index.scss b/assets/styles/elements/_index.scss
new file mode 100644
index 00000000..18b200a6
--- /dev/null
+++ b/assets/styles/elements/_index.scss
@@ -0,0 +1,13 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+@use "dynamic-table-form";
+@use "error";
+@use "help-button";
+@use "image-file-input";
+@use "share-chat";
+@use "spinner";
+@use "tags-input";
diff --git a/assets/styles/style/elements/share-chat.scss b/assets/styles/elements/_share-chat.scss
similarity index 100%
rename from assets/styles/style/elements/share-chat.scss
rename to assets/styles/elements/_share-chat.scss
diff --git a/assets/styles/elements/_spinner.scss b/assets/styles/elements/_spinner.scss
new file mode 100644
index 00000000..672bf01c
--- /dev/null
+++ b/assets/styles/elements/_spinner.scss
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+livechat-spinner,
+.livechat-spinner {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+
+ div {
+ width: 48px;
+ height: 48px;
+ margin: 20px;
+ /* stylelint-disable-next-line custom-property-pattern */
+ border: 5px solid var(--greyBackgroundColor);
+ /* stylelint-disable-next-line custom-property-pattern */
+ border-bottom-color: var(--mainColor);
+ border-radius: 50%;
+ display: inline-block;
+ box-sizing: border-box;
+ animation: livechatrotating 1s linear infinite;
+
+ @keyframes livechatrotating {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+ }
+ }
+}
diff --git a/assets/styles/elements/_tags-input.scss b/assets/styles/elements/_tags-input.scss
new file mode 100644
index 00000000..e667ff06
--- /dev/null
+++ b/assets/styles/elements/_tags-input.scss
@@ -0,0 +1,160 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Mehdi Benadel
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+/* stylelint-disable custom-property-pattern */
+
+livechat-tags-input {
+ --tag-padding-vertical: 3px;
+ --tag-padding-horizontal: 6px;
+
+ display: flex;
+ align-items: flex-start;
+ flex-wrap: wrap;
+ max-width: 320px;
+
+ .livechat-tags-container {
+ align-items: center;
+ display: flex;
+ flex-flow: row;
+ justify-content: space-between;
+ }
+
+ // stylelint trying to rearrange unrelated root blocks because of smaller blocks in them
+ /* stylelint-disable-next-line no-descending-specificity */
+ input {
+ flex: 1;
+ border: none;
+ padding: 0;
+ color: inherit;
+ background-color: inherit;
+ width: 100%;
+
+ /* stylelint-disable-next-line no-descending-specificity */
+ &:focus {
+ outline: transparent;
+ }
+ }
+
+ .livechat-tags,
+ .livechat-tags-searched {
+ display: flex;
+ flex-wrap: wrap;
+ padding: 0;
+ margin: var(--tag-padding-vertical) 0;
+ max-height: 150px;
+ overflow-y: auto;
+ transition-property: height, margin;
+ transition-duration: 0.3s;
+
+ @supports (scrollbar-width: auto) {
+ scrollbar-color: var(--greyForegroundColor) transparent;
+ scrollbar-width: thin;
+ }
+ }
+
+ .livechat-tags-container,
+ .livechat-tags-searched {
+ border-bottom: 1px dashed var(--greyForegroundColor);
+
+ &.livechat-empty {
+ height: 0;
+ margin: 0;
+ border: none;
+ }
+ }
+
+ .livechat-tags-searched {
+ &::after {
+ content: "\1F50D";
+ flex-grow: 1;
+ text-align: right;
+ }
+
+ &.livechat-empty {
+ &::after {
+ display: none;
+ }
+ }
+ }
+
+ .livechat-tag,
+ .livechat-tag-searched {
+ width: auto;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #fff;
+ padding: 0 var(--tag-padding-horizontal);
+ font-size: 14px;
+ list-style: none;
+ border-radius: 3px;
+ margin: 0 3px 3px 0;
+ transition: 0.3s filter;
+
+ .livechat-tag-close {
+ display: block;
+ width: 12px;
+ height: 12px;
+ line-height: 12px;
+ text-align: center;
+ font-size: 10px;
+ margin-left: var(--tag-padding-horizontal);
+ color: var(--mainColor);
+ border-radius: 50%;
+ background: #fff;
+ cursor: pointer;
+
+ &::before {
+ content: "\2715";
+ }
+ }
+
+ &,
+ &:active,
+ &:focus {
+ color: #fff;
+ background-color: var(--mainColor);
+
+ .livechat-tag-close {
+ color: var(--mainColor);
+ }
+ }
+
+ &:hover {
+ color: #fff;
+ background-color: var(--mainHoverColor);
+
+ .livechat-tag-close {
+ color: var(--mainHoverColor);
+ }
+ }
+
+ &[disabled],
+ &.disabled {
+ cursor: default;
+ color: #fff;
+ background-color: var(--inputBorderColor);
+
+ .livechat-tag-close {
+ color: var(--inputBorderColor);
+ }
+ }
+
+ .livechat-tag-name {
+ margin-top: 3px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ max-width: 250px;
+ }
+ }
+
+ .livechat-tags.livechat-unfocused .livechat-tag {
+ filter: opacity(50%) grayscale(80%);
+ }
+}
diff --git a/assets/styles/list-rooms/_list-rooms.scss b/assets/styles/list-rooms/_list-rooms.scss
new file mode 100644
index 00000000..0c601f53
--- /dev/null
+++ b/assets/styles/list-rooms/_list-rooms.scss
@@ -0,0 +1,33 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+table.peertube-plugin-livechat-prosody-list-rooms {
+ border: 1px solid black;
+ margin: 5px 0;
+}
+
+table.peertube-plugin-livechat-prosody-list-rooms tr:nth-child(odd) {
+ background-color: #eee;
+}
+
+table.peertube-plugin-livechat-prosody-list-rooms tr:nth-child(even) {
+ background-color: #fff;
+}
+
+table.peertube-plugin-livechat-prosody-list-rooms th {
+ /* stylelint-disable-next-line custom-property-pattern */
+ background-color: var(--mainHoverColor);
+ border: 1px solid black;
+ /* stylelint-disable-next-line custom-property-pattern */
+ color: var(--mainBackgroundColor);
+ padding: 4px 5px;
+}
+
+table.peertube-plugin-livechat-prosody-list-rooms td {
+ border: 1px solid #555;
+ color: black;
+ padding: 4px 5px;
+}
diff --git a/assets/styles/style.scss b/assets/styles/style.scss
index 088f6c9f..0fd2c1bb 100644
--- a/assets/styles/style.scss
+++ b/assets/styles/style.scss
@@ -4,195 +4,9 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-@use "style/elements/share-chat.scss";
-
-#peertube-plugin-livechat-container {
- display: flex;
- flex-direction: column;
- height: 100%;
-
- // Bigger occupants sidebar when embedded near a video.
- .chatroom .box-flyout .chatroom-body .occupants {
- min-width: min(200px, 50%);
- }
-}
-
-.peertube-plugin-livechat-buttons,
-.livechat-mini-muc-bar-buttons {
- align-items: center;
- display: flex;
- flex-flow: row nowrap;
- justify-content: flex-end;
- padding-right: 12px !important; // to avoid being under the window scrollbar.
-}
-
-.peertube-plugin-livechat-button {
- align-items: center;
- display: flex;
- flex-direction: row;
- height: 36px !important;
- margin: 5px !important;
- padding: 2px !important;
-
- svg {
- height: auto; // override .peertube-button-link
- }
-}
-
-.peertube-plugin-livechat-buttons-open,
-.livechat-mini-muc-bar-buttons {
- .peertube-plugin-livechat-button {
- height: 18px !important;
- margin: 2px !important;
- padding: 1px !important;
- }
-}
-
-.peertube-plugin-livechat-buttons-cloned {
- // Hiding buttons when cloned by the ConverseJS mini-muc-head plugin.
- display: none;
-}
-
-[peertube-plugin-livechat-state="initializing"] {
- display: none;
-}
-
-[peertube-plugin-livechat-state="open"] .peertube-plugin-livechat-button-open {
- display: none;
-}
-
-[peertube-plugin-livechat-state="closed"] {
- .peertube-plugin-livechat-button-promote,
- .peertube-plugin-livechat-button-close {
- display: none;
- }
-}
-
-[peertube-plugin-livechat-state]:not([peertube-plugin-livechat-state="open"]) {
- .peertube-plugin-livechat-multi-button-main {
- border-top-right-radius: 0 !important;
- border-bottom-right-radius: 0 !important;
- margin-right: 0 !important;
- }
-
- .peertube-plugin-livechat-multi-button-secondary {
- border-radius: 0 !important;
- margin-right: 0 !important;
- margin-left: 0 !important;
- border-left: 1px solid currentcolor;
- }
-
- .peertube-plugin-livechat-multi-button-last-secondary {
- border-top-left-radius: 0 !important;
- border-bottom-left-radius: 0 !important;
- margin-left: 0 !important;
- border-left: 1px solid currentcolor;
- }
-}
-
-/* Note: livechat-viewer-mode-content (the form where anonymous users can
- choose nickname or log in with external account), can be something like
- ~180px height (at time of writing).
- We must ensure that the 200px limit for converse-muc and converse-root is
- always higher than livechat-viewer-mode-content max size.
-*/
-#peertube-plugin-livechat-container converse-root {
- display: block;
- border: 1px solid black;
- min-height: max(30vh, 200px); // Always at least 200px, and ideally at least 30% of viewport.
- height: 100%;
-
- converse-muc {
- min-height: max(30vh, 200px);
- }
-}
-
-.peertube-plugin-livechat-experimental,
-.peertube-plugin-livechat-warning {
- color: orange;
-}
-
-livechat-error,
-.peertube-plugin-livechat-error {
- color: red;
-}
-
-table.peertube-plugin-livechat-prosody-list-rooms {
- border: 1px solid black;
- margin: 5px 0;
-}
-
-table.peertube-plugin-livechat-prosody-list-rooms tr:nth-child(odd) {
- background-color: #eee;
-}
-
-table.peertube-plugin-livechat-prosody-list-rooms tr:nth-child(even) {
- background-color: #fff;
-}
-
-table.peertube-plugin-livechat-prosody-list-rooms th {
- /* stylelint-disable-next-line custom-property-pattern */
- background-color: var(--mainHoverColor);
- border: 1px solid black;
- /* stylelint-disable-next-line custom-property-pattern */
- color: var(--mainBackgroundColor);
- padding: 4px 5px;
-}
-
-table.peertube-plugin-livechat-prosody-list-rooms td {
- border: 1px solid #555;
- color: black;
- padding: 4px 5px;
-}
-
-livechat-spinner,
-.livechat-spinner {
- display: flex;
- flex-direction: row;
- justify-content: center;
-
- div {
- width: 48px;
- height: 48px;
- margin: 20px;
- /* stylelint-disable-next-line custom-property-pattern */
- border: 5px solid var(--greyBackgroundColor);
- /* stylelint-disable-next-line custom-property-pattern */
- border-bottom-color: var(--mainColor);
- border-radius: 50%;
- display: inline-block;
- box-sizing: border-box;
- animation: livechatrotating 1s linear infinite;
-
- @keyframes livechatrotating {
- from {
- transform: rotate(0deg);
- }
-
- to {
- transform: rotate(360deg);
- }
- }
- }
-}
-
-.peertube-plugin-livechat-error-message {
- /* display an error block (page not found, ...) */
- display: block;
- font-size: 20px;
- padding-top: 50px;
- text-align: center;
- width: 100%;
-}
-
-.peertube-plugin-livechat-container {
- .peertube-plugin-livechat-error-message {
- max-width: 30vw;
- }
-}
-
-livechat-error {
- display: block;
- padding: 50px;
- text-align: center;
-}
+@use "variables";
+@use "utils";
+@use "elements/index";
+@use "video";
+@use "configuration/configuration";
+@use "list-rooms/list-rooms.scss";
diff --git a/assets/styles/video/_button.scss b/assets/styles/video/_button.scss
new file mode 100644
index 00000000..ae3ef6a3
--- /dev/null
+++ b/assets/styles/video/_button.scss
@@ -0,0 +1,78 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+.peertube-plugin-livechat-buttons,
+.livechat-mini-muc-bar-buttons {
+ align-items: center;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-end;
+ padding-right: 12px !important; // to avoid being under the window scrollbar.
+}
+
+.peertube-plugin-livechat-button {
+ align-items: center;
+ display: flex;
+ flex-direction: row;
+ height: 36px !important;
+ margin: 5px !important;
+ padding: 2px !important;
+
+ svg {
+ height: auto; // override .peertube-button-link
+ }
+}
+
+.peertube-plugin-livechat-buttons-open,
+.livechat-mini-muc-bar-buttons {
+ .peertube-plugin-livechat-button {
+ height: 18px !important;
+ margin: 2px !important;
+ padding: 1px !important;
+ }
+}
+
+.peertube-plugin-livechat-buttons-cloned {
+ // Hiding buttons when cloned by the ConverseJS mini-muc-head plugin.
+ display: none;
+}
+
+[peertube-plugin-livechat-state="initializing"] {
+ display: none;
+}
+
+[peertube-plugin-livechat-state="open"] .peertube-plugin-livechat-button-open {
+ display: none;
+}
+
+[peertube-plugin-livechat-state="closed"] {
+ .peertube-plugin-livechat-button-promote,
+ .peertube-plugin-livechat-button-close {
+ display: none;
+ }
+}
+
+[peertube-plugin-livechat-state]:not([peertube-plugin-livechat-state="open"]) {
+ .peertube-plugin-livechat-multi-button-main {
+ border-top-right-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+ margin-right: 0 !important;
+ }
+
+ .peertube-plugin-livechat-multi-button-secondary {
+ border-radius: 0 !important;
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+ border-left: 1px solid currentcolor;
+ }
+
+ .peertube-plugin-livechat-multi-button-last-secondary {
+ border-top-left-radius: 0 !important;
+ border-bottom-left-radius: 0 !important;
+ margin-left: 0 !important;
+ border-left: 1px solid currentcolor;
+ }
+}
diff --git a/assets/styles/video/_container.scss b/assets/styles/video/_container.scss
new file mode 100644
index 00000000..402af31f
--- /dev/null
+++ b/assets/styles/video/_container.scss
@@ -0,0 +1,33 @@
+/*
+ * SPDX-FileCopyrightText: 2024 John Livingston
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+#peertube-plugin-livechat-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+
+ // Bigger occupants sidebar when embedded near a video.
+ .chatroom .box-flyout .chatroom-body .occupants {
+ min-width: min(200px, 50%);
+ }
+}
+
+/* Note: livechat-viewer-mode-content (the form where anonymous users can
+ choose nickname or log in with external account), can be something like
+ ~180px height (at time of writing).
+ We must ensure that the 200px limit for converse-muc and converse-root is
+ always higher than livechat-viewer-mode-content max size.
+*/
+#peertube-plugin-livechat-container converse-root {
+ display: block;
+ border: 1px solid black;
+ min-height: max(30vh, 200px); // Always at least 200px, and ideally at least 30% of viewport.
+ height: 100%;
+
+ converse-muc {
+ min-height: max(30vh, 200px);
+ }
+}
diff --git a/assets/styles/video/_index.scss b/assets/styles/video/_index.scss
new file mode 100644
index 00000000..35031451
--- /dev/null
+++ b/assets/styles/video/_index.scss
@@ -0,0 +1,2 @@
+@use "./container";
+@use "./button";
diff --git a/package.json b/package.json
index 809f6818..e7cd679c 100644
--- a/package.json
+++ b/package.json
@@ -23,8 +23,7 @@
}
],
"css": [
- "dist/assets/styles/style.css",
- "dist/assets/styles/configuration.css"
+ "dist/assets/styles/style.css"
],
"dependencies": {
"@xmpp/jid": "^0.13.1",