New theming system
This commit is contained in:
parent
c505f6ff9b
commit
cd422832dd
|
@ -108,7 +108,7 @@ flake8:
|
||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: fetch
|
GIT_STRATEGY: fetch
|
||||||
before_script:
|
before_script:
|
||||||
- pip install flake8
|
- pip install 'flake8<3.7'
|
||||||
script:
|
script:
|
||||||
- flake8 -v api
|
- flake8 -v api
|
||||||
cache:
|
cache:
|
||||||
|
|
|
@ -704,6 +704,21 @@ Views: you can find some readable views tests in file: ``api/tests/users/test_vi
|
||||||
Contributing to the front-end
|
Contributing to the front-end
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
Styles and themes
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Our UI framework is Fomantic UI (https://fomantic-ui.com/), and Funkwhale's custom styles are written in SCSS. All the styles are configured in ``front/src/styles/_main.scss``,
|
||||||
|
including imporing of Fomantic UI styles and components.
|
||||||
|
|
||||||
|
We're applying several changes on top of the Fomantic CSS files, before they are imported:
|
||||||
|
|
||||||
|
1. Many hardcoded color values are replaced by CSS vars: e.g ``color: orange`` is replaced by ``color: var(--vibrant-color)``. This makes theming way easier.
|
||||||
|
2. Unused components variations and icons are stripped from the source files, in order to reduce the final size of our CSS files
|
||||||
|
|
||||||
|
This changes are applied automatically when running ``yarn install``, through a ``postinstall`` hook. Internally, ``front/scripts/fix-fomantic-css.py`` is called
|
||||||
|
and handle both kind of modifications. Please refer to this script if you need to use new icons to the project, or restore some components variations that
|
||||||
|
were stripped in order to use them.
|
||||||
|
|
||||||
Running tests
|
Running tests
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/* These styles are generated from project.scss. */
|
|
||||||
|
|
||||||
.alert-debug {
|
|
||||||
color: black;
|
|
||||||
background-color: white;
|
|
||||||
border-color: #d6e9c6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-error {
|
|
||||||
color: #b94a48;
|
|
||||||
background-color: #f2dede;
|
|
||||||
border-color: #eed3d7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a fix for the bootstrap4 alpha release */
|
|
||||||
@media (max-width: 47.9em) {
|
|
||||||
.navbar-nav .nav-item {
|
|
||||||
float: none;
|
|
||||||
width: 100%;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-nav .nav-item + .nav-item {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav.navbar-nav.pull-right {
|
|
||||||
float: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display django-debug-toolbar.
|
|
||||||
See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
|
|
||||||
and https://github.com/pydanny/cookiecutter-django/issues/317
|
|
||||||
*/
|
|
||||||
[hidden][style="display: block;"] {
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 8.2 KiB |
|
@ -1 +0,0 @@
|
||||||
/* Project specific Javascript goes here. */
|
|
|
@ -1,51 +0,0 @@
|
||||||
// project specific CSS goes here
|
|
||||||
|
|
||||||
// Alert colors
|
|
||||||
|
|
||||||
$white: #fff;
|
|
||||||
$mint-green: #d6e9c6;
|
|
||||||
$black: #000;
|
|
||||||
$pink: #f2dede;
|
|
||||||
$dark-pink: #eed3d7;
|
|
||||||
$red: #b94a48;
|
|
||||||
|
|
||||||
// bootstrap alert CSS, translated to the django-standard levels of
|
|
||||||
// debug, info, success, warning, error
|
|
||||||
|
|
||||||
.alert-debug {
|
|
||||||
background-color: $white;
|
|
||||||
border-color: $mint-green;
|
|
||||||
color: $black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-error {
|
|
||||||
background-color: $pink;
|
|
||||||
border-color: $dark-pink;
|
|
||||||
color: $red;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a fix for the bootstrap4 alpha release
|
|
||||||
|
|
||||||
@media (max-width: 47.9em) {
|
|
||||||
.navbar-nav .nav-item {
|
|
||||||
display: inline-block;
|
|
||||||
float: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-nav .nav-item + .nav-item {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav.navbar-nav.pull-right {
|
|
||||||
float: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display django-debug-toolbar.
|
|
||||||
// See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
|
|
||||||
// and https://github.com/pydanny/cookiecutter-django/issues/317
|
|
||||||
|
|
||||||
[hidden][style="display: block;"] {
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
|
@ -10,7 +10,9 @@
|
||||||
"test:unit": "vue-cli-service test:unit",
|
"test:unit": "vue-cli-service test:unit",
|
||||||
"lint": "vue-cli-service lint",
|
"lint": "vue-cli-service lint",
|
||||||
"i18n-compile": "scripts/i18n-compile.sh",
|
"i18n-compile": "scripts/i18n-compile.sh",
|
||||||
"i18n-extract": "scripts/i18n-extract.sh"
|
"i18n-extract": "scripts/i18n-extract.sh",
|
||||||
|
"fix-fomantic-css": "scripts/fix-fomantic-css.sh",
|
||||||
|
"postinstall": "yarn run fix-fomantic-css"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
|
@ -25,6 +27,7 @@
|
||||||
"qs": "^6.7.0",
|
"qs": "^6.7.0",
|
||||||
"register-service-worker": "^1.6.2",
|
"register-service-worker": "^1.6.2",
|
||||||
"sanitize-html": "^1.20.1",
|
"sanitize-html": "^1.20.1",
|
||||||
|
"sass": "^1.26.5",
|
||||||
"showdown": "^1.8.6",
|
"showdown": "^1.8.6",
|
||||||
"text-clipper": "^1.3.0",
|
"text-clipper": "^1.3.0",
|
||||||
"vue": "^2.6.10",
|
"vue": "^2.6.10",
|
||||||
|
@ -54,7 +57,6 @@
|
||||||
"glob-all": "^3.1.0",
|
"glob-all": "^3.1.0",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"moxios": "^0.4.0",
|
"moxios": "^0.4.0",
|
||||||
"node-sass": "^4.9.3",
|
|
||||||
"preload-webpack-plugin": "^3.0.0-beta.4",
|
"preload-webpack-plugin": "^3.0.0-beta.4",
|
||||||
"purgecss-webpack-plugin": "^1.6.0",
|
"purgecss-webpack-plugin": "^1.6.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#orange-square {
|
#orange-square {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
background-color: #f2711c
|
background-color: #f2711c;
|
||||||
}
|
}
|
||||||
#fake-content {
|
#fake-content {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|
|
@ -0,0 +1,897 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
This scripts handles all the heavy-lifting of parsing CSS files from ``fomantic-ui-css`` and:
|
||||||
|
|
||||||
|
1. Replace hardcoded values by their CSS vars counterparts, for easier theming
|
||||||
|
2. Strip unused styles and icons to reduce the final size of CSS
|
||||||
|
|
||||||
|
Updated files are not modified in place, but instead copied to another directory (``fomantic-ui-css/tweaked``), in order
|
||||||
|
to allow easy comparison detection of changes.
|
||||||
|
|
||||||
|
If you change this file, you'll need to run ``yarn run fix-fomantic-css`` manually for the changes
|
||||||
|
to be picked up. If the ``NOSTRIP`` environment variable is set, the second step will be skipped.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
|
||||||
|
STRIP_UNUSED = "NOSTRIP" not in os.environ
|
||||||
|
|
||||||
|
# Perform a blind replacement of some strings in all fomantic CSS files
|
||||||
|
GLOBAL_REPLACES = [
|
||||||
|
# some selectors are repeated in the stylesheet, for some reason
|
||||||
|
(".ui.ui.ui.ui", ".ui"),
|
||||||
|
(".ui.ui.ui", ".ui"),
|
||||||
|
(".ui.ui", ".ui"),
|
||||||
|
(".icon.icon.icon.icon", ".icon"),
|
||||||
|
(".icon.icon.icon", ".icon"),
|
||||||
|
(".icon.icon", ".icon"),
|
||||||
|
# actually useful stuff
|
||||||
|
("'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif", "var(--font-family)"),
|
||||||
|
(".orange", ".vibrant"),
|
||||||
|
("#F2711C", "var(--vibrant-color)"),
|
||||||
|
("#FF851B", "var(--vibrant-color)"),
|
||||||
|
("#f26202", "var(--vibrant-hover-color)"),
|
||||||
|
("#e76b00", "var(--vibrant-hover-color)"),
|
||||||
|
("#cf590c", "var(--vibrant-active-color)"),
|
||||||
|
("#f56100", "var(--vibrant-active-color)"),
|
||||||
|
("#e76b00", "var(--vibrant-active-color)"),
|
||||||
|
("#e55b00", "var(--vibrant-focus-color)"),
|
||||||
|
("#f17000", "var(--vibrant-focus-color)"),
|
||||||
|
(".green", ".success"),
|
||||||
|
("#21BA45", "var(--success-color)"),
|
||||||
|
("#2ECC40", "var(--success-color)"),
|
||||||
|
("#16ab39", "var(--success-hover-color)"),
|
||||||
|
("#1ea92e", "var(--success-hover-color)"),
|
||||||
|
("#198f35", "var(--success-active-color)"),
|
||||||
|
("#25a233", "var(--success-active-color)"),
|
||||||
|
("#0ea432", "var(--success-focus-color)"),
|
||||||
|
("#19b82b", "var(--success-focus-color)"),
|
||||||
|
(".blue", ".primary"),
|
||||||
|
("#2185D0", "var(--primary-color)"),
|
||||||
|
("#54C8FF", "var(--primary-color)"),
|
||||||
|
("#54C8FF", "var(--primary-color)"),
|
||||||
|
("#1678c2", "var(--primary-hover-color)"),
|
||||||
|
("#21b8ff", "var(--primary-hover-color)"),
|
||||||
|
("#1a69a4", "var(--primary-active-color)"),
|
||||||
|
("#0d71bb", "var(--primary-focus-color)"),
|
||||||
|
("#2bbbff", "var(--primary-focus-color)"),
|
||||||
|
(".yellow", ".warning"),
|
||||||
|
("#FBBD08", "var(--warning-color)"),
|
||||||
|
("#FFE21F", "var(--warning-color)"),
|
||||||
|
("#eaae00", "var(--warning-hover-color)"),
|
||||||
|
("#ebcd00", "var(--warning-hover-color)"),
|
||||||
|
("#cd9903", "var(--warning-active-color)"),
|
||||||
|
("#ebcd00", "var(--warning-active-color)"),
|
||||||
|
("#daa300", "var(--warning-focus-color)"),
|
||||||
|
("#f5d500", "var(--warning-focus-color)"),
|
||||||
|
(".red.", ".danger."),
|
||||||
|
("#DB2828", "var(--danger-color)"),
|
||||||
|
("#FF695E", "var(--danger-color)"),
|
||||||
|
("#d01919", "var(--danger-hover-color)"),
|
||||||
|
("#ff392b", "var(--danger-hover-color)"),
|
||||||
|
("#b21e1e", "var(--danger-active-color)"),
|
||||||
|
("#ca1010", "var(--danger-focus-color)"),
|
||||||
|
("#ff4335", "var(--danger-focus-color)"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def discard_unused_icons(rule):
|
||||||
|
"""
|
||||||
|
Add an icon to this list if you want to use it in the app.
|
||||||
|
"""
|
||||||
|
used_icons = [
|
||||||
|
".angle",
|
||||||
|
".arrow",
|
||||||
|
".at",
|
||||||
|
".ban",
|
||||||
|
".bell",
|
||||||
|
".book",
|
||||||
|
".bookmark",
|
||||||
|
".check",
|
||||||
|
".clock",
|
||||||
|
".close",
|
||||||
|
".cloud",
|
||||||
|
".code",
|
||||||
|
".comment",
|
||||||
|
".copy",
|
||||||
|
".copyright",
|
||||||
|
".danger",
|
||||||
|
".database",
|
||||||
|
".delete",
|
||||||
|
".disc",
|
||||||
|
".down angle",
|
||||||
|
".download",
|
||||||
|
".dropdown",
|
||||||
|
".edit",
|
||||||
|
".ellipsis",
|
||||||
|
".eraser",
|
||||||
|
".external",
|
||||||
|
".eye",
|
||||||
|
".feed",
|
||||||
|
".file",
|
||||||
|
".forward",
|
||||||
|
".globe",
|
||||||
|
".hashtag",
|
||||||
|
".headphones",
|
||||||
|
".heart",
|
||||||
|
".home",
|
||||||
|
".hourglass",
|
||||||
|
".info",
|
||||||
|
".layer",
|
||||||
|
".lines",
|
||||||
|
".link",
|
||||||
|
".list",
|
||||||
|
".loading",
|
||||||
|
".lock",
|
||||||
|
".minus",
|
||||||
|
".mobile",
|
||||||
|
".music",
|
||||||
|
".paper",
|
||||||
|
".pause",
|
||||||
|
".pencil",
|
||||||
|
".play",
|
||||||
|
".plus",
|
||||||
|
".podcast",
|
||||||
|
".question",
|
||||||
|
".question ",
|
||||||
|
".random",
|
||||||
|
".redo",
|
||||||
|
".refresh",
|
||||||
|
".repeat",
|
||||||
|
".rss",
|
||||||
|
".search",
|
||||||
|
".server",
|
||||||
|
".share",
|
||||||
|
".shield",
|
||||||
|
".sidebar",
|
||||||
|
".sign",
|
||||||
|
".spinner",
|
||||||
|
".step",
|
||||||
|
".stream",
|
||||||
|
".track",
|
||||||
|
".trash",
|
||||||
|
".undo",
|
||||||
|
".upload",
|
||||||
|
".user",
|
||||||
|
".users",
|
||||||
|
".volume",
|
||||||
|
".wikipedia",
|
||||||
|
".wrench",
|
||||||
|
".x",
|
||||||
|
]
|
||||||
|
if ":before" not in rule["lines"][0]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return not match(rule, used_icons)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Below is the main configuration object that is used for fine-grained replacement of properties
|
||||||
|
in component files. It also handles removal of unused selectors.
|
||||||
|
|
||||||
|
Example config for a component:
|
||||||
|
|
||||||
|
REPLACEMENTS = {
|
||||||
|
# applies to fomantic-ui-css/components/component-name.css
|
||||||
|
"component-name": {
|
||||||
|
# Discard any CSS rule matching one of the selectors listed below
|
||||||
|
# matching is done using a simple string search, so ``.pink`` will remove
|
||||||
|
# rules applied to ``.pink``, ``.pink.button`` and `.pinkdark`
|
||||||
|
"skip": [
|
||||||
|
".unused.variation",
|
||||||
|
".pink",
|
||||||
|
],
|
||||||
|
# replace some CSS properties values in specific selectors
|
||||||
|
(".inverted", ".dark"): [
|
||||||
|
("background", "var(--inverted-background)"),
|
||||||
|
("color", "var(--inverted-color)"),
|
||||||
|
],
|
||||||
|
(".active"): [
|
||||||
|
("font-size", "var(--active-font-size)"),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Given the previous config, the following style sheet:
|
||||||
|
|
||||||
|
.. code-block:: css
|
||||||
|
|
||||||
|
.unsed.variation {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.primary.pink {
|
||||||
|
color: pink;
|
||||||
|
}
|
||||||
|
.inverted.primary {
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
border-top: 1px solid red;
|
||||||
|
}
|
||||||
|
.inverted.primary.active {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
Would be converted to:
|
||||||
|
|
||||||
|
.. code-block:: css
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.inverted.primary {
|
||||||
|
background: var(--inverted-background);
|
||||||
|
color: var(--inverted-color);
|
||||||
|
border-top: 1px solid red;
|
||||||
|
}
|
||||||
|
.inverted.primary.active {
|
||||||
|
font-size: var(--active-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
REPLACEMENTS = {
|
||||||
|
"site": {
|
||||||
|
("a",): [
|
||||||
|
("color", "var(--link-color)"),
|
||||||
|
("text-decoration", "var(--link-text-decoration)"),
|
||||||
|
],
|
||||||
|
("a:hover",): [
|
||||||
|
("color", "var(--link-hover-color)"),
|
||||||
|
("text-decoration", "var(--link-hover-text-decoration)"),
|
||||||
|
],
|
||||||
|
("body",): [
|
||||||
|
("background", "var(--site-background)"),
|
||||||
|
("color", "var(--text-color)"),
|
||||||
|
],
|
||||||
|
("::-webkit-selection", "::-moz-selection", "::selection",): [
|
||||||
|
("color", "var(--text-selection-color)"),
|
||||||
|
("background-color", "var(--text-selection-background)"),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
"textarea::-webkit-selection",
|
||||||
|
"input::-webkit-selection",
|
||||||
|
"textarea::-moz-selection",
|
||||||
|
"input::-moz-selection",
|
||||||
|
"textarea::selection",
|
||||||
|
"input::selection",
|
||||||
|
): [
|
||||||
|
("color", "var(--input-selection-color)"),
|
||||||
|
("background-color", "var(--input-selection-background)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"skip": [
|
||||||
|
".vertical",
|
||||||
|
".animated",
|
||||||
|
".active",
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".positive",
|
||||||
|
".negative",
|
||||||
|
".secondary",
|
||||||
|
".tertiary",
|
||||||
|
".facebook",
|
||||||
|
".twitter",
|
||||||
|
".google.plus",
|
||||||
|
".vk",
|
||||||
|
".linkedin",
|
||||||
|
".instagram",
|
||||||
|
".youtube",
|
||||||
|
".whatsapp",
|
||||||
|
".telegram",
|
||||||
|
],
|
||||||
|
(".ui.orange.button", ".ui.orange.button:hover"): [
|
||||||
|
("background-color", "var(--button-orange-background)")
|
||||||
|
],
|
||||||
|
(".ui.basic.button",): [
|
||||||
|
("background", "var(--button-basic-background)"),
|
||||||
|
("color", "var(--button-basic-color)"),
|
||||||
|
("box-shadow", "var(--button-basic-box-shadow)"),
|
||||||
|
],
|
||||||
|
(".ui.basic.button:hover",): [
|
||||||
|
("background", "var(--button-basic-hover-background)"),
|
||||||
|
("color", "var(--button-basic-hover-color)"),
|
||||||
|
("box-shadow", "var(--button-basic-hover-box-shadow)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"card": {
|
||||||
|
"skip": [
|
||||||
|
".inverted",
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".pink",
|
||||||
|
".black",
|
||||||
|
".vibrant",
|
||||||
|
".success",
|
||||||
|
".warning",
|
||||||
|
".danger",
|
||||||
|
".primary",
|
||||||
|
".secondary",
|
||||||
|
".horizontal",
|
||||||
|
".raised",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"checkbox": {
|
||||||
|
(
|
||||||
|
".ui.toggle.checkbox label",
|
||||||
|
".ui.toggle.checkbox input:checked ~ label",
|
||||||
|
'.ui.checkbox input[type="checkbox"]',
|
||||||
|
".ui.checkbox input:focus ~ label",
|
||||||
|
".ui.toggle.checkbox input:focus:checked ~ label",
|
||||||
|
".ui.checkbox input:active ~ label",
|
||||||
|
): [("color", "var(--form-label-color)"),],
|
||||||
|
(".ui.toggle.checkbox label:before",): [
|
||||||
|
("background", "var(--input-background)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"divider": {
|
||||||
|
(".ui.divider:not(.vertical):not(.horizontal)",): [
|
||||||
|
("border-top", "var(--divider)"),
|
||||||
|
("border-bottom", "var(--divider)"),
|
||||||
|
],
|
||||||
|
(".ui.divider",): [("color", "var(--text-color)"),],
|
||||||
|
},
|
||||||
|
"dimmer": {
|
||||||
|
(".ui.inverted.dimmer",): [
|
||||||
|
("background-color", "var(--dimmer-background)"),
|
||||||
|
("color", "var(--dropdown-color)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"dropdown": {
|
||||||
|
"skip": [".error", ".info", ".success", ".warning",],
|
||||||
|
(
|
||||||
|
".ui.selection.dropdown",
|
||||||
|
".ui.selection.visible.dropdown > .text:not(.default)",
|
||||||
|
".ui.dropdown .menu",
|
||||||
|
): [
|
||||||
|
("background", "var(--dropdown-background)"),
|
||||||
|
("color", "var(--dropdown-color)"),
|
||||||
|
],
|
||||||
|
(".ui.dropdown .menu > .item",): [("color", "var(--dropdown-item-color)"),],
|
||||||
|
(".ui.dropdown .menu > .item:hover",): [
|
||||||
|
("color", "var(--dropdown-item-hover-color)"),
|
||||||
|
("background", "var(--dropdown-item-hover-background)"),
|
||||||
|
],
|
||||||
|
(".ui.dropdown .menu .selected.item",): [
|
||||||
|
("color", "var(--dropdown-item-selected-color)"),
|
||||||
|
("background", "var(--dropdown-item-selected-background)"),
|
||||||
|
],
|
||||||
|
(".ui.dropdown .menu > .header:not(.ui)",): [
|
||||||
|
("color", "var(--dropdown-header-color)"),
|
||||||
|
],
|
||||||
|
(".ui.dropdown .menu > .divider",): [("border-top", "var(--divider)"),],
|
||||||
|
},
|
||||||
|
"form": {
|
||||||
|
"skip": [".inverted", ".success", ".warning", ".error", ".info",],
|
||||||
|
('.ui.form input[type="text"]', ".ui.form select", ".ui.input textarea"): [
|
||||||
|
("background", "var(--input-background)"),
|
||||||
|
("color", "var(--input-color)"),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
'.ui.form input[type="text"]:focus',
|
||||||
|
".ui.form select:focus",
|
||||||
|
".ui.form textarea:focus",
|
||||||
|
): [
|
||||||
|
("background", "var(--input-focus-background)"),
|
||||||
|
("color", "var(--input-focus-color)"),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
".ui.form ::-webkit-input-placeholder",
|
||||||
|
".ui.form :-ms-input-placeholder",
|
||||||
|
".ui.form ::-moz-placeholder",
|
||||||
|
): [("color", "var(--input-placeholder-color)"),],
|
||||||
|
(
|
||||||
|
".ui.form :focus::-webkit-input-placeholder",
|
||||||
|
".ui.form :focus:-ms-input-placeholder",
|
||||||
|
".ui.form :focus::-moz-placeholder",
|
||||||
|
): [("color", "var(--input-focus-placeholder-color)"),],
|
||||||
|
(".ui.form .field > label", ".ui.form .inline.fields .field > label",): [
|
||||||
|
("color", "var(--form-label-color)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"skip": [
|
||||||
|
"wide tablet",
|
||||||
|
"screen",
|
||||||
|
"mobile only",
|
||||||
|
"tablet only",
|
||||||
|
"computer only",
|
||||||
|
"computer reversed",
|
||||||
|
"tablet reversed",
|
||||||
|
"wide computer",
|
||||||
|
"wide mobile",
|
||||||
|
"wide tablet",
|
||||||
|
"vertically",
|
||||||
|
".celled",
|
||||||
|
".doubling",
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".positive",
|
||||||
|
".negative",
|
||||||
|
".secondary",
|
||||||
|
".tertiary",
|
||||||
|
".danger",
|
||||||
|
".vibrant",
|
||||||
|
".warning",
|
||||||
|
".primary",
|
||||||
|
".success",
|
||||||
|
".justified",
|
||||||
|
".centered",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"icon": {"skip": discard_unused_icons},
|
||||||
|
"input": {
|
||||||
|
(".ui.input > input",): [
|
||||||
|
("background", "var(--input-background)"),
|
||||||
|
("color", "var(--input-color)"),
|
||||||
|
],
|
||||||
|
(".ui.input > input:focus",): [
|
||||||
|
("background", "var(--input-focus-background)"),
|
||||||
|
("color", "var(--input-focus-color)"),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
".ui.input > input::-webkit-input-placeholder",
|
||||||
|
".ui.input > input::-moz-placeholder",
|
||||||
|
".ui.input > input:-ms-input-placeholder",
|
||||||
|
): [("color", "var(--input-placeholder-color)"),],
|
||||||
|
(
|
||||||
|
".ui.input > input:focus::-webkit-input-placeholder",
|
||||||
|
".ui.input > input:focus::-moz-placeholder",
|
||||||
|
".ui.input > input:focus:-ms-input-placeholder",
|
||||||
|
): [("color", "var(--input-focus-placeholder-color)"),],
|
||||||
|
},
|
||||||
|
"item": {
|
||||||
|
(".ui.divided.items > .item",): [("border-top", "var(--divider)"),],
|
||||||
|
(".ui.items > .item > .content",): [("color", "var(--text-color)"),],
|
||||||
|
(".ui.items > .item .extra",): [
|
||||||
|
("color", "var(--really-discrete-text-color)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"skip": [
|
||||||
|
".inverted",
|
||||||
|
".block",
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".pink",
|
||||||
|
],
|
||||||
|
(".ui.header",): [("color", "var(--header-color)"),],
|
||||||
|
(".ui.header .sub.header",): [("color", "var(--header-color)"),],
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"skip": [
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".positive",
|
||||||
|
".negative",
|
||||||
|
".secondary",
|
||||||
|
".tertiary",
|
||||||
|
".facebook",
|
||||||
|
".twitter",
|
||||||
|
".google.plus",
|
||||||
|
".vk",
|
||||||
|
".linkedin",
|
||||||
|
".instagram",
|
||||||
|
".youtube",
|
||||||
|
".whatsapp",
|
||||||
|
".telegram",
|
||||||
|
".corner",
|
||||||
|
"ribbon",
|
||||||
|
"pointing",
|
||||||
|
"attached",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"skip": [
|
||||||
|
".mini",
|
||||||
|
".tiny",
|
||||||
|
".small",
|
||||||
|
".large",
|
||||||
|
".big",
|
||||||
|
".huge",
|
||||||
|
".massive",
|
||||||
|
".celled",
|
||||||
|
".horizontal",
|
||||||
|
".bulleted",
|
||||||
|
".ordered",
|
||||||
|
".suffixed",
|
||||||
|
".inverted",
|
||||||
|
".fitted",
|
||||||
|
"aligned",
|
||||||
|
],
|
||||||
|
(".ui.list .list > .item a.header", ".ui.list .list > a.item"): [
|
||||||
|
("color", "var(--link-color)"),
|
||||||
|
("text-decoration", "var(--link-text-decoration)"),
|
||||||
|
],
|
||||||
|
("a:hover", ".ui.list .list > a.item:hover"): [
|
||||||
|
("color", "var(--link-hover-color)"),
|
||||||
|
("text-decoration", "var(--link-hover-text-decoration)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"loader": {
|
||||||
|
"skip": [
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".pink",
|
||||||
|
".primary",
|
||||||
|
".vibrant",
|
||||||
|
".warning",
|
||||||
|
".success",
|
||||||
|
".danger",
|
||||||
|
".elastic",
|
||||||
|
],
|
||||||
|
(".ui.inverted.dimmer > .ui.loader",): [("color", "var(--dimmer-color)"),],
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"skip": [
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".pink",
|
||||||
|
".vibrant",
|
||||||
|
".primary",
|
||||||
|
".secondary",
|
||||||
|
".floating",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"skip": [
|
||||||
|
".inverted.pointing",
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".vertical.tabular",
|
||||||
|
".primary.menu",
|
||||||
|
".pink.menu",
|
||||||
|
".vibrant.menu",
|
||||||
|
".warning.menu",
|
||||||
|
".success.menu",
|
||||||
|
".danger.menu",
|
||||||
|
".fitted",
|
||||||
|
"fixed",
|
||||||
|
],
|
||||||
|
(".ui.menu .item",): [("color", "var(--menu-item-color)"),],
|
||||||
|
(".ui.vertical.inverted.menu .menu .item", ".ui.inverted.menu .item"): [
|
||||||
|
("color", "var(--inverted-menu-item-color)"),
|
||||||
|
],
|
||||||
|
(".inverted-ui.menu .active.item",): [
|
||||||
|
("color", "var(--menu-inverted-active-item-color)"),
|
||||||
|
],
|
||||||
|
(".ui.secondary.pointing.menu .active.item",): [
|
||||||
|
("color", "var(--secondary-menu-active-item-color)"),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
".ui.secondary.pointing.menu a.item:hover",
|
||||||
|
".ui.secondary.pointing.menu .active.item:hover",
|
||||||
|
): [("color", "var(--secondary-menu-hover-item-color)"),],
|
||||||
|
(".ui.menu .ui.dropdown .menu > .item",): [
|
||||||
|
("color", "var(--dropdown-item-color) !important"),
|
||||||
|
],
|
||||||
|
(".ui.menu .ui.dropdown .menu > .item:hover",): [
|
||||||
|
("color", "var(--dropdown-item-hover-color) !important"),
|
||||||
|
("background", "var(--dropdown-item-hover-background) !important"),
|
||||||
|
],
|
||||||
|
(".ui.menu .dropdown.item .menu",): [
|
||||||
|
("color", "var(--dropdown--color)"),
|
||||||
|
("background", "var(--dropdown-background)"),
|
||||||
|
],
|
||||||
|
(".ui.menu .ui.dropdown .menu > .active.item",): [
|
||||||
|
("color", "var(--dropdown-item-selected-color)"),
|
||||||
|
("background", "var(--dropdown-item-selected-background) !important"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"modal": {
|
||||||
|
(".ui.modal", ".ui.modal > .actions", ".ui.modal > .content"): [
|
||||||
|
("background", "var(--modal-background)"),
|
||||||
|
("border-bottom", "var(--divider)"),
|
||||||
|
("border-top", "var(--divider)"),
|
||||||
|
],
|
||||||
|
(".ui.modal > .close.inside",): [("color", "var(--text-color)"),],
|
||||||
|
(".ui.modal > .header",): [
|
||||||
|
("color", "var(--header-color)"),
|
||||||
|
("background", "var(--modal-background)"),
|
||||||
|
("border-bottom", "var(--divider)"),
|
||||||
|
("border-top", "var(--divider)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
(
|
||||||
|
".ui.search > .results",
|
||||||
|
".ui.search > .results .result",
|
||||||
|
".ui.category.search > .results .category .results",
|
||||||
|
".ui.category.search > .results .category",
|
||||||
|
".ui.category.search > .results .category > .name",
|
||||||
|
".ui.search > .results > .message .header",
|
||||||
|
".ui.search > .results > .message .description",
|
||||||
|
): [
|
||||||
|
("background", "var(--dropdown-background)"),
|
||||||
|
("color", "var(--dropdown-item-color)"),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
".ui.search > .results .result .title",
|
||||||
|
".ui.search > .results .result .description",
|
||||||
|
): [("color", "var(--dropdown-item-color)"),],
|
||||||
|
(".ui.search > .results .result:hover",): [
|
||||||
|
("color", "var(--dropdown-item-hover-color)"),
|
||||||
|
("background", "var(--dropdown-item-hover-background)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"segment": {
|
||||||
|
"skip": [
|
||||||
|
".stacked",
|
||||||
|
".horizontal.segment",
|
||||||
|
".inverted.segment",
|
||||||
|
".circular",
|
||||||
|
".piled",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
(".ui.left.visible.sidebar",): [("box-shadow", "var(--sidebar-box-shadow)"),]
|
||||||
|
},
|
||||||
|
"statistic": {
|
||||||
|
(".ui.statistic > .value", ".ui.statistic > .label"): [
|
||||||
|
("color", "var(--text-color)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
(".ui.progress.success > .label",): [("color", "var(--text-color)"),],
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"skip": [
|
||||||
|
".marked",
|
||||||
|
".active",
|
||||||
|
".olive",
|
||||||
|
".brown",
|
||||||
|
".teal",
|
||||||
|
".violet",
|
||||||
|
".purple",
|
||||||
|
".brown",
|
||||||
|
".grey",
|
||||||
|
".black",
|
||||||
|
".padded",
|
||||||
|
".column.table",
|
||||||
|
".inverted",
|
||||||
|
".definition",
|
||||||
|
".error",
|
||||||
|
".negative",
|
||||||
|
".structured",
|
||||||
|
"tablet stackable",
|
||||||
|
],
|
||||||
|
(".ui.table", ".ui.table > thead > tr > th",): [
|
||||||
|
("color", "var(--text-color)"),
|
||||||
|
("background", "var(--table-background)"),
|
||||||
|
],
|
||||||
|
(".ui.table > tr > td", ".ui.table > tbody + tbody tr:first-child > td"): [
|
||||||
|
("border-top", "var(--table-border)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def match(rule, skip):
|
||||||
|
if hasattr(skip, "__call__"):
|
||||||
|
return skip(rule)
|
||||||
|
for s in skip:
|
||||||
|
for rs in rule["selectors"]:
|
||||||
|
if s in rs:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def rules_from_media_query(rule):
|
||||||
|
internal = rule["lines"][1:-1]
|
||||||
|
return parse_rules("\n".join(internal))
|
||||||
|
|
||||||
|
|
||||||
|
def wraps(rule, internal_rules):
|
||||||
|
return {
|
||||||
|
"lines": [rule["lines"][0]]
|
||||||
|
+ [line for r in internal_rules for line in r["lines"]]
|
||||||
|
+ ["}"]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_vars(component_name, rules):
|
||||||
|
"""
|
||||||
|
Given rules parsed via ``parse_rules``, replace properties values when needed
|
||||||
|
using ``REPLACEMENTS`` and ``GLOBAL_REPLACES``.
|
||||||
|
|
||||||
|
Also remove unused styles if STRIP_UNUSED is set to True.
|
||||||
|
"""
|
||||||
|
final_rules = []
|
||||||
|
try:
|
||||||
|
conf = REPLACEMENTS[component_name]
|
||||||
|
except KeyError:
|
||||||
|
return rules
|
||||||
|
selectors = list(conf.keys()) + list()
|
||||||
|
skip = None
|
||||||
|
if STRIP_UNUSED:
|
||||||
|
skip = conf.get("skip", [])
|
||||||
|
try:
|
||||||
|
skip = set(skip)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for rule in rules:
|
||||||
|
if rule["lines"][0].startswith("@media"):
|
||||||
|
# manual handling of media queries, becaues our parser is really
|
||||||
|
# simplistic
|
||||||
|
internal_rules = rules_from_media_query(rule)
|
||||||
|
internal_rules = set_vars(component_name, internal_rules)
|
||||||
|
rule = wraps(rule, internal_rules)
|
||||||
|
if len(rule["lines"]) > 2:
|
||||||
|
final_rules.append(rule)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if skip and match(rule, skip):
|
||||||
|
# discard rule entirely
|
||||||
|
continue
|
||||||
|
|
||||||
|
matching = []
|
||||||
|
for s in selectors:
|
||||||
|
if set(s) & set(rule["selectors"]):
|
||||||
|
matching.append(s)
|
||||||
|
if not matching:
|
||||||
|
# no replacements to apply, keep rule as is
|
||||||
|
final_rules.append(rule)
|
||||||
|
continue
|
||||||
|
new_rule = {"lines": []}
|
||||||
|
|
||||||
|
for m in matching:
|
||||||
|
# the block match one of our replacement rules, so we loop on each line
|
||||||
|
# and replace values if needed.
|
||||||
|
replacements = conf[m]
|
||||||
|
for line in rule["lines"]:
|
||||||
|
for property, new_value in replacements:
|
||||||
|
if line.strip().startswith("{}:".format(property)):
|
||||||
|
new_property = "{}: {};".format(property, new_value)
|
||||||
|
indentation = " " * (len(line) - len(line.lstrip(" ")))
|
||||||
|
line = indentation + new_property
|
||||||
|
break
|
||||||
|
new_rule["lines"].append(line)
|
||||||
|
final_rules.append(new_rule)
|
||||||
|
return final_rules
|
||||||
|
|
||||||
|
|
||||||
|
def parse_rules(text):
|
||||||
|
"""
|
||||||
|
Really basic CSS parsers that stores selectors and corresponding properties. Only works
|
||||||
|
because the source files have coma-separated selectors (one per line), and one
|
||||||
|
property/value per line.
|
||||||
|
|
||||||
|
Returns a list of dictionaries, each dictionarry containing the selectors and
|
||||||
|
lines of of each block.
|
||||||
|
"""
|
||||||
|
rules = []
|
||||||
|
current_rule = None
|
||||||
|
opened_brackets = 0
|
||||||
|
current_selector = []
|
||||||
|
for line in text.splitlines():
|
||||||
|
if not current_rule and line.endswith(","):
|
||||||
|
current_selector.append(line.rstrip(",").strip())
|
||||||
|
elif line.endswith(" {"):
|
||||||
|
# for media queries
|
||||||
|
opened_brackets += 1
|
||||||
|
if not current_rule:
|
||||||
|
current_selector.append(line.rstrip("{").strip())
|
||||||
|
current_rule = {
|
||||||
|
"lines": [",\n".join(current_selector) + " {"],
|
||||||
|
"selectors": current_selector,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
current_rule["lines"].append(line)
|
||||||
|
elif current_rule:
|
||||||
|
current_rule["lines"].append(line)
|
||||||
|
if line.strip() == "}":
|
||||||
|
opened_brackets -= 1
|
||||||
|
if not opened_brackets:
|
||||||
|
# move on to next rule
|
||||||
|
rules.append(current_rule)
|
||||||
|
current_rule = None
|
||||||
|
current_selector = []
|
||||||
|
|
||||||
|
return rules
|
||||||
|
|
||||||
|
|
||||||
|
def serialize_rules(rules):
|
||||||
|
"""
|
||||||
|
Convert rules back to valid CSS.
|
||||||
|
"""
|
||||||
|
lines = []
|
||||||
|
for rule in rules:
|
||||||
|
for line in rule["lines"]:
|
||||||
|
lines.append(line)
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def iter_components(dir):
|
||||||
|
for dname, dirs, files in os.walk(dir):
|
||||||
|
for fname in files:
|
||||||
|
if fname.endswith(".min.css"):
|
||||||
|
continue
|
||||||
|
if fname.endswith(".js"):
|
||||||
|
continue
|
||||||
|
if "semantic" in fname:
|
||||||
|
continue
|
||||||
|
if fname.endswith(".css"):
|
||||||
|
yield os.path.join(dname, fname)
|
||||||
|
|
||||||
|
|
||||||
|
def replace_vars(source, dest):
|
||||||
|
components = list(sorted(iter_components(os.path.join(source, "components"))))
|
||||||
|
for c in components:
|
||||||
|
with open(c, "r") as f:
|
||||||
|
text = f.read()
|
||||||
|
|
||||||
|
for s, r in GLOBAL_REPLACES:
|
||||||
|
text = text.replace(s, r)
|
||||||
|
text = text.replace(s.lower(), r)
|
||||||
|
text = text.replace(s.upper(), r)
|
||||||
|
rules = parse_rules(text)
|
||||||
|
name = c.split("/")[-1].split(".")[0]
|
||||||
|
updated_rules = set_vars(name, rules)
|
||||||
|
text = serialize_rules(updated_rules)
|
||||||
|
with open(os.path.join(dest, "{}.css".format(name)), "w") as f:
|
||||||
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Replace hardcoded values by CSS vars and strip unused rules")
|
||||||
|
parser.add_argument(
|
||||||
|
"source", help="Source path of the fomantic-ui-less distribution to fix"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"dest", help="Destination directory where fixed files should be written"
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
replace_vars(source=args.source, dest=args.dest)
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash -eux
|
||||||
|
|
||||||
|
find node_modules/fomantic-ui-css/components -name "*.min.css" -delete
|
||||||
|
mkdir -p node_modules/fomantic-ui-css/tweaked
|
||||||
|
echo 'Removing google font…'
|
||||||
|
sed -i '/@import url(/d' node_modules/fomantic-ui-css/components/site.css
|
||||||
|
echo "Replacing hardcoded values by CSS vars…"
|
||||||
|
scripts/fix-fomantic-css.py node_modules/fomantic-ui-css node_modules/fomantic-ui-css/tweaked
|
|
@ -444,194 +444,4 @@ export default {
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "style/_main";
|
@import "style/_main";
|
||||||
|
|
||||||
.ui.bottom-player {
|
|
||||||
z-index: 999999;
|
|
||||||
width: 100%;
|
|
||||||
width: 100vw;
|
|
||||||
.ui.top.attached.progress {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.dimmed {
|
|
||||||
.ui.bottom-player {
|
|
||||||
@include media("<desktop") {
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#app.queue-focused {
|
|
||||||
.queue-not-focused {
|
|
||||||
@include media("<desktop") {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.when-queue-focused {
|
|
||||||
.group {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 1.1em;
|
|
||||||
> * {
|
|
||||||
margin-left: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include media("<desktop") {
|
|
||||||
width: 100%;
|
|
||||||
justify-content: space-between !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#app:not(.queue-focused) {
|
|
||||||
.when-queue-focused {
|
|
||||||
@include media("<desktop") {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.bottom-player > .segment.fixed-controls {
|
|
||||||
width: 100%;
|
|
||||||
width: 100vw;
|
|
||||||
border-radius: 0;
|
|
||||||
padding: 0em;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
margin: 0;
|
|
||||||
z-index: 1001;
|
|
||||||
height: $bottom-player-height;
|
|
||||||
.controls-row {
|
|
||||||
height: $bottom-player-height;
|
|
||||||
margin: 0 auto;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
@include media(">desktop") {
|
|
||||||
padding: 0 1em;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor: pointer;
|
|
||||||
.indicating.progress {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.progress .bar {
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.progress .buffer.bar {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes MOVE-BG {
|
|
||||||
from {
|
|
||||||
transform: translateX(0px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateX(46px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.discrete.link {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
.indicating.progress .bar {
|
|
||||||
left: -46px;
|
|
||||||
width: 200% !important;
|
|
||||||
color: grey;
|
|
||||||
background: repeating-linear-gradient(
|
|
||||||
-55deg,
|
|
||||||
grey 1px,
|
|
||||||
grey 10px,
|
|
||||||
transparent 10px,
|
|
||||||
transparent 20px
|
|
||||||
) !important;
|
|
||||||
|
|
||||||
animation-name: MOVE-BG;
|
|
||||||
animation-duration: 2s;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
.ui.progress:not([data-percent]):not(.indeterminate)
|
|
||||||
.bar.position:not(.buffer) {
|
|
||||||
background: #ff851b;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.track-controls {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: start;
|
|
||||||
flex-grow: 1;
|
|
||||||
.image {
|
|
||||||
padding: 0.5em;
|
|
||||||
width: auto;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
> img {
|
|
||||||
max-height: 3.7em;
|
|
||||||
max-width: 4.7em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.controls {
|
|
||||||
min-width: 8em;
|
|
||||||
font-size: 1.1em;
|
|
||||||
@include media(">desktop") {
|
|
||||||
&:not(.fluid) {
|
|
||||||
width: 20%;
|
|
||||||
}
|
|
||||||
&.queue-controls {
|
|
||||||
width: 32.5%;
|
|
||||||
}
|
|
||||||
&.progress-controls {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
&.player-controls {
|
|
||||||
width: 15%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.small, .small {
|
|
||||||
@include media(">desktop") {
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
.icon.large {
|
|
||||||
font-size: 1.4em;
|
|
||||||
}
|
|
||||||
&:not(.track-controls) {
|
|
||||||
@include media(">desktop") {
|
|
||||||
line-height: 1em;
|
|
||||||
}
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
&.align-right {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
&.align-left {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
> * {
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.player-controls {
|
|
||||||
.icon {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.queue-enter-active, .queue-leave-active {
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
.current-track, .queue-column {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.queue-enter, .queue-leave-to {
|
|
||||||
transform: translateY(100vh);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<main class="main pusher">
|
<main class="main pusher page-about">
|
||||||
<section :class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle">
|
<section :class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle">
|
||||||
<div class="segment-content">
|
<div class="segment-content">
|
||||||
<h1 class="ui center aligned large header">
|
<h1 class="ui center aligned large header">
|
||||||
|
@ -173,22 +173,22 @@
|
||||||
<translate translate-context="Content/Home/Header">Statistics</translate>
|
<translate translate-context="Content/Home/Header">Statistics</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<i class="user grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.users.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.users" translate-plural="%{ count } active users">%{ count } active user</translate>
|
<i class="user really discrete icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.users.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.users" translate-plural="%{ count } active users">%{ count } active user</translate>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<i class="music grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale)}" :translate-n="parseInt(stats.hours)" translate-plural="%{ count } hours of music">%{ count } hour of music</translate>
|
<i class="music really discrete icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale)}" :translate-n="parseInt(stats.hours)" translate-plural="%{ count } hours of music">%{ count } hour of music</translate>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="stats.artists">
|
<p v-if="stats.artists">
|
||||||
<i class="users grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.artists.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.artists" translate-plural="%{ count } artists">%{ count } artists</translate>
|
<i class="users really discrete icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.artists.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.artists" translate-plural="%{ count } artists">%{ count } artists</translate>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="stats.albums">
|
<p v-if="stats.albums">
|
||||||
<i class="headphones grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.albums.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.albums" translate-plural="%{ count } albums">%{ count } albums</translate>
|
<i class="headphones really discrete icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.albums.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.albums" translate-plural="%{ count } albums">%{ count } albums</translate>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="stats.tracks">
|
<p v-if="stats.tracks">
|
||||||
<i class="file grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.tracks.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.tracks" translate-plural="%{ count } tracks">%{ count } tracks</translate>
|
<i class="file really discrete icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.tracks.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.tracks" translate-plural="%{ count } tracks">%{ count } tracks</translate>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="stats.listenings">
|
<p v-if="stats.listenings">
|
||||||
<i class="play grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.listenings.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.listenings" translate-plural="%{ count } listenings">%{ count } listenings</translate>
|
<i class="play really discrete icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.listenings.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.listenings" translate-plural="%{ count } listenings">%{ count } listenings</translate>
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -285,38 +285,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
|
|
||||||
.ui.list .list.icon {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1.header, h1 .sub.header {
|
|
||||||
text-shadow: 0 2px 0 rgba(0,0,0,.8);
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
h1.ui.header {
|
|
||||||
font-size: 3em;
|
|
||||||
}
|
|
||||||
h1.ui.header .sub.header {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
.main.pusher {
|
|
||||||
margin-top: 0;
|
|
||||||
min-height: 10em;
|
|
||||||
}
|
|
||||||
section.segment.head {
|
|
||||||
padding: 8em 3em;
|
|
||||||
background: linear-gradient(90deg, rgba(40,88,125,1) 0%, rgba(64,130,180,1) 100%);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
#pod {
|
|
||||||
font-size: 110%;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -9,16 +9,16 @@
|
||||||
<h4 v-else class="ui header ellipsis">
|
<h4 v-else class="ui header ellipsis">
|
||||||
<span v-translate="{instanceUrl: instanceHostname}" translate-context="Footer/About/Title">About %{instanceUrl}</span>
|
<span v-translate="{instanceUrl: instanceHostname}" translate-context="Footer/About/Title">About %{instanceUrl}</span>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ui link list">
|
<div class="ui list">
|
||||||
<router-link class="item" to="/about">
|
<router-link class="link item" to="/about">
|
||||||
<translate translate-context="Footer/About/List item.Link">About page</translate>
|
<translate translate-context="Footer/About/List item.Link">About page</translate>
|
||||||
</router-link>
|
</router-link>
|
||||||
<a v-if="version" class="item" href="https://docs.funkwhale.audio/changelog.html" target="_blank">
|
<a v-if="version" class="link item" href="https://docs.funkwhale.audio/changelog.html" target="_blank">
|
||||||
<translate translate-context="Footer/*/List item" :translate-params="{version: version}" >Version %{version}</translate>
|
<translate translate-context="Footer/*/List item" :translate-params="{version: version}" >Version %{version}</translate>
|
||||||
</a>
|
</a>
|
||||||
<div role="button" class="item" @click="$emit('show:set-instance-modal')" >
|
<a role="button" class="link item" @click.prevent="$emit('show:set-instance-modal')" >
|
||||||
<translate translate-context="Footer/*/List item.Link">Use another instance</translate>
|
<translate translate-context="Footer/*/List item.Link">Use another instance</translate>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui form">
|
<div class="ui form">
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
|
@ -31,10 +31,10 @@
|
||||||
</section>
|
</section>
|
||||||
<section class="four wide column">
|
<section class="four wide column">
|
||||||
<h4 v-translate class="ui header" translate-context="Footer/*/Title">Using Funkwhale</h4>
|
<h4 v-translate class="ui header" translate-context="Footer/*/Title">Using Funkwhale</h4>
|
||||||
<div class="ui link list">
|
<div class="ui list">
|
||||||
<a href="https://docs.funkwhale.audio" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link/Short, Noun">Documentation</translate></a>
|
<a href="https://docs.funkwhale.audio" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link/Short, Noun">Documentation</translate></a>
|
||||||
<a href="https://funkwhale.audio/apps" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Mobile and desktop apps</translate></a>
|
<a href="https://funkwhale.audio/apps" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Mobile and desktop apps</translate></a>
|
||||||
<div role="button" class="item" @click="$emit('show:shortcuts-modal')"><translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate></div>
|
<a role="button" class="link item" @click.prevent="$emit('show:shortcuts-modal')"><translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui form">
|
<div class="ui form">
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
|
@ -47,18 +47,18 @@
|
||||||
</section>
|
</section>
|
||||||
<section class="four wide column">
|
<section class="four wide column">
|
||||||
<h4 v-translate translate-context="Footer/*/Link" class="ui header">Getting help</h4>
|
<h4 v-translate translate-context="Footer/*/Link" class="ui header">Getting help</h4>
|
||||||
<div class="ui link list">
|
<div class="ui list">
|
||||||
<a href="https://governance.funkwhale.audio/g/kQgxNq15/funkwhale" class="item" target="_blank"><translate translate-context="Footer/*/Listitem.Link">Support forum</translate></a>
|
<a href="https://governance.funkwhale.audio/g/kQgxNq15/funkwhale" class="link item" target="_blank"><translate translate-context="Footer/*/Listitem.Link">Support forum</translate></a>
|
||||||
<a href="https://riot.im/app/#/room/#funkwhale-troubleshooting:matrix.org" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Chat room</translate></a>
|
<a href="https://riot.im/app/#/room/#funkwhale-troubleshooting:matrix.org" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Chat room</translate></a>
|
||||||
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Issue tracker</translate></a>
|
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Issue tracker</translate></a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="four wide column">
|
<section class="four wide column">
|
||||||
<h4 v-translate class="ui header" translate-context="Footer/*/Title/Short">About Funkwhale</h4>
|
<h4 v-translate class="ui header" translate-context="Footer/*/Title/Short">About Funkwhale</h4>
|
||||||
<div class="ui link list">
|
<div class="ui list">
|
||||||
<a href="https://funkwhale.audio" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Official website</translate></a>
|
<a href="https://funkwhale.audio" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Official website</translate></a>
|
||||||
<a href="https://contribute.funkwhale.audio" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Contribute</translate></a>
|
<a href="https://contribute.funkwhale.audio" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Contribute</translate></a>
|
||||||
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Source code</translate></a>
|
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Source code</translate></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui hidden divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<main class="main pusher" v-title="labels.title">
|
<main class="main pusher page-home" v-title="labels.title">
|
||||||
<section :class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle">
|
<section :class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle">
|
||||||
<div class="segment-content">
|
<div class="segment-content">
|
||||||
<h1 class="ui center aligned large header">
|
<h1 class="ui center aligned large header">
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
<div v-if="truncatedDescription" class="ui hidden divider"></div>
|
<div v-if="truncatedDescription" class="ui hidden divider"></div>
|
||||||
<div class="ui relaxed list">
|
<div class="ui relaxed list">
|
||||||
<div class="item" v-if="truncatedDescription">
|
<div class="item" v-if="truncatedDescription">
|
||||||
<i class="arrow right grey icon"></i>
|
<i class="arrow right icon"></i>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<router-link class="ui link" :to="{name: 'about'}">
|
<router-link class="ui link" :to="{name: 'about'}">
|
||||||
<translate translate-context="Content/Home/Link">Learn more</translate>
|
<translate translate-context="Content/Home/Link">Learn more</translate>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item" v-if="rules">
|
<div class="item" v-if="rules">
|
||||||
<i class="book open grey icon"></i>
|
<i class="book open icon"></i>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<router-link class="ui link" v-if="rules" :to="{name: 'about', hash: '#rules'}">
|
<router-link class="ui link" v-if="rules" :to="{name: 'about', hash: '#rules'}">
|
||||||
<translate translate-context="Content/Home/Link">Server rules</translate>
|
<translate translate-context="Content/Home/Link">Server rules</translate>
|
||||||
|
@ -56,10 +56,10 @@
|
||||||
<translate translate-context="Content/Home/Header">Statistics</translate>
|
<translate translate-context="Content/Home/Header">Statistics</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<i class="user grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.users.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.users" translate-plural="%{ count } active users">%{ count } active user</translate>
|
<i class="user icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.users.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.users" translate-plural="%{ count } active users">%{ count } active user</translate>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<i class="music grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale)}" :translate-n="parseInt(stats.hours)" translate-plural="%{ count } hours of music">%{ count } hour of music</translate>
|
<i class="music icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale)}" :translate-n="parseInt(stats.hours)" translate-plural="%{ count } hours of music">%{ count } hour of music</translate>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
<h3 class="sub header">
|
<h3 class="sub header">
|
||||||
<translate translate-context="Content/Home/Header/Name">Contact</translate>
|
<translate translate-context="Content/Home/Header/Name">Contact</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<i class="at grey icon"></i>
|
<i class="at icon"></i>
|
||||||
<a :href="`mailto:${contactEmail}`">{{ contactEmail }}</a>
|
<a :href="`mailto:${contactEmail}`">{{ contactEmail }}</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate translate-context="Head/Login/Title">Log In</translate>
|
<translate translate-context="Head/Login/Title">Log In</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<login-form button-classes="basic green" :show-signup="false"></login-form>
|
<login-form button-classes="basic success" :show-signup="false"></login-form>
|
||||||
<div class="ui hidden clearing divider"></div>
|
<div class="ui hidden clearing divider"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
<p v-if="defaultUploadQuota">
|
<p v-if="defaultUploadQuota">
|
||||||
<translate translate-context="Content/Home/Paragraph" :translate-params="{quota: humanSize(defaultUploadQuota * 1000 * 1000)}">Users on this pod also get %{ quota } of free storage to upload their own content!</translate>
|
<translate translate-context="Content/Home/Paragraph" :translate-params="{quota: humanSize(defaultUploadQuota * 1000 * 1000)}">Users on this pod also get %{ quota } of free storage to upload their own content!</translate>
|
||||||
</p>
|
</p>
|
||||||
<signup-form button-classes="basic green" :show-login="false"></signup-form>
|
<signup-form button-classes="basic success" :show-login="false"></signup-form>
|
||||||
</template>
|
</template>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<p translate-context="Content/Home/Paragraph">Registrations are closed on this pod. You can signup on another pod using the link below.</p>
|
<p translate-context="Content/Home/Paragraph">Registrations are closed on this pod. You can signup on another pod using the link below.</p>
|
||||||
|
@ -288,39 +288,3 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "../style/vendor/media";
|
|
||||||
|
|
||||||
.ui.list .list.icon {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1.header, h1 .sub.header {
|
|
||||||
text-shadow: 1px 1px 2px rgba(0,0,0,.8);
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
h1.ui.header {
|
|
||||||
@include media(">tablet") {
|
|
||||||
font-size: 3em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h1.ui.header .sub.header {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
.main.pusher {
|
|
||||||
margin-top: 0;
|
|
||||||
min-height: 10em;
|
|
||||||
}
|
|
||||||
section.segment.head {
|
|
||||||
padding: 8em 3em;
|
|
||||||
background: linear-gradient(90deg, rgba(40,88,125,1) 0%, rgba(64,130,180,1) 100%);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
#pod {
|
|
||||||
font-size: 110%;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -36,7 +36,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if='maxPage > 1' class="ui pagination menu" role="navigation" :aria-label="labels.pagination">
|
<div v-if='maxPage > 1' class="ui pagination menu component-pagination" role="navigation" :aria-label="labels.pagination">
|
||||||
<a href
|
<a href
|
||||||
:disabled="current - 1 < 1"
|
:disabled="current - 1 < 1"
|
||||||
@click.prevent.stop="selectPage(current - 1)"
|
@click.prevent.stop="selectPage(current - 1)"
|
||||||
|
@ -95,10 +95,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.ui.pagination.menu .item {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<section class="main with-background" :aria-label="labels.queue">
|
<section class="main with-background component-queue" :aria-label="labels.queue">
|
||||||
<div :class="['ui vertical stripe queue segment', playerFocused ? 'player-focused' : '']">
|
<div :class="['ui vertical stripe queue segment', playerFocused ? 'player-focused' : '']">
|
||||||
<div class="ui fluid container">
|
<div class="ui fluid container">
|
||||||
<div class="ui stackable grid" id="queue-grid">
|
<div class="ui stackable grid" id="queue-grid">
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
<div class="progress-area" v-if="currentTrack && !errored">
|
<div class="progress-area" v-if="currentTrack && !errored">
|
||||||
<div
|
<div
|
||||||
ref="progress"
|
ref="progress"
|
||||||
:class="['ui', 'small', 'orange', {'indicating': isLoadingAudio}, 'progress']"
|
:class="['ui', 'small', 'vibrant', {'indicating': isLoadingAudio}, 'progress']"
|
||||||
@click="touchProgress">
|
@click="touchProgress">
|
||||||
<div class="buffer bar" :data-percent="bufferProgress" :style="{ 'width': bufferProgress + '%' }"></div>
|
<div class="buffer bar" :data-percent="bufferProgress" :style="{ 'width': bufferProgress + '%' }"></div>
|
||||||
<div class="position bar" :data-percent="progress" :style="{ 'width': progress + '%' }"></div>
|
<div class="position bar" :data-percent="progress" :style="{ 'width': progress + '%' }"></div>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<div class="progress-area" v-else>
|
<div class="progress-area" v-else>
|
||||||
<div
|
<div
|
||||||
ref="progress"
|
ref="progress"
|
||||||
:class="['ui', 'small', 'orange', 'progress']">
|
:class="['ui', 'small', 'vibrant', 'progress']">
|
||||||
<div class="buffer bar"></div>
|
<div class="buffer bar"></div>
|
||||||
<div class="position bar"></div>
|
<div class="position bar"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui sixteen wide mobile ten wide computer column queue-column">
|
<div class="ui ten wide column queue-column">
|
||||||
<div class="ui basic clearing fixed-header segment">
|
<div class="ui basic clearing fixed-header segment">
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="['queue-item', {'active': index === queue.currentIndex}]">
|
:class="['queue-item', {'active': index === queue.currentIndex}]">
|
||||||
<td class="handle">
|
<td class="handle">
|
||||||
<i class="grip lines grey icon"></i>
|
<i class="grip lines icon"></i>
|
||||||
</td>
|
</td>
|
||||||
<td class="image-cell" @click="$store.dispatch('queue/currentIndex', index)">
|
<td class="image-cell" @click="$store.dispatch('queue/currentIndex', index)">
|
||||||
<img class="ui mini image" v-if="track.album && track.album.cover && track.album.cover.original" :src="$store.getters['instance/absoluteUrl'](track.album.cover.square_crop)">
|
<img class="ui mini image" v-if="track.album && track.album.cover && track.album.cover.original" :src="$store.getters['instance/absoluteUrl'](track.album.cover.square_crop)">
|
||||||
|
@ -374,204 +374,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import "../style/vendor/media";
|
|
||||||
|
|
||||||
.main {
|
|
||||||
position: absolute;
|
|
||||||
min-height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
z-index: 1000;
|
|
||||||
padding-bottom: 3em;
|
|
||||||
}
|
|
||||||
.main > .button {
|
|
||||||
position: fixed;
|
|
||||||
top: 1em;
|
|
||||||
right: 1em;
|
|
||||||
z-index: 9999999;
|
|
||||||
@include media("<desktop") {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.queue.segment:not(.player-focused) {
|
|
||||||
#player {
|
|
||||||
@include media("<desktop") {
|
|
||||||
height: 0;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.queue.segment #player {
|
|
||||||
padding: 0em;
|
|
||||||
> * {
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.player-focused .grid > .ui.queue-column {
|
|
||||||
@include media("<desktop") {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.queue-column {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.queue-column .table {
|
|
||||||
margin-top: 4em !important;
|
|
||||||
margin-bottom: 4rem;
|
|
||||||
}
|
|
||||||
.ui.table > tbody > tr > td.controls {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.ui.table > tbody > tr > td {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
td:first-child {
|
|
||||||
padding-left: 1em !important;
|
|
||||||
}
|
|
||||||
td:last-child {
|
|
||||||
padding-right: 1em !important;
|
|
||||||
}
|
|
||||||
.image-cell {
|
|
||||||
width: 4em;
|
|
||||||
}
|
|
||||||
.queue.segment {
|
|
||||||
@include media("<desktop") {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
> .container {
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.handle {
|
|
||||||
@include media("<desktop") {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.duration-cell {
|
|
||||||
@include media("<tablet") {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fixed-header {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 9;
|
|
||||||
@include media("<desktop") {
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
@include media(">desktop") {
|
|
||||||
right: 1em;
|
|
||||||
left: 38%;
|
|
||||||
}
|
|
||||||
.header .content {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.current-track #player {
|
|
||||||
font-size: 1.8em;
|
|
||||||
padding: 1em;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
position: fixed;
|
|
||||||
height: 100vh;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
bottom: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 32%;
|
|
||||||
@include media("<desktop") {
|
|
||||||
padding: 0.5em;
|
|
||||||
font-size: 1.5em;
|
|
||||||
width: 100%;
|
|
||||||
width: 100vw;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
> .image {
|
|
||||||
max-height: 50vh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
> *:not(.image) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
margin: 0;
|
|
||||||
min-height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.progress-area {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.progress-wrapper, .warning.message {
|
|
||||||
max-width: 25em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.ui.progress .buffer.bar {
|
|
||||||
position: absolute;
|
|
||||||
background-color: rgba(255, 255, 255, 0.15);
|
|
||||||
}
|
|
||||||
.ui.progress:not([data-percent]):not(.indeterminate)
|
|
||||||
.bar.position:not(.buffer) {
|
|
||||||
background: #ff851b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.indicating.progress .bar {
|
|
||||||
left: -46px;
|
|
||||||
width: 200% !important;
|
|
||||||
color: grey;
|
|
||||||
background: repeating-linear-gradient(
|
|
||||||
-55deg,
|
|
||||||
grey 1px,
|
|
||||||
grey 10px,
|
|
||||||
transparent 10px,
|
|
||||||
transparent 20px
|
|
||||||
) !important;
|
|
||||||
|
|
||||||
animation-name: MOVE-BG;
|
|
||||||
animation-duration: 2s;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
.ui.progress {
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
}
|
|
||||||
.timer {
|
|
||||||
font-size: 0.7em;
|
|
||||||
}
|
|
||||||
.progress {
|
|
||||||
cursor: pointer;
|
|
||||||
.bar {
|
|
||||||
min-width: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.player-controls {
|
|
||||||
.control:not(:first-child) {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.handle {
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
.sortable-chosen {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
.queue-item.sortable-ghost {
|
|
||||||
td {
|
|
||||||
border-top: 3px dashed rgba(0, 0, 0, 0.15) !important;
|
|
||||||
border-bottom: 3px dashed rgba(0, 0, 0, 0.15) !important;
|
|
||||||
&:first-child {
|
|
||||||
border-left: 3px dashed rgba(0, 0, 0, 0.15) !important;
|
|
||||||
}
|
|
||||||
&:last-child {
|
|
||||||
border-right: 3px dashed rgba(0, 0, 0, 0.15) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -142,6 +142,3 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -157,7 +157,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<aside :class="['ui', 'vertical', 'left', 'visible', 'wide', {'collapsed': isCollapsed}, 'sidebar',]">
|
<aside :class="['ui', 'vertical', 'left', 'visible', 'wide', {'collapsed': isCollapsed}, 'sidebar', 'component-sidebar']">
|
||||||
<header class="ui basic segment header-wrapper">
|
<header class="ui basic segment header-wrapper">
|
||||||
<router-link :title="'Funkwhale'" :to="{name: logoUrl}">
|
<router-link :title="'Funkwhale'" :to="{name: logoUrl}">
|
||||||
<i class="logo bordered inverted orange big icon">
|
<i class="logo bordered inverted vibrant big icon">
|
||||||
<logo class="logo"></logo>
|
<logo class="logo"></logo>
|
||||||
</i>
|
</i>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
|
|
||||||
<span
|
<span
|
||||||
@click="isCollapsed = !isCollapsed"
|
@click="isCollapsed = !isCollapsed"
|
||||||
:class="['ui', 'basic', 'big', {'orange': !isCollapsed}, 'inverted icon', 'collapse', 'button']">
|
:class="['ui', 'basic', 'big', {'vibrant': !isCollapsed}, 'inverted icon', 'collapse', 'button']">
|
||||||
<i class="sidebar icon"></i></span>
|
<i class="sidebar icon"></i></span>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -343,239 +343,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "../style/vendor/media";
|
|
||||||
|
|
||||||
$sidebar-color: #2D2F33;
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background: $sidebar-color;
|
|
||||||
z-index: 1;
|
|
||||||
@include media(">desktop") {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-bottom: 4em;
|
|
||||||
}
|
|
||||||
> nav {
|
|
||||||
flex-grow: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
@include media(">desktop") {
|
|
||||||
.menu .item.collapse-button-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.collapse.button {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include media("<=desktop") {
|
|
||||||
position: static !important;
|
|
||||||
width: 100% !important;
|
|
||||||
&.collapsed {
|
|
||||||
.player-wrapper,
|
|
||||||
.search,
|
|
||||||
.signup.segment,
|
|
||||||
nav.secondary {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> div {
|
|
||||||
margin: 0;
|
|
||||||
background-color: $sidebar-color;
|
|
||||||
}
|
|
||||||
.menu.vertical {
|
|
||||||
background: $sidebar-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.vertical.menu {
|
|
||||||
.item .item {
|
|
||||||
font-size: 1em;
|
|
||||||
> i.icon {
|
|
||||||
float: none;
|
|
||||||
margin: 0 0.5em 0 0;
|
|
||||||
}
|
|
||||||
&:not(.active) {
|
|
||||||
// color: rgba(255, 255, 255, 0.75);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item.active {
|
|
||||||
border-right: 5px solid #F2711C;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
background-color: rgba(255, 255, 255, 0.15) !important;
|
|
||||||
}
|
|
||||||
.item.collapsed {
|
|
||||||
&:not(:focus) > .menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.collaspable.item .header {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.secondary.menu {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
.tabs {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow-y: auto;
|
|
||||||
justify-content: space-between;
|
|
||||||
@include media("<=desktop") {
|
|
||||||
max-height: 500px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.tab.active {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.tab[data-tab="queue"] {
|
|
||||||
flex-direction: column;
|
|
||||||
tr {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
td:nth-child(2) {
|
|
||||||
width: 55px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item .header .angle.icon {
|
|
||||||
float: right;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.tab[data-tab="library"] {
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
> .menu {
|
|
||||||
flex: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
> .player-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sidebar .segment {
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.menu .item.inline.admin-dropdown.dropdown > .menu {
|
|
||||||
left: 0;
|
|
||||||
right: auto;
|
|
||||||
}
|
|
||||||
.ui.segment.header-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
height: 4em;
|
|
||||||
nav {
|
|
||||||
> .item, > .menu > .item > .item {
|
|
||||||
&:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nav.top.title-menu {
|
|
||||||
flex-grow: 1;
|
|
||||||
.item {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapsed .search-wrapper {
|
|
||||||
@include media("<desktop") {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.search {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.ui.message.black {
|
|
||||||
background: $sidebar-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.mini.image {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
nav.top {
|
|
||||||
align-items: self-end;
|
|
||||||
padding: 0.5em 0;
|
|
||||||
> .item, > .right.menu > .item {
|
|
||||||
// color: rgba(255, 255, 255, 0.9) !important;
|
|
||||||
font-size: 1.2em;
|
|
||||||
&:hover, > .dropdown > .icon {
|
|
||||||
// color: rgba(255, 255, 255, 0.9) !important;
|
|
||||||
}
|
|
||||||
> .label, > .dropdown > .label {
|
|
||||||
font-size: 0.5em;
|
|
||||||
right: 1.7em;
|
|
||||||
bottom: -0.5em;
|
|
||||||
z-index: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.user-dropdown > .text > .label {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
.logo-wrapper {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 auto;
|
|
||||||
@include media("<desktop") {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
height: 1em;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
@include media(">tablet") {
|
|
||||||
img {
|
|
||||||
height: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
aside.ui.sidebar {
|
|
||||||
overflow-y: visible !important;
|
|
||||||
.ui.search .input {
|
|
||||||
flex: 1;
|
|
||||||
.prompt {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.search .results {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.ui.search .name {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ui.tiny.avatar.image {
|
|
||||||
position: relative;
|
|
||||||
top: -0.5em;
|
|
||||||
width: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
:not(.active) button.title {
|
|
||||||
outline-color: white;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<form :id="group.id" class="ui form" @submit.prevent="save">
|
<form :id="group.id" class="ui form component-settings-group" @submit.prevent="save">
|
||||||
<div class="ui divider" />
|
<div class="ui divider" />
|
||||||
<h3 class="ui header">{{ group.label }}</h3>
|
<h3 class="ui header">{{ group.label }}</h3>
|
||||||
<div v-if="errors.length > 0" class="ui negative message">
|
<div v-if="errors.length > 0" class="ui negative message">
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']">
|
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']">
|
||||||
<translate translate-context="Content/*/Button.Label/Verb">Save</translate>
|
<translate translate-context="Content/*/Button.Label/Verb">Save</translate>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -176,10 +176,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.ui.checkbox p {
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="album-entries">
|
<div class="album-entries">
|
||||||
<div :class="[{active: currentTrack && isPlaying && track.id === currentTrack.id}, 'album-entry']" v-for="track in tracks" :key="track.id">
|
<div :class="[{active: currentTrack && isPlaying && track.id === currentTrack.id}, 'album-entry']" v-for="track in tracks" :key="track.id">
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<play-button class="basic circular icon" :button-classes="['circular inverted orange icon button']" :discrete="true" :icon-only="true" :track="track"></play-button>
|
<play-button class="basic circular icon" :button-classes="['circular inverted vibrant icon button']" :discrete="true" :icon-only="true" :track="track"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="position">{{ prettyPosition(track.position) }}</div>
|
<div class="position">{{ prettyPosition(track.position) }}</div>
|
||||||
<div class="content ellipsis">
|
<div class="content ellipsis">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div
|
<div
|
||||||
@click="$router.push({name: 'channels.detail', params: {id: urlId}})"
|
@click="$router.push({name: 'channels.detail', params: {id: urlId}})"
|
||||||
:class="['ui', 'head-image', {'circular': object.artist.content_category != 'podcast'}, {'padded': object.artist.content_category === 'podcast'}, 'image', {'default-cover': !object.artist.cover}]" v-lazy:background-image="imageUrl">
|
:class="['ui', 'head-image', {'circular': object.artist.content_category != 'podcast'}, {'padded': object.artist.content_category === 'podcast'}, 'image', {'default-cover': !object.artist.cover}]" v-lazy:background-image="imageUrl">
|
||||||
<play-button :icon-only="true" :is-playable="true" :button-classes="['ui', 'circular', 'large', 'orange', 'icon', 'button']" :artist="object.artist"></play-button>
|
<play-button :icon-only="true" :is-playable="true" :button-classes="['ui', 'circular', 'large', 'vibrant', 'icon', 'button']" :artist="object.artist"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
class="right floated basic icon"
|
class="right floated basic icon"
|
||||||
:dropdown-only="true"
|
:dropdown-only="true"
|
||||||
:is-playable="true"
|
:is-playable="true"
|
||||||
:dropdown-icon-classes="['ellipsis', 'horizontal', 'large', 'grey']" :artist="object.artist" :channel="object" :account="object.attributed_to"></play-button>
|
:dropdown-icon-classes="['ellipsis', 'horizontal', 'large really discrete']" :artist="object.artist" :channel="object" :account="object.attributed_to"></play-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -58,14 +58,9 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
imageUrl () {
|
imageUrl () {
|
||||||
let url = '../../assets/audio/default-cover.png'
|
|
||||||
|
|
||||||
if (this.object.artist.cover) {
|
if (this.object.artist.cover) {
|
||||||
url = this.$store.getters['instance/absoluteUrl'](this.object.artist.cover.medium_square_crop)
|
return this.$store.getters['instance/absoluteUrl'](this.object.artist.cover.medium_square_crop)
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
return url
|
|
||||||
},
|
},
|
||||||
urlId () {
|
urlId () {
|
||||||
if (this.object.actor && this.object.actor.is_local) {
|
if (this.object.actor && this.object.actor.is_local) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="[{active: currentTrack && isPlaying && entry.id === currentTrack.id}, 'channel-entry-card']">
|
<div :class="[{active: currentTrack && isPlaying && entry.id === currentTrack.id}, 'channel-entry-card']">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<play-button class="basic circular icon" :discrete="true" :icon-only="true" :is-playable="true" :button-classes="['ui', 'circular', 'inverted orange', 'icon', 'button']" :track="entry"></play-button>
|
<play-button class="basic circular icon" :discrete="true" :icon-only="true" :is-playable="true" :button-classes="['ui', 'circular', 'inverted vibrant', 'icon', 'button']" :track="entry"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
@click="$router.push({name: 'library.tracks.detail', params: {id: entry.id}})"
|
@click="$router.push({name: 'library.tracks.detail', params: {id: entry.id}})"
|
||||||
|
@ -62,16 +62,6 @@ export default {
|
||||||
isPlaying () {
|
isPlaying () {
|
||||||
return this.$store.state.player.playing
|
return this.$store.state.player.playing
|
||||||
},
|
},
|
||||||
imageUrl () {
|
|
||||||
let url = '../../assets/audio/default-cover.png'
|
|
||||||
let cover = this.cover
|
|
||||||
if (cover && cover.original) {
|
|
||||||
url = this.$store.getters['instance/absoluteUrl'](cover.medium_square_crop)
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
},
|
|
||||||
cover () {
|
cover () {
|
||||||
if (this.entry.cover) {
|
if (this.entry.cover) {
|
||||||
return this.entry.cover
|
return this.entry.cover
|
||||||
|
@ -88,7 +78,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<play-button :icon-only="true" :is-playable="true" :button-classes="['ui', 'circular', 'orange', 'icon', 'button']" :album="serie"></play-button>
|
<play-button :icon-only="true" :is-playable="true" :button-classes="['ui', 'circular', 'vibrant', 'icon', 'button']" :album="serie"></play-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -36,16 +36,6 @@ export default {
|
||||||
PlayButton,
|
PlayButton,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
imageUrl () {
|
|
||||||
let url = '../../assets/audio/default-cover.png'
|
|
||||||
let cover = this.cover
|
|
||||||
if (cover && cover.original) {
|
|
||||||
url = this.$store.getters['instance/absoluteUrl'](cover.medium_square_crop)
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
},
|
|
||||||
cover () {
|
cover () {
|
||||||
if (this.serie.cover) {
|
if (this.serie.cover) {
|
||||||
return this.serie.cover
|
return this.serie.cover
|
||||||
|
@ -60,10 +50,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.default-cover {
|
|
||||||
background-image: url("../../assets/audio/default-cover.png") !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -115,12 +115,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
p.message {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: -2em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -37,7 +37,3 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<span :title="title" :class="['ui', {'tiny': discrete}, {'icon': !discrete}, {'buttons': !dropdownOnly && !iconOnly}, 'play-button']">
|
<span :title="title" :class="['ui', {'tiny': discrete}, {'icon': !discrete}, {'buttons': !dropdownOnly && !iconOnly}, 'play-button component-play-button']">
|
||||||
<button
|
<button
|
||||||
v-if="!dropdownOnly"
|
v-if="!dropdownOnly"
|
||||||
:title="labels.playNow"
|
:title="labels.playNow"
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
<div
|
<div
|
||||||
v-if="!discrete && !iconOnly"
|
v-if="!discrete && !iconOnly"
|
||||||
@click.prevent="clicked = true"
|
@click.prevent="clicked = true"
|
||||||
|
role="button"
|
||||||
:class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]">
|
:class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]">
|
||||||
<i :class="dropdownIconClasses.concat(['icon'])" :title="title" ></i>
|
<i :class="dropdownIconClasses.concat(['icon'])" :title="title" ></i>
|
||||||
<div class="menu" v-if="clicked">
|
<div class="menu" v-if="clicked">
|
||||||
|
@ -288,14 +289,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
i {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
button.item {
|
|
||||||
background-color: white;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<section v-if="currentTrack" class="player-wrapper ui bottom-player">
|
<section v-if="currentTrack" class="player-wrapper ui bottom-player component-player">
|
||||||
<div class="ui inverted segment fixed-controls" @click.prevent.stop="toggleMobilePlayer">
|
<div class="ui inverted segment fixed-controls" @click.prevent.stop="toggleMobilePlayer">
|
||||||
<div
|
<div
|
||||||
:class="['ui', 'top attached', 'small', 'orange', 'inverted', {'indicating': isLoadingAudio}, 'progress']">
|
:class="['ui', 'top attached', 'small', 'inverted', {'indicating': isLoadingAudio}, 'progress']">
|
||||||
<div class="buffer bar" :data-percent="bufferProgress" :style="{ 'width': bufferProgress + '%' }"></div>
|
<div class="buffer bar" :data-percent="bufferProgress" :style="{ 'width': bufferProgress + '%' }"></div>
|
||||||
<div class="position bar" :data-percent="progress" :style="{ 'width': progress + '%' }"></div>
|
<div class="position bar" :data-percent="progress" :style="{ 'width': progress + '%' }"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
:disabled="!currentTrack">
|
:disabled="!currentTrack">
|
||||||
<i
|
<i
|
||||||
class="repeat icon">
|
class="repeat icon">
|
||||||
<span class="ui circular tiny orange label">1</span>
|
<span class="ui circular tiny vibrant label">1</span>
|
||||||
</i>
|
</i>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
@ -141,7 +141,7 @@
|
||||||
@click.prevent.stop="$store.commit('player/looping', 0)">
|
@click.prevent.stop="$store.commit('player/looping', 0)">
|
||||||
<i
|
<i
|
||||||
class="repeat icon">
|
class="repeat icon">
|
||||||
<span class="ui circular tiny orange label">∞</span>
|
<span class="ui circular tiny vibrant label">∞</span>
|
||||||
</i>
|
</i>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
@ -436,7 +436,6 @@ export default {
|
||||||
param = "token"
|
param = "token"
|
||||||
value = this.$store.state.auth.scopedTokens.listen
|
value = this.$store.state.auth.scopedTokens.listen
|
||||||
}
|
}
|
||||||
console.log('HELLO', param, value, this.$store.state.auth.scopedTokens)
|
|
||||||
sources.forEach(e => {
|
sources.forEach(e => {
|
||||||
e.url = url.updateQueryString(e.url, param, value)
|
e.url = url.updateQueryString(e.url, param, value)
|
||||||
})
|
})
|
||||||
|
@ -777,77 +776,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "../../style/vendor/media";
|
|
||||||
.controls {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls .icon.big {
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 2em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls .icon {
|
|
||||||
cursor: pointer;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.timer {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
.looping {
|
|
||||||
i {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.ui.circular.label {
|
|
||||||
font-family: sans-serif;
|
|
||||||
position: absolute;
|
|
||||||
font-size: 0.5em !important;
|
|
||||||
bottom: -0.7rem;
|
|
||||||
right: -0.7rem;
|
|
||||||
padding: 2px 0 !important;
|
|
||||||
width: 15px !important;
|
|
||||||
height: 15px !important;
|
|
||||||
min-width: 15px !important;
|
|
||||||
min-height: 15px !important;
|
|
||||||
@include media(">desktop") {
|
|
||||||
font-size: 0.6em !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.shuffling.loader.inline {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.control.circular.button {
|
|
||||||
padding: 0;
|
|
||||||
border: none;
|
|
||||||
background-color: transparent;
|
|
||||||
color: inherit;
|
|
||||||
&:focus {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
.fake-dropdown {
|
|
||||||
border: 1px solid gray;
|
|
||||||
border-radius: 3px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
min-width: 10em;
|
|
||||||
> * {
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
}
|
|
||||||
.position.control {
|
|
||||||
padding-right: 1em;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.angle.icon {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -98,7 +98,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -236,7 +236,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<span :class="['volume-control', {'expanded': expanded}]" @click.prevent.stop="" @mouseover="handleOver" @mouseleave="handleLeave">
|
<span :class="['component-volume-control', {'expanded': expanded}]" @click.prevent.stop="" @mouseover="handleOver" @mouseleave="handleLeave">
|
||||||
<span
|
<span
|
||||||
role="button"
|
role="button"
|
||||||
v-if="sliderVolume === 0"
|
v-if="sliderVolume === 0"
|
||||||
|
@ -82,37 +82,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
.volume-control {
|
|
||||||
display: flex;
|
|
||||||
line-height: inherit;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
overflow: visible;
|
|
||||||
input {
|
|
||||||
max-width: 5.5em;
|
|
||||||
height: 4px;
|
|
||||||
}
|
|
||||||
&.expandable {
|
|
||||||
.popup {
|
|
||||||
background-color: #1B1C1D;
|
|
||||||
position: absolute;
|
|
||||||
left: -4em;
|
|
||||||
top: -7em;
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 2.5em;
|
|
||||||
padding: 0 0.5em;
|
|
||||||
box-shadow: 1px 1px 3px rgba(125, 125, 125, 0.5);
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
max-width: 8.5em;
|
|
||||||
}
|
|
||||||
&:not(:hover):not(.expanded) .popup {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="card app-card">
|
<div class="card app-card component-album-card">
|
||||||
<div
|
<div
|
||||||
@click="$router.push({name: 'library.albums.detail', params: {id: album.id}})"
|
@click="$router.push({name: 'library.albums.detail', params: {id: album.id}})"
|
||||||
:class="['ui', 'head-image', 'image', {'default-cover': !album.cover.original}]" v-lazy:background-image="imageUrl">
|
:class="['ui', 'head-image', 'image', {'default-cover': !album.cover.original}]" v-lazy:background-image="imageUrl">
|
||||||
<play-button :icon-only="true" :is-playable="album.is_playable" :button-classes="['ui', 'circular', 'large', 'orange', 'icon', 'button']" :album="album"></play-button>
|
<play-button :icon-only="true" :is-playable="album.is_playable" :button-classes="['ui', 'circular', 'large', 'vibrant', 'icon', 'button']" :album="album"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="extra content">
|
<div class="extra content">
|
||||||
<translate translate-context="*/*/*" :translate-params="{count: album.tracks.length}" :translate-n="album.tracks.length" translate-plural="%{ count } tracks">%{ count } track</translate>
|
<translate translate-context="*/*/*" :translate-params="{count: album.tracks.length}" :translate-n="album.tracks.length" translate-plural="%{ count } tracks">%{ count } track</translate>
|
||||||
<play-button class="right floated basic icon" :dropdown-only="true" :is-playable="album.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large', 'grey']" :album="album"></play-button>
|
<play-button class="right floated basic icon" :dropdown-only="true" :is-playable="album.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large really discrete']" :album="album"></play-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -38,28 +38,10 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
imageUrl () {
|
imageUrl () {
|
||||||
let url = '../../../assets/audio/default-cover.png'
|
|
||||||
|
|
||||||
if (this.album.cover.original) {
|
if (this.album.cover.original) {
|
||||||
url = this.$store.getters['instance/absoluteUrl'](this.album.cover.medium_square_crop)
|
return this.$store.getters['instance/absoluteUrl'](this.album.cover.medium_square_crop)
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
return url
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
|
|
||||||
.default-cover {
|
|
||||||
background-image: url("../../../assets/audio/default-cover.png") !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card.app-card > .head-image > .icon {
|
|
||||||
margin: 0.5em;
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -91,18 +91,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
|
||||||
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ui.cards {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style>
|
|
||||||
.ui.cards .ui.button {
|
|
||||||
margin-right: 0px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div
|
<div
|
||||||
@click="$router.push({name: 'library.artists.detail', params: {id: artist.id}})"
|
@click="$router.push({name: 'library.artists.detail', params: {id: artist.id}})"
|
||||||
:class="['ui', 'head-image', 'circular', 'image', {'default-cover': !cover.original}]" v-lazy:background-image="imageUrl">
|
:class="['ui', 'head-image', 'circular', 'image', {'default-cover': !cover.original}]" v-lazy:background-image="imageUrl">
|
||||||
<play-button :icon-only="true" :is-playable="artist.is_playable" :button-classes="['ui', 'circular', 'large', 'orange', 'icon', 'button']" :artist="artist"></play-button>
|
<play-button :icon-only="true" :is-playable="artist.is_playable" :button-classes="['ui', 'circular', 'large', 'vibrant', 'icon', 'button']" :artist="artist"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="extra content">
|
<div class="extra content">
|
||||||
<translate translate-context="*/*/*" :translate-params="{count: artist.tracks_count}" :translate-n="artist.tracks_count" translate-plural="%{ count } tracks">%{ count } track</translate>
|
<translate translate-context="*/*/*" :translate-params="{count: artist.tracks_count}" :translate-n="artist.tracks_count" translate-plural="%{ count } tracks">%{ count } track</translate>
|
||||||
<play-button class="right floated basic icon" :dropdown-only="true" :is-playable="artist.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large', 'grey']" :artist="artist"></play-button>
|
<play-button class="right floated basic icon" :dropdown-only="true" :is-playable="artist.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large really discrete']" :artist="artist"></play-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -39,14 +39,10 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
imageUrl () {
|
imageUrl () {
|
||||||
let url = '../../../assets/audio/default-cover.png'
|
|
||||||
let cover = this.cover
|
let cover = this.cover
|
||||||
if (cover.original) {
|
if (cover.original) {
|
||||||
url = this.$store.getters['instance/absoluteUrl'](cover.medium_square_crop)
|
return this.$store.getters['instance/absoluteUrl'](cover.medium_square_crop)
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
return url
|
|
||||||
},
|
},
|
||||||
cover () {
|
cover () {
|
||||||
if (this.artist.cover && this.artist.cover.original) {
|
if (this.artist.cover && this.artist.cover.original) {
|
||||||
|
@ -61,10 +57,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.default-cover {
|
|
||||||
background-image: url("../../../assets/audio/default-cover.png") !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -90,27 +90,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "../../../style/vendor/media";
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ui.cards {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.three.cards .card {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
@include media(">tablet") {
|
|
||||||
.ui.three.cards .card {
|
|
||||||
width: 25em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style>
|
|
||||||
.ui.cards .ui.button {
|
|
||||||
margin-right: 0px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<play-button :class="['basic', {orange: currentTrack && isPlaying && track.id === currentTrack.id}, 'icon']" :discrete="true" :is-playable="playable" :track="track"></play-button>
|
<play-button :class="['basic', {vibrant: currentTrack && isPlaying && track.id === currentTrack.id}, 'icon']" :discrete="true" :is-playable="playable" :track="track"></play-button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img class="ui mini image" v-if="track.album && track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](track.album.cover.small_square_crop)">
|
<img class="ui mini image" v-if="track.album && track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](track.album.cover.small_square_crop)">
|
||||||
|
@ -12,17 +12,17 @@
|
||||||
<template v-if="displayPosition && track.position">
|
<template v-if="displayPosition && track.position">
|
||||||
{{ track.position }}.
|
{{ track.position }}.
|
||||||
</template>
|
</template>
|
||||||
{{ track.title }}
|
{{ track.title|truncate(40) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="4">
|
<td colspan="4">
|
||||||
<router-link class="artist discrete link" :to="{name: 'library.artists.detail', params: {id: track.artist.id }}">
|
<router-link class="artist discrete link" :to="{name: 'library.artists.detail', params: {id: track.artist.id }}">
|
||||||
{{ track.artist.name }}
|
{{ track.artist.name|truncate(40) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="4">
|
<td colspan="4">
|
||||||
<router-link v-if="track.album" class="album discrete link" :title="track.album.title" :to="{name: 'library.albums.detail', params: {id: track.album.id }}">
|
<router-link v-if="track.album" class="album discrete link" :title="track.album.title" :to="{name: 'library.albums.detail', params: {id: track.album.id }}">
|
||||||
{{ track.album.title }}
|
{{ track.album.title|truncate(40) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="4" v-if="track.uploads && track.uploads.length > 0">
|
<td colspan="4" v-if="track.uploads && track.uploads.length > 0">
|
||||||
|
@ -32,17 +32,17 @@
|
||||||
<translate translate-context="*/*/*">N/A</translate>
|
<translate translate-context="*/*/*">N/A</translate>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="2" v-if="displayActions" class="align right">
|
<td colspan="2" v-if="displayActions" class="align right">
|
||||||
<track-favorite-icon class="favorite-icon" :track="track"></track-favorite-icon>
|
|
||||||
<play-button
|
<play-button
|
||||||
class="play-button basic icon"
|
class="play-button basic icon"
|
||||||
:dropdown-only="true"
|
:dropdown-only="true"
|
||||||
:is-playable="track.is_playable"
|
:is-playable="track.is_playable"
|
||||||
:dropdown-icon-classes="['ellipsis', 'vertical', 'large', 'grey']"
|
:dropdown-icon-classes="['ellipsis', 'vertical', 'large really discrete']"
|
||||||
:track="track"
|
:track="track"
|
||||||
></play-button>
|
></play-button>
|
||||||
<track-playlist-icon
|
<track-playlist-icon
|
||||||
v-if="$store.state.auth.authenticated"
|
v-if="$store.state.auth.authenticated"
|
||||||
:track="track"></track-playlist-icon>
|
:track="track"></track-playlist-icon>
|
||||||
|
<track-favorite-icon class="favorite-icon" :track="track"></track-favorite-icon>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
@ -83,13 +83,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
tr:not(:hover) {
|
|
||||||
.favorite-icon:not(.favorited),
|
|
||||||
.playlist-icon {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper component-track-table">
|
||||||
<inline-search-bar v-model="query" v-if="search" @search="additionalTracks = []; loadMore()"></inline-search-bar>
|
<inline-search-bar v-model="query" v-if="search" @search="additionalTracks = []; loadMore()"></inline-search-bar>
|
||||||
<slot v-if="!isLoading && allTracks.length === 0" name="empty-state">
|
<slot v-if="!isLoading && allTracks.length === 0" name="empty-state">
|
||||||
<empty-state @refresh="fetchData" :refresh="true"></empty-state>
|
<empty-state @refresh="fetchData" :refresh="true"></empty-state>
|
||||||
|
@ -90,16 +90,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
tr:not(:hover) .favorite-icon:not(.favorited) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
overflow-x: scroll;
|
|
||||||
}
|
|
||||||
.table-wrapper {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="component-track-widget">
|
||||||
<h3 class="ui header">
|
<h3 class="ui header">
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
<span v-if="showCount" class="ui tiny circular label">{{ count }}</span>
|
<span v-if="showCount" class="ui tiny circular label">{{ count }}</span>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<div class="ui tiny image">
|
<div class="ui tiny image">
|
||||||
<img v-if="object.track.album && object.track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](object.track.album.cover.medium_square_crop)">
|
<img v-if="object.track.album && object.track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](object.track.album.cover.medium_square_crop)">
|
||||||
<img v-else src="../../../assets/audio/default-cover.png">
|
<img v-else src="../../../assets/audio/default-cover.png">
|
||||||
<play-button class="play-overlay" :icon-only="true" :button-classes="['ui', 'circular', 'tiny', 'orange', 'icon', 'button']" :track="object.track"></play-button>
|
<play-button class="play-overlay" :icon-only="true" :button-classes="['ui', 'circular', 'tiny', 'vibrant', 'icon', 'button']" :track="object.track"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="middle aligned content">
|
<div class="middle aligned content">
|
||||||
<div class="ui unstackable grid">
|
<div class="ui unstackable grid">
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
class="basic icon"
|
class="basic icon"
|
||||||
:account="object.actor"
|
:account="object.actor"
|
||||||
:dropdown-only="true"
|
:dropdown-only="true"
|
||||||
:dropdown-icon-classes="['ellipsis', 'vertical', 'large', 'grey']"
|
:dropdown-icon-classes="['ellipsis', 'vertical', 'large really discrete']"
|
||||||
:track="object.track"></play-button>
|
:track="object.track"></play-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -151,37 +151,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "../../../style/vendor/media";
|
|
||||||
|
|
||||||
.play-overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: 4em;
|
|
||||||
left: 4em;
|
|
||||||
@include media(">tablet") {
|
|
||||||
top: 2.5em;
|
|
||||||
left: 2.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.refresh.icon {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.ui.divided.items > .item:last-child {
|
|
||||||
padding-bottom: 1em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include media(">tablet") {
|
|
||||||
.divided.items > .track-item.inline {
|
|
||||||
width: 25em;
|
|
||||||
float: left;
|
|
||||||
border-top: none;
|
|
||||||
&,
|
|
||||||
&:first-child {
|
|
||||||
margin-top: 0.5em !important;
|
|
||||||
margin-right: 0.5em !important;
|
|
||||||
padding: 1em 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<form class="ui form" @submit.prevent="submit()">
|
<form class="ui form component-form" @submit.prevent="submit()">
|
||||||
<div v-if="errors.length > 0" class="ui negative message">
|
<div v-if="errors.length > 0" class="ui negative message">
|
||||||
<div class="header"><translate translate-context="Content/*/Error message.Title">We cannot save your changes</translate></div>
|
<div class="header"><translate translate-context="Content/*/Error message.Title">We cannot save your changes</translate></div>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button :class="['ui', {'loading': isLoading}, 'green', 'button']" type="submit">
|
<button :class="['ui', {'loading': isLoading}, 'success', 'button']" type="submit">
|
||||||
<translate v-if="updating" key="2" translate-context="Content/Applications/Button.Label/Verb">Update application</translate>
|
<translate v-if="updating" key="2" translate-context="Content/Applications/Button.Label/Verb">Update application</translate>
|
||||||
<translate v-else key="2" translate-context="Content/Applications/Button.Label/Verb">Create application</translate>
|
<translate v-else key="2" translate-context="Content/Applications/Button.Label/Verb">Create application</translate>
|
||||||
</button>
|
</button>
|
||||||
|
@ -173,13 +173,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.parent.checkbox {
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
.child.checkbox {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -16,15 +16,15 @@
|
||||||
<form v-else-if="application && !code" :class="['ui', {loading: isLoading}, 'form']" @submit.prevent="submit">
|
<form v-else-if="application && !code" :class="['ui', {loading: isLoading}, 'form']" @submit.prevent="submit">
|
||||||
<h3><translate translate-context="Content/Auth/Title" :translate-params="{app: application.name}">%{ app } wants to access your Funkwhale account</translate></h3>
|
<h3><translate translate-context="Content/Auth/Title" :translate-params="{app: application.name}">%{ app } wants to access your Funkwhale account</translate></h3>
|
||||||
|
|
||||||
<h4 v-for="topic in topicScopes" class="ui header">
|
<h4 v-for="topic in topicScopes" class="ui header vertical-align">
|
||||||
<span v-if="topic.write && !topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'label']">
|
<span v-if="topic.write && !topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']">
|
||||||
<i class="pencil icon"></i>
|
<i class="pencil icon"></i>
|
||||||
<translate translate-context="Content/Auth/Label/Noun">Write-only</translate>
|
<translate translate-context="Content/Auth/Label/Noun">Write-only</translate>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="!topic.write && topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'label']">
|
<span v-else-if="!topic.write && topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']">
|
||||||
<translate translate-context="Content/Auth/Label/Noun">Read-only</translate>
|
<translate translate-context="Content/Auth/Label/Noun">Read-only</translate>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="topic.write && topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'label']">
|
<span v-else-if="topic.write && topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']">
|
||||||
<i class="pencil icon"></i>
|
<i class="pencil icon"></i>
|
||||||
<translate translate-context="Content/Auth/Label/Noun">Full access</translate>
|
<translate translate-context="Content/Auth/Label/Noun">Full access</translate>
|
||||||
</span>
|
</span>
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button class="ui green labeled icon button" type="submit">
|
<button class="ui success labeled icon button" type="submit">
|
||||||
<i class="lock open icon"></i>
|
<i class="lock open icon"></i>
|
||||||
<translate translate-context="Content/Signup/Button.Label/Verb" :translate-params="{app: application.name}">Authorize %{ app }</translate>
|
<translate translate-context="Content/Signup/Button.Label/Verb" :translate-params="{app: application.name}">Authorize %{ app }</translate>
|
||||||
</button>
|
</button>
|
||||||
|
@ -189,13 +189,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.ui.header .content {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.ui.header > .ui.label {
|
|
||||||
margin-top: 0.3em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ import PasswordInput from "@/components/forms/PasswordInput"
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
next: { type: String, default: "/library" },
|
next: { type: String, default: "/library" },
|
||||||
buttonClasses: { type: String, default: "green" },
|
buttonClasses: { type: String, default: "success" },
|
||||||
showSignup: { type: Boolean, default: true},
|
showSignup: { type: Boolean, default: true},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -117,7 +117,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -23,7 +23,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
<password-input required v-model="new_password" />
|
<password-input required v-model="new_password" />
|
||||||
</div>
|
</div>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
:class="['ui', {'loading': isLoading}, 'yellow', 'button']"
|
:class="['ui', {'loading': isLoading}, 'warning', 'button']"
|
||||||
:action="submitPassword">
|
:action="submitPassword">
|
||||||
<translate translate-context="Content/Settings/Button.Label">Change password</translate>
|
<translate translate-context="Content/Settings/Button.Label">Change password</translate>
|
||||||
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Change your password?</translate></p>
|
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Change your password?</translate></p>
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
class="ui tiny basic red button"
|
class="ui tiny basic danger button"
|
||||||
@confirm="revokeApp(app.client_id)">
|
@confirm="revokeApp(app.client_id)">
|
||||||
<translate translate-context="*/*/*/Verb">Revoke</translate>
|
<translate translate-context="*/*/*/Verb">Revoke</translate>
|
||||||
<p slot="modal-header" v-translate="{application: app.name}" translate-context="Popup/Settings/Title">Revoke access for application "%{ application }"?</p>
|
<p slot="modal-header" v-translate="{application: app.name}" translate-context="Popup/Settings/Title">Revoke access for application "%{ application }"?</p>
|
||||||
|
@ -207,7 +207,7 @@
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p><translate translate-context="Content/Settings/Paragraph">This is the list of applications that you have created.</translate></p>
|
<p><translate translate-context="Content/Settings/Paragraph">This is the list of applications that you have created.</translate></p>
|
||||||
<router-link class="ui basic green button" :to="{name: 'settings.applications.new'}">
|
<router-link class="ui basic success button" :to="{name: 'settings.applications.new'}">
|
||||||
<translate translate-context="Content/Settings/Button.Label">Create a new application</translate>
|
<translate translate-context="Content/Settings/Button.Label">Create a new application</translate>
|
||||||
</router-link>
|
</router-link>
|
||||||
<table v-if="ownedApps.length > 0" class="ui compact very basic unstackable table">
|
<table v-if="ownedApps.length > 0" class="ui compact very basic unstackable table">
|
||||||
|
@ -233,11 +233,11 @@
|
||||||
<human-date :date="app.created" />
|
<human-date :date="app.created" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<router-link class="ui basic tiny green button" :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
|
<router-link class="ui basic tiny success button" :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
|
||||||
<translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
|
<translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
|
||||||
</router-link>
|
</router-link>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
class="ui tiny basic red button"
|
class="ui tiny basic danger button"
|
||||||
@confirm="deleteApp(app.client_id)">
|
@confirm="deleteApp(app.client_id)">
|
||||||
<translate translate-context="*/*/*/Verb">Delete</translate>
|
<translate translate-context="*/*/*/Verb">Delete</translate>
|
||||||
<p slot="modal-header" v-translate="{application: app.name}" translate-context="Popup/Settings/Title">Delete application "%{ application }"?</p>
|
<p slot="modal-header" v-translate="{application: app.name}" translate-context="Popup/Settings/Title">Delete application "%{ application }"?</p>
|
||||||
|
@ -283,7 +283,7 @@
|
||||||
<password-input required v-model="password" />
|
<password-input required v-model="password" />
|
||||||
</div>
|
</div>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
:class="['ui', {'loading': isDeletingAccount}, {disabled: !password}, 'red', 'button']"
|
:class="['ui', {'loading': isDeletingAccount}, {disabled: !password}, 'danger', 'button']"
|
||||||
:action="deleteAccount">
|
:action="deleteAccount">
|
||||||
<translate translate-context="*/*/Button.Label">Delete my account…</translate>
|
<translate translate-context="*/*/Button.Label">Delete my account…</translate>
|
||||||
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Do you want to delete your account?</translate></p>
|
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Do you want to delete your account?</translate></p>
|
||||||
|
@ -534,7 +534,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<h2><translate translate-context="Content/Login/Title/Verb">Log in to your Funkwhale account</translate></h2>
|
<h2><translate translate-context="Content/Login/Title/Verb">Log in to your Funkwhale account</translate></h2>
|
||||||
<login-form button-classes="basic green" :show-signup="false"></login-form>
|
<login-form button-classes="basic success" :show-signup="false"></login-form>
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form
|
||||||
v-else
|
v-else
|
||||||
|
@ -93,7 +93,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
defaultInvitation: { type: String, required: false, default: null },
|
defaultInvitation: { type: String, required: false, default: null },
|
||||||
next: { type: String, default: "/" },
|
next: { type: String, default: "/" },
|
||||||
buttonClasses: { type: String, default: "green" },
|
buttonClasses: { type: String, default: "success" },
|
||||||
customization: { type: Object, default: null},
|
customization: { type: Object, default: null},
|
||||||
fetchDescriptionHtml: { type: Boolean, default: false},
|
fetchDescriptionHtml: { type: Boolean, default: false},
|
||||||
fetchDescriptionHtml: { type: Boolean, default: false},
|
fetchDescriptionHtml: { type: Boolean, default: false},
|
||||||
|
@ -176,7 +176,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</div>
|
</div>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="token"
|
v-if="token"
|
||||||
:class="['ui', {'loading': isLoading}, 'grey', 'button']"
|
:class="['ui', {'loading': isLoading}, 'button']"
|
||||||
:action="requestNewToken">
|
:action="requestNewToken">
|
||||||
<translate translate-context="*/Settings/Button.Label/Verb">Request a new password</translate>
|
<translate translate-context="*/Settings/Button.Label/Verb">Request a new password</translate>
|
||||||
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Request a new Subsonic API password?</translate></p>
|
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Request a new Subsonic API password?</translate></p>
|
||||||
|
@ -42,12 +42,12 @@
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
color="grey"
|
color=""
|
||||||
:class="['ui', {'loading': isLoading}, 'button']"
|
:class="['ui', {'loading': isLoading}, 'button']"
|
||||||
@click="requestNewToken"><translate translate-context="Content/Settings/Button.Label/Verb">Request a password</translate></button>
|
@click="requestNewToken"><translate translate-context="Content/Settings/Button.Label/Verb">Request a password</translate></button>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="token"
|
v-if="token"
|
||||||
:class="['ui', {'loading': isLoading}, 'yellow', 'button']"
|
:class="['ui', {'loading': isLoading}, 'warning', 'button']"
|
||||||
:action="disable">
|
:action="disable">
|
||||||
<translate translate-context="Content/Settings/Button.Label/Verb">Disable Subsonic access</translate>
|
<translate translate-context="Content/Settings/Button.Label/Verb">Disable Subsonic access</translate>
|
||||||
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Disable Subsonic API access?</translate></p>
|
<p slot="modal-header"><translate translate-context="Popup/Settings/Title">Disable Subsonic API access?</translate></p>
|
||||||
|
@ -135,7 +135,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -37,7 +37,3 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<form @submit.stop.prevent :class="['ui', {loading: isLoadingStep1}, 'form']">
|
<form @submit.stop.prevent :class="['ui', {loading: isLoadingStep1}, 'form component-file-upload']">
|
||||||
<div v-if="errors.length > 0" class="ui negative message">
|
<div v-if="errors.length > 0" class="ui negative message">
|
||||||
<div class="header"><translate translate-context="Content/*/Error message.Title">Error while publishing</translate></div>
|
<div class="header"><translate translate-context="Content/*/Error message.Title">Error while publishing</translate></div>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
<div
|
<div
|
||||||
v-if="file.error"
|
v-if="file.error"
|
||||||
@click.stop.prevent="selectedUploadId = file.response.uuid"
|
@click.stop.prevent="selectedUploadId = file.response.uuid"
|
||||||
class="ui basic red icon label"
|
class="ui basic danger icon label"
|
||||||
:title="file.error">
|
:title="file.error">
|
||||||
<i class="warning sign icon"></i>
|
<i class="warning sign icon"></i>
|
||||||
</div>
|
</div>
|
||||||
|
@ -402,9 +402,9 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
d.icon = "user"
|
d.icon = "user"
|
||||||
if (c.artist.content_category === 'podcast') {
|
if (c.artist.content_category === 'podcast') {
|
||||||
d.iconClass = "bordered grey icon"
|
d.iconClass = "bordered icon"
|
||||||
} else {
|
} else {
|
||||||
d.iconClass = "circular grey icon"
|
d.iconClass = "circular icon"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<span class="feedback" v-if="isLoading || isDone">
|
<span class="feedback" v-if="isLoading || isDone">
|
||||||
<span v-if="isLoading" :class="['ui', 'active', size, 'inline', 'loader']"></span>
|
<span v-if="isLoading" :class="['ui', 'active', size, 'inline', 'loader']"></span>
|
||||||
<i v-if="isDone" :class="['green', size, 'check', 'icon']"></i>
|
<i v-if="isDone" :class="['success', size, 'check', 'icon']"></i>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper component-action-table">
|
||||||
<table class="ui compact very basic unstackable table">
|
<table class="ui compact very basic unstackable table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="selectAll || currentAction.isDangerous" :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
|
v-if="selectAll || currentAction.isDangerous" :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
|
||||||
:confirm-color="currentAction.confirmColor || 'green'"
|
:confirm-color="currentAction.confirmColor || 'success'"
|
||||||
@confirm="launchAction">
|
@confirm="launchAction">
|
||||||
<translate translate-context="Content/*/Button.Label/Short, Verb">Go</translate>
|
<translate translate-context="Content/*/Button.Label/Short, Verb">Go</translate>
|
||||||
<p slot="modal-header">
|
<p slot="modal-header">
|
||||||
|
@ -300,11 +300,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
|
||||||
.count.field {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
.ui.form .inline.fields {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -20,10 +20,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
|
||||||
.ui.circular.avatar {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
font-size: 1em !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui bottom attached segment">
|
<div class="ui bottom attached segment">
|
||||||
<span :class="['right', 'floated', {'ui red text': remainingChars < 0}]" v-if="charLimit">
|
<span :class="['right', 'floated', {'ui danger text': remainingChars < 0}]" v-if="charLimit">
|
||||||
{{ remainingChars }}
|
{{ remainingChars }}
|
||||||
</span>
|
</span>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="ui fluid action input">
|
<div class="ui fluid action input component-copy-input">
|
||||||
<p class="message" v-if="copied">
|
<p class="message" v-if="copied">
|
||||||
<translate translate-context="Content/*/Paragraph">Text copied to clipboard!</translate>
|
<translate translate-context="Content/*/Paragraph">Text copied to clipboard!</translate>
|
||||||
</p>
|
</p>
|
||||||
|
@ -39,14 +39,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
|
||||||
.message {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: -3em;
|
|
||||||
padding: 0.3em;
|
|
||||||
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
|
|
||||||
background-color: white;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
action: {type: Function, required: false},
|
action: {type: Function, required: false},
|
||||||
disabled: {type: Boolean, default: false},
|
disabled: {type: Boolean, default: false},
|
||||||
confirmColor: {type: String, default: "red", required: false}
|
confirmColor: {type: String, default: "danger", required: false}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Modal
|
Modal
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="ui small placeholder segment">
|
<div class="ui small placeholder segment component-placeholder component-empty-state">
|
||||||
<div class="ui header">
|
<div class="ui header">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
|
@ -28,13 +28,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.ui.small.placeholder.segment {
|
|
||||||
min-height: auto;
|
|
||||||
}
|
|
||||||
.ui.header .content {
|
|
||||||
text-align: center;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<span>
|
<span class="component-user-link">
|
||||||
<template v-if="avatar">
|
<template v-if="avatar">
|
||||||
<img
|
<img
|
||||||
class="ui tiny circular avatar"
|
class="ui tiny circular avatar"
|
||||||
|
@ -32,9 +32,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
|
||||||
.tiny.circular.avatar {
|
|
||||||
width: 1.7em;
|
|
||||||
height: 1.7em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
translate-context="Content/Home/Placeholder"
|
translate-context="Content/Home/Placeholder"
|
||||||
>No tracks have been added to your favorites yet</translate>
|
>No tracks have been added to your favorites yet</translate>
|
||||||
</div>
|
</div>
|
||||||
<router-link :to="'/library'" class="ui green labeled icon button">
|
<router-link :to="'/library'" class="ui success labeled icon button">
|
||||||
<i class="headphones icon"></i>
|
<i class="headphones icon"></i>
|
||||||
<translate translate-context="Content/*/Verb">Browse the library</translate>
|
<translate translate-context="Content/*/Verb">Browse the library</translate>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -178,7 +178,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -36,7 +36,3 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<div role="button" class="ui basic cancel button">
|
<div role="button" class="ui basic cancel button">
|
||||||
<translate translate-context="*/*/Button.Label/Verb">Close</translate>
|
<translate translate-context="*/*/Button.Label/Verb">Close</translate>
|
||||||
</div>
|
</div>
|
||||||
<div role="button" @click="showModal = false; $emit('refresh')" class="ui confirm green button" v-if="fetch && fetch.status === 'finished'">
|
<div role="button" @click="showModal = false; $emit('refresh')" class="ui confirm success button" v-if="fetch && fetch.status === 'finished'">
|
||||||
<translate translate-context="*/*/Button.Label/Verb">Close and reload page</translate>
|
<translate translate-context="*/*/Button.Label/Verb">Close and reload page</translate>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<translate v-else translate-context="*/*/*" :translate-params="{count: totalTracks}" :translate-n="totalTracks" translate-plural="%{ count } tracks">%{ count } track</translate>
|
<translate v-else translate-context="*/*/*" :translate-params="{count: totalTracks}" :translate-n="totalTracks" translate-plural="%{ count } tracks">%{ count } track</translate>
|
||||||
</template>
|
</template>
|
||||||
<div class="ui small hidden divider"></div>
|
<div class="ui small hidden divider"></div>
|
||||||
<play-button class="orange" :tracks="object.tracks"></play-button>
|
<play-button class="vibrant" :tracks="object.tracks"></play-button>
|
||||||
<div class="ui hidden horizontal divider"></div>
|
<div class="ui hidden horizontal divider"></div>
|
||||||
<album-dropdown
|
<album-dropdown
|
||||||
:object="object"
|
:object="object"
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
</template>
|
</template>
|
||||||
<human-duration v-if="totalDuration > 0" :duration="totalDuration"></human-duration>
|
<human-duration v-if="totalDuration > 0" :duration="totalDuration"></human-duration>
|
||||||
<div class="ui small hidden divider"></div>
|
<div class="ui small hidden divider"></div>
|
||||||
<play-button class="orange" :tracks="object.tracks"></play-button>
|
<play-button class="vibrant" :tracks="object.tracks"></play-button>
|
||||||
<div class="ui horizontal hidden divider"></div>
|
<div class="ui horizontal hidden divider"></div>
|
||||||
<album-dropdown
|
<album-dropdown
|
||||||
:object="object"
|
:object="object"
|
||||||
|
|
|
@ -58,7 +58,3 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
item-selector=".column"
|
item-selector=".column"
|
||||||
percent-position="true"
|
percent-position="true"
|
||||||
stagger="0"
|
stagger="0"
|
||||||
class="ui stackable three column doubling grid">
|
class="">
|
||||||
<div
|
<div
|
||||||
v-if="result.results.length > 0"
|
v-if="result.results.length > 0"
|
||||||
class="ui app-cards cards">
|
class="ui app-cards cards">
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.authenticated"
|
v-if="$store.state.auth.authenticated"
|
||||||
:to="{name: 'content.index'}"
|
:to="{name: 'content.index'}"
|
||||||
class="ui green button labeled icon">
|
class="ui success button labeled icon">
|
||||||
<i class="upload icon"></i>
|
<i class="upload icon"></i>
|
||||||
<translate translate-context="Content/*/Verb">
|
<translate translate-context="Content/*/Verb">
|
||||||
Add some music
|
Add some music
|
||||||
|
@ -223,7 +223,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<play-button :is-playable="isPlayable" class="orange" :artist="object">
|
<play-button :is-playable="isPlayable" class="vibrant" :artist="object">
|
||||||
<translate translate-context="Content/Artist/Button.Label/Verb">Play all albums</translate>
|
<translate translate-context="Content/Artist/Button.Label/Verb">Play all albums</translate>
|
||||||
</play-button>
|
</play-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -95,7 +95,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.authenticated"
|
v-if="$store.state.auth.authenticated"
|
||||||
:to="{name: 'content.index'}"
|
:to="{name: 'content.index'}"
|
||||||
class="ui green button labeled icon">
|
class="ui success button labeled icon">
|
||||||
<i class="upload icon"></i>
|
<i class="upload icon"></i>
|
||||||
<translate translate-context="Content/*/Verb">
|
<translate translate-context="Content/*/Verb">
|
||||||
Add some music
|
Add some music
|
||||||
|
@ -214,24 +214,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "../../style/vendor/media";
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ui.cards {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.three.cards .card {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
@include media(">tablet") {
|
|
||||||
.ui.three.cards .card {
|
|
||||||
width: 25em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -18,19 +18,19 @@
|
||||||
|
|
||||||
<span class="right floated">
|
<span class="right floated">
|
||||||
<span v-if="obj.is_approved && obj.is_applied">
|
<span v-if="obj.is_approved && obj.is_applied">
|
||||||
<i class="green check icon"></i>
|
<i class="success check icon"></i>
|
||||||
<translate translate-context="Content/Library/Card/Short">Approved and applied</translate>
|
<translate translate-context="Content/Library/Card/Short">Approved and applied</translate>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="obj.is_approved">
|
<span v-else-if="obj.is_approved">
|
||||||
<i class="green check icon"></i>
|
<i class="success check icon"></i>
|
||||||
<translate translate-context="Content/*/*/Short">Approved</translate>
|
<translate translate-context="Content/*/*/Short">Approved</translate>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="obj.is_approved === null">
|
<span v-else-if="obj.is_approved === null">
|
||||||
<i class="yellow hourglass icon"></i>
|
<i class="warning hourglass icon"></i>
|
||||||
<translate translate-context="Content/Admin/*/Noun">Pending review</translate>
|
<translate translate-context="Content/Admin/*/Noun">Pending review</translate>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="obj.is_approved === false">
|
<span v-else-if="obj.is_approved === false">
|
||||||
<i class="red x icon"></i>
|
<i class="dangerx icon"></i>
|
||||||
<translate translate-context="Content/Library/*/Short">Rejected</translate>
|
<translate translate-context="Content/Library/*/Short">Rejected</translate>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -95,18 +95,18 @@
|
||||||
<button
|
<button
|
||||||
v-if="canApprove && obj.is_approved !== true"
|
v-if="canApprove && obj.is_approved !== true"
|
||||||
@click="approve(true)"
|
@click="approve(true)"
|
||||||
:class="['ui', {loading: isLoading}, 'green', 'basic', 'button']">
|
:class="['ui', {loading: isLoading}, 'success', 'basic', 'button']">
|
||||||
<translate translate-context="Content/*/Button.Label/Verb">Approve</translate>
|
<translate translate-context="Content/*/Button.Label/Verb">Approve</translate>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="canApprove && obj.is_approved === null"
|
v-if="canApprove && obj.is_approved === null"
|
||||||
@click="approve(false)"
|
@click="approve(false)"
|
||||||
:class="['ui', {loading: isLoading}, 'yellow', 'basic', 'button']">
|
:class="['ui', {loading: isLoading}, 'warning', 'basic', 'button']">
|
||||||
<translate translate-context="Content/Library/Button.Label">Reject</translate>
|
<translate translate-context="Content/Library/Button.Label">Reject</translate>
|
||||||
</button>
|
</button>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="canDelete"
|
v-if="canDelete"
|
||||||
:class="['ui', {loading: isLoading}, 'basic red button']"
|
:class="['ui', {loading: isLoading}, 'basic danger button']"
|
||||||
:action="remove">
|
:action="remove">
|
||||||
<translate translate-context="*/*/*/Verb">Delete</translate>
|
<translate translate-context="*/*/*/Verb">Delete</translate>
|
||||||
<p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this suggestion?</translate></p>
|
<p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this suggestion?</translate></p>
|
||||||
|
|
|
@ -123,7 +123,7 @@
|
||||||
>
|
>
|
||||||
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
|
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
|
||||||
</router-link>
|
</router-link>
|
||||||
<button :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']" type="submit" :disabled="isLoading || !mutationPayload">
|
<button :class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']" type="submit" :disabled="isLoading || !mutationPayload">
|
||||||
<translate v-if="canEdit" key="1" translate-context="Content/Library/Button.Label/Verb">Submit and apply edit</translate>
|
<translate v-if="canEdit" key="1" translate-context="Content/Library/Button.Label/Verb">Submit and apply edit</translate>
|
||||||
<translate v-else key="2" translate-context="Content/Library/Button.Label/Verb">Submit suggestion</translate>
|
<translate v-else key="2" translate-context="Content/Library/Button.Label/Verb">Submit suggestion</translate>
|
||||||
</button>
|
</button>
|
||||||
|
@ -256,8 +256,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
|
||||||
.reset.button {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="component-file-upload">
|
||||||
<div class="ui top attached tabular menu">
|
<div class="ui top attached tabular menu">
|
||||||
<a :class="['item', {active: currentTab === 'summary'}]" @click="currentTab = 'summary'"><translate translate-context="Content/Library/Tab.Title/Short">Summary</translate></a>
|
<a :class="['item', {active: currentTab === 'summary'}]" @click="currentTab = 'summary'"><translate translate-context="Content/Library/Tab.Title/Short">Summary</translate></a>
|
||||||
<a :class="['item', {active: currentTab === 'uploads'}]" @click="currentTab = 'uploads'">
|
<a :class="['item', {active: currentTab === 'uploads'}]" @click="currentTab = 'uploads'">
|
||||||
|
@ -7,10 +7,10 @@
|
||||||
<div v-if="files.length === 0" class="ui label">
|
<div v-if="files.length === 0" class="ui label">
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="files.length > uploadedFilesCount + erroredFilesCount" class="ui yellow label">
|
<div v-else-if="files.length > uploadedFilesCount + erroredFilesCount" class="ui warning label">
|
||||||
{{ uploadedFilesCount + erroredFilesCount }}/{{ files.length }}
|
{{ uploadedFilesCount + erroredFilesCount }}/{{ files.length }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else :class="['ui', {'green': erroredFilesCount === 0}, {'red': erroredFilesCount > 0}, 'label']">
|
<div v-else :class="['ui', {'success': erroredFilesCount === 0}, {'danger': erroredFilesCount > 0}, 'label']">
|
||||||
{{ uploadedFilesCount + erroredFilesCount }}/{{ files.length }}
|
{{ uploadedFilesCount + erroredFilesCount }}/{{ files.length }}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -19,10 +19,10 @@
|
||||||
<div v-if="processableFiles === 0" class="ui label">
|
<div v-if="processableFiles === 0" class="ui label">
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="processableFiles > processedFilesCount" class="ui yellow label">
|
<div v-else-if="processableFiles > processedFilesCount" class="ui warning label">
|
||||||
{{ processedFilesCount }}/{{ processableFiles }}
|
{{ processedFilesCount }}/{{ processableFiles }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else :class="['ui', {'green': uploads.errored === 0}, {'red': uploads.errored > 0}, 'label']">
|
<div v-else :class="['ui', {'success': uploads.errored === 0}, {'danger': uploads.errored > 0}, 'label']">
|
||||||
{{ processedFilesCount }}/{{ processableFiles }}
|
{{ processedFilesCount }}/{{ processableFiles }}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -54,12 +54,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="ui green button"><translate translate-context="Content/Library/Button.Label">Proceed</translate></button>
|
<button type="submit" class="ui success button"><translate translate-context="Content/Library/Button.Label">Proceed</translate></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'uploads'}]">
|
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'uploads'}]">
|
||||||
<div :class="['ui', {loading: isLoadingQuota}, 'container']">
|
<div :class="['ui', {loading: isLoadingQuota}, 'container']">
|
||||||
<div :class="['ui', {red: remainingSpace === 0}, {yellow: remainingSpace > 0 && remainingSpace <= 50}, 'small', 'statistic']">
|
<div :class="['ui', {red: remainingSpace === 0}, {warning: remainingSpace > 0 && remainingSpace <= 50}, 'small', 'statistic']">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<translate translate-context="Content/Library/Paragraph">Remaining storage space</translate>
|
<translate translate-context="Content/Library/Paragraph">Remaining storage space</translate>
|
||||||
</div>
|
</div>
|
||||||
|
@ -113,14 +113,14 @@
|
||||||
<td>{{ file.size | humanSize }}</td>
|
<td>{{ file.size | humanSize }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="file.error" class="ui tooltip" :data-tooltip="labels.tooltips[file.error]">
|
<span v-if="file.error" class="ui tooltip" :data-tooltip="labels.tooltips[file.error]">
|
||||||
<span class="ui red icon label">
|
<span class="ui danger icon label">
|
||||||
<i class="question circle outline icon" /> {{ file.error }}
|
<i class="question circle outline icon" /> {{ file.error }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="file.success" class="ui green label">
|
<span v-else-if="file.success" class="ui success label">
|
||||||
<translate translate-context="Content/Library/Table" key="1">Uploaded</translate>
|
<translate translate-context="Content/Library/Table" key="1">Uploaded</translate>
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="file.active" class="ui yellow label">
|
<span v-else-if="file.active" class="ui warning label">
|
||||||
<translate translate-context="Content/Library/Table" key="2">Uploading…</translate>
|
<translate translate-context="Content/Library/Table" key="2">Uploading…</translate>
|
||||||
({{ parseInt(file.progress) }}%)
|
({{ parseInt(file.progress) }}%)
|
||||||
</span>
|
</span>
|
||||||
|
@ -137,7 +137,7 @@
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="!file.success">
|
<template v-else-if="!file.success">
|
||||||
<button class="ui tiny basic red icon right floated button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
|
<button class="ui tiny basic danger icon right floated button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -396,16 +396,3 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.file-uploads.ui.button {
|
|
||||||
display: block;
|
|
||||||
padding: 2em 1em;
|
|
||||||
width: 100%;
|
|
||||||
box-shadow: none;
|
|
||||||
border-style: dashed !important;
|
|
||||||
border: 3px solid rgba(50, 50, 50, 0.5);
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -38,7 +38,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -98,7 +98,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="main library pusher">
|
<div class="main pusher page-library">
|
||||||
<router-view :key="$router.currentRoute.name"></router-view>
|
<router-view :key="$router.currentRoute.name"></router-view>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,35 +21,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style lang="scss">
|
|
||||||
@import "../../style/vendor/media";
|
|
||||||
|
|
||||||
.library {
|
|
||||||
.ui.segment.head {
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
padding: 0;
|
|
||||||
.segment-content {
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2em;
|
|
||||||
@include media(">tablet") {
|
|
||||||
padding: 4em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.with-background {
|
|
||||||
.header {
|
|
||||||
&,
|
|
||||||
.sub {
|
|
||||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.8);
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.segment-content {
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<h3 class="ui header">
|
<h3 class="ui header">
|
||||||
<translate translate-context="Content/Radio/Title">User radios</translate>
|
<translate translate-context="Content/Radio/Title">User radios</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<router-link class="ui green basic button" to="/library/radios/build" exact>
|
<router-link class="ui success basic button" to="/library/radios/build" exact>
|
||||||
<translate translate-context="Content/Radio/Button.Label/Verb">Create your own radio</translate>
|
<translate translate-context="Content/Radio/Button.Label/Verb">Create your own radio</translate>
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="ui hidden divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.authenticated"
|
v-if="$store.state.auth.authenticated"
|
||||||
:to="{name: 'library.radios.build'}"
|
:to="{name: 'library.radios.build'}"
|
||||||
class="ui green button labeled icon">
|
class="ui success button labeled icon">
|
||||||
<i class="rss icon"></i>
|
<i class="rss icon"></i>
|
||||||
<translate translate-context="Content/*/Verb">
|
<translate translate-context="Content/*/Verb">
|
||||||
Create a radio
|
Create a radio
|
||||||
|
@ -215,7 +215,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<main v-title="labels.title">
|
<main v-title="labels.title">
|
||||||
<section class="ui vertical stripe segment">
|
<section class="ui vertical stripe segment">
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<span class="ui circular huge hashtag label">
|
<span class="ui circular huge hashtag label component-label">
|
||||||
{{ labels.title }}
|
{{ labels.title }}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
@ -83,11 +83,3 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
.ui.circular.label {
|
|
||||||
padding-left: 1em !important;
|
|
||||||
padding-right: 1em !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -82,11 +82,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
.ui.form .field > .selection.dropdown {
|
|
||||||
min-width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="eight wide right aligned column button-group">
|
<div class="eight wide right aligned column button-group">
|
||||||
<play-button class="orange" :track="track">
|
<play-button class="vibrant" :track="track">
|
||||||
<translate translate-context="*/Queue/Button.Label/Short, Verb">Play</translate>
|
<translate translate-context="*/Queue/Button.Label/Short, Verb">Play</translate>
|
||||||
</play-button>
|
</play-button>
|
||||||
|
|
||||||
|
|
|
@ -232,11 +232,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.table.center.aligned {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<label for="public"><translate translate-context="Content/Radio/Checkbox.Label/Verb">Display publicly</translate></label>
|
<label for="public"><translate translate-context="Content/Radio/Checkbox.Label/Verb">Display publicly</translate></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui hidden divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
<button :disabled="!canSave" @click="save" :class="['ui', 'green', {loading: isLoading}, 'button']">
|
<button :disabled="!canSave" @click="save" :class="['ui', 'success', {loading: isLoading}, 'button']">
|
||||||
<translate translate-context="Content/*/Button.Label/Verb">Save</translate>
|
<translate translate-context="Content/*/Button.Label/Verb">Save</translate>
|
||||||
</button>
|
</button>
|
||||||
<radio-button v-if="id" type="custom" :custom-radio-id="id"></radio-button>
|
<radio-button v-if="id" type="custom" :custom-radio-id="id"></radio-button>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<span
|
<span
|
||||||
@click="showCandidadesModal = !showCandidadesModal"
|
@click="showCandidadesModal = !showCandidadesModal"
|
||||||
v-if="checkResult"
|
v-if="checkResult"
|
||||||
:class="['ui', {'green': checkResult.candidates.count > 10}, 'label']">
|
:class="['ui', {'success': checkResult.candidates.count > 10}, 'label']">
|
||||||
{{ checkResult.candidates.count }} tracks matching filter
|
{{ checkResult.candidates.count }} tracks matching filter
|
||||||
</span>
|
</span>
|
||||||
<modal v-if="checkResult" :show.sync="showCandidadesModal">
|
<modal v-if="checkResult" :show.sync="showCandidadesModal">
|
||||||
|
@ -49,14 +49,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<div class="ui basic black deny button">
|
<div class="ui basic deny button">
|
||||||
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
|
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button @click="$emit('delete', index)" class="ui basic red button"><translate translate-context="Content/Radio/Button.Label/Verb">Remove</translate></button>
|
<button @click="$emit('delete', index)" class="ui basic danger button"><translate translate-context="Content/Radio/Button.Label/Verb">Remove</translate></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -200,7 +200,7 @@ export default {
|
||||||
// confirmationMessage: confirmationMessage,
|
// confirmationMessage: confirmationMessage,
|
||||||
// isDangerous: true,
|
// isDangerous: true,
|
||||||
// allowAll: false,
|
// allowAll: false,
|
||||||
// confirmColor: 'red',
|
// confirmColor: 'danger',
|
||||||
// },
|
// },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ export default {
|
||||||
confirmationMessage: confirmationMessage,
|
confirmationMessage: confirmationMessage,
|
||||||
isDangerous: true,
|
isDangerous: true,
|
||||||
allowAll: false,
|
allowAll: false,
|
||||||
confirmColor: 'red',
|
confirmColor: 'danger',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ export default {
|
||||||
confirmationMessage: confirmationMessage,
|
confirmationMessage: confirmationMessage,
|
||||||
isDangerous: true,
|
isDangerous: true,
|
||||||
allowAll: false,
|
allowAll: false,
|
||||||
confirmColor: 'red',
|
confirmColor: 'danger',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ export default {
|
||||||
confirmationMessage: confirmationMessage,
|
confirmationMessage: confirmationMessage,
|
||||||
isDangerous: true,
|
isDangerous: true,
|
||||||
allowAll: false,
|
allowAll: false,
|
||||||
confirmColor: 'red',
|
confirmColor: 'danger',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,7 @@ export default {
|
||||||
confirmationMessage: confirmationMessage,
|
confirmationMessage: confirmationMessage,
|
||||||
isDangerous: true,
|
isDangerous: true,
|
||||||
allowAll: false,
|
allowAll: false,
|
||||||
confirmColor: 'red',
|
confirmColor: 'danger',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ export default {
|
||||||
confirmationMessage: confirmationMessage,
|
confirmationMessage: confirmationMessage,
|
||||||
isDangerous: true,
|
isDangerous: true,
|
||||||
allowAll: false,
|
allowAll: false,
|
||||||
confirmColor: 'red',
|
confirmColor: 'danger',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ export default {
|
||||||
confirmationMessage: confirmationMessage,
|
confirmationMessage: confirmationMessage,
|
||||||
isDangerous: true,
|
isDangerous: true,
|
||||||
allowAll: false,
|
allowAll: false,
|
||||||
confirmColor: 'red',
|
confirmColor: 'danger',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<td>
|
<td>
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.name }}">
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.name }}">
|
||||||
{{ scope.obj.name }}
|
{{ scope.obj.name }}
|
||||||
<i v-if="allowListEnabled && scope.obj.allowed" class="green check icon" :title="labels.allowListTitle"></i>
|
<i v-if="allowListEnabled && scope.obj.allowed" class="success check icon" :title="labels.allowListTitle"></i>
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -67,6 +67,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -54,11 +54,11 @@
|
||||||
<button @click.prevent="$emit('cancel')" class="ui basic left floated button">
|
<button @click.prevent="$emit('cancel')" class="ui basic left floated button">
|
||||||
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
|
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
|
||||||
</button>
|
</button>
|
||||||
<button :class="['ui', 'right', 'floated', 'green', {'disabled loading': isLoading}, 'button']" :disabled="isLoading">
|
<button :class="['ui', 'right', 'floated', 'success', {'disabled loading': isLoading}, 'button']" :disabled="isLoading">
|
||||||
<translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-if="object" key="1">Update</translate>
|
<translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-if="object" key="1">Update</translate>
|
||||||
<translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-else key="2">Create</translate>
|
<translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-else key="2">Create</translate>
|
||||||
</button>
|
</button>
|
||||||
<dangerous-button v-if="object" class="ui right floated basic red button" @confirm="remove">
|
<dangerous-button v-if="object" class="ui right floated basic danger button" @confirm="remove">
|
||||||
<translate translate-context="*/*/*/Verb">Delete</translate>
|
<translate translate-context="*/*/*/Verb">Delete</translate>
|
||||||
<p slot="modal-header">
|
<p slot="modal-header">
|
||||||
<translate translate-context="Popup/Moderation/Title">Delete this moderation rule?</translate>
|
<translate translate-context="Popup/Moderation/Title">Delete this moderation rule?</translate>
|
||||||
|
@ -200,15 +200,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.ui.placeholder.segment .field,
|
|
||||||
.ui.placeholder.segment textarea,
|
|
||||||
.ui.placeholder.segment > .ui.input,
|
|
||||||
.ui.placeholder.segment .button {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.segment .right.floated.button {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
:class="['ui', {loading: isLoading}, 'basic borderless mini grey button']"
|
:class="['ui', {loading: isLoading}, 'basic borderless mini button']"
|
||||||
@confirm="remove(note)">
|
@confirm="remove(note)">
|
||||||
<i class="trash icon"></i>
|
<i class="trash icon"></i>
|
||||||
<translate translate-context="*/*/*/Verb">Delete</translate>
|
<translate translate-context="*/*/*/Verb">Delete</translate>
|
||||||
|
|
|
@ -59,12 +59,12 @@
|
||||||
</td>
|
</td>
|
||||||
<td v-if="obj.is_handled">
|
<td v-if="obj.is_handled">
|
||||||
<span v-if="obj.is_handled">
|
<span v-if="obj.is_handled">
|
||||||
<i class="green check icon"></i>
|
<i class="success check icon"></i>
|
||||||
<translate translate-context="Content/*/*/Short">Resolved</translate>
|
<translate translate-context="Content/*/*/Short">Resolved</translate>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td v-else>
|
<td v-else>
|
||||||
<i class="red x icon"></i>
|
<i class="dangerx icon"></i>
|
||||||
<translate translate-context="Content/*/*/Short">Unresolved</translate>
|
<translate translate-context="Content/*/*/Short">Unresolved</translate>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -215,14 +215,14 @@
|
||||||
v-if="obj.is_handled === false"
|
v-if="obj.is_handled === false"
|
||||||
@click="resolve(true)"
|
@click="resolve(true)"
|
||||||
:class="['ui', {loading: isLoading}, 'button']">
|
:class="['ui', {loading: isLoading}, 'button']">
|
||||||
<i class="green check icon"></i>
|
<i class="success check icon"></i>
|
||||||
<translate translate-context="Content/*/Button.Label/Verb">Resolve</translate>
|
<translate translate-context="Content/*/Button.Label/Verb">Resolve</translate>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="obj.is_handled === true"
|
v-if="obj.is_handled === true"
|
||||||
@click="resolve(false)"
|
@click="resolve(false)"
|
||||||
:class="['ui', {loading: isLoading}, 'button']">
|
:class="['ui', {loading: isLoading}, 'button']">
|
||||||
<i class="yellow redo icon"></i>
|
<i class="warning redo icon"></i>
|
||||||
<translate translate-context="Content/*/Button.Label">Unresolve</translate>
|
<translate translate-context="Content/*/Button.Label">Unresolve</translate>
|
||||||
</button>
|
</button>
|
||||||
<template v-for="action in actions">
|
<template v-for="action in actions">
|
||||||
|
@ -357,7 +357,7 @@ export default {
|
||||||
modalContent: this.$pgettext('Content/Moderation/Popup,Paragraph', 'This will delete the object associated with this report and mark the report as resolved. The deletion is irreversible.'),
|
modalContent: this.$pgettext('Content/Moderation/Popup,Paragraph', 'This will delete the object associated with this report and mark the report as resolved. The deletion is irreversible.'),
|
||||||
modalConfirmLabel: this.$pgettext('*/*/*/Verb', 'Delete'),
|
modalConfirmLabel: this.$pgettext('*/*/*/Verb', 'Delete'),
|
||||||
icon: 'x',
|
icon: 'x',
|
||||||
iconColor: 'red',
|
iconColor: 'danger',
|
||||||
show: (obj) => { return !!obj.target },
|
show: (obj) => { return !!obj.target },
|
||||||
dangerous: true,
|
dangerous: true,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
|
|
|
@ -41,15 +41,15 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<template v-if="obj.status === 'pending'">
|
<template v-if="obj.status === 'pending'">
|
||||||
<i class="yellow hourglass icon"></i>
|
<i class="warning hourglass icon"></i>
|
||||||
<translate translate-context="Content/Library/*/Short">Pending</translate>
|
<translate translate-context="Content/Library/*/Short">Pending</translate>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="obj.status === 'refused'">
|
<template v-else-if="obj.status === 'refused'">
|
||||||
<i class="red x icon"></i>
|
<i class="dangerx icon"></i>
|
||||||
<translate translate-context="Content/*/*/Short">Refused</translate>
|
<translate translate-context="Content/*/*/Short">Refused</translate>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="obj.status === 'approved'">
|
<template v-else-if="obj.status === 'approved'">
|
||||||
<i class="green check icon"></i>
|
<i class="success check icon"></i>
|
||||||
<translate translate-context="Content/*/*/Short">Approved</translate>
|
<translate translate-context="Content/*/*/Short">Approved</translate>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
|
@ -118,14 +118,14 @@
|
||||||
v-if="obj.status === 'pending' || obj.status === 'refused'"
|
v-if="obj.status === 'pending' || obj.status === 'refused'"
|
||||||
@click="approve(true)"
|
@click="approve(true)"
|
||||||
:class="['ui', {loading: isLoading}, 'button']">
|
:class="['ui', {loading: isLoading}, 'button']">
|
||||||
<i class="green check icon"></i>
|
<i class="success check icon"></i>
|
||||||
<translate translate-context="Content/*/Button.Label/Verb">Approve</translate>
|
<translate translate-context="Content/*/Button.Label/Verb">Approve</translate>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="obj.status === 'pending'"
|
v-if="obj.status === 'pending'"
|
||||||
@click="approve(false)"
|
@click="approve(false)"
|
||||||
:class="['ui', {loading: isLoading}, 'button']">
|
:class="['ui', {loading: isLoading}, 'button']">
|
||||||
<i class="red x icon"></i>
|
<i class="dangerx icon"></i>
|
||||||
<translate translate-context="Content/*/Button.Label">Refuse</translate>
|
<translate translate-context="Content/*/Button.Label">Refuse</translate>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -82,6 +82,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
<router-link :to="{name: 'manage.users.users.detail', params: {id: scope.obj.id }}">{{ scope.obj.owner.username }}</router-link>
|
<router-link :to="{name: 'manage.users.users.detail', params: {id: scope.obj.id }}">{{ scope.obj.owner.username }}</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="scope.obj.users.length > 0" class="ui green basic label"><translate translate-context="Content/Admin/Table">Used</translate></span>
|
<span v-if="scope.obj.users.length > 0" class="ui success basic label"><translate translate-context="Content/Admin/Table">Used</translate></span>
|
||||||
<span v-else-if="moment().isAfter(scope.obj.expiration_date)" class="ui red basic label"><translate translate-context="Content/Admin/Table">Expired</translate></span>
|
<span v-else-if="moment().isAfter(scope.obj.expiration_date)" class="ui danger basic label"><translate translate-context="Content/Admin/Table">Expired</translate></span>
|
||||||
<span v-else class="ui basic label"><translate translate-context="Content/Admin/Table">Not used</translate></span>
|
<span v-else class="ui basic label"><translate translate-context="Content/Admin/Table">Not used</translate></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
<span>{{ scope.obj.email }}</span>
|
<span>{{ scope.obj.email }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="scope.obj.is_active" class="ui basic green label"><translate translate-context="Content/Admin/Table">Active</translate></span>
|
<span v-if="scope.obj.is_active" class="ui basic success label"><translate translate-context="Content/Admin/Table">Active</translate></span>
|
||||||
<span v-else class="ui basic grey label"><translate translate-context="Content/Admin/Table">Inactive</translate></span>
|
<span v-else class="ui basic label"><translate translate-context="Content/Admin/Table">Inactive</translate></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<human-date :date="scope.obj.date_joined"></human-date>
|
<human-date :date="scope.obj.date_joined"></human-date>
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
|
<div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
|
||||||
<div :class="['ui', 'green', {loading: isLoading}, 'button']" @click="hide"><translate translate-context="Popup/*/Button.Label">Hide content</translate></div>
|
<div :class="['ui', 'success', {loading: isLoading}, 'button']" @click="hide"><translate translate-context="Popup/*/Button.Label">Hide content</translate></div>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -102,7 +102,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
<div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
|
<div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
|
||||||
<button
|
<button
|
||||||
v-if="canSubmit"
|
v-if="canSubmit"
|
||||||
:class="['ui', 'green', {loading: isLoading}, 'button']"
|
:class="['ui', 'success', {loading: isLoading}, 'button']"
|
||||||
type="submit" form="report-form">
|
type="submit" form="report-form">
|
||||||
<translate translate-context="Popup/*/Button.Label">Submit report</translate>
|
<translate translate-context="Popup/*/Button.Label">Submit report</translate>
|
||||||
</button>
|
</button>
|
||||||
|
@ -204,7 +204,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
</td>
|
</td>
|
||||||
<td><human-date :date="item.activity.creation_date" /></td>
|
<td><human-date :date="item.activity.creation_date" /></td>
|
||||||
<td class="read collapsing">
|
<td class="read collapsing">
|
||||||
<span @click="markRead(false)" v-if="item.is_read" :title="labels.markUnread">
|
<span @click="markRead(false)" role="button" v-if="item.is_read" :title="labels.markUnread">
|
||||||
<i class="redo icon" />
|
<i class="redo icon" />
|
||||||
</span>
|
</span>
|
||||||
<span @click="markRead(true)" v-else :title="labels.markRead">
|
<span @click="markRead(true)" role="button" v-else :title="labels.markRead">
|
||||||
<i class="check icon" />
|
<i class="check icon" />
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
@ -68,13 +68,13 @@ export default {
|
||||||
if (a.related_object.approved === null) {
|
if (a.related_object.approved === null) {
|
||||||
message = this.labels.libraryPendingFollowMessage
|
message = this.labels.libraryPendingFollowMessage
|
||||||
acceptFollow = {
|
acceptFollow = {
|
||||||
buttonClass: 'green',
|
buttonClass: 'success',
|
||||||
icon: 'check',
|
icon: 'check',
|
||||||
label: this.$pgettext('Content/*/Button.Label/Verb', 'Approve'),
|
label: this.$pgettext('Content/*/Button.Label/Verb', 'Approve'),
|
||||||
handler: () => { self.approveLibraryFollow(a.related_object) }
|
handler: () => { self.approveLibraryFollow(a.related_object) }
|
||||||
},
|
},
|
||||||
rejectFollow = {
|
rejectFollow = {
|
||||||
buttonClass: 'red',
|
buttonClass: 'danger',
|
||||||
icon: 'x',
|
icon: 'x',
|
||||||
label: this.$pgettext('Content/*/Button.Label/Verb', 'Reject'),
|
label: this.$pgettext('Content/*/Button.Label/Verb', 'Reject'),
|
||||||
handler: () => { self.rejectLibraryFollow(a.related_object) }
|
handler: () => { self.rejectLibraryFollow(a.related_object) }
|
||||||
|
@ -146,8 +146,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
|
||||||
.read > span {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
@click="$router.push({name: 'library.playlists.detail', params: {id: playlist.id }})"
|
@click="$router.push({name: 'library.playlists.detail', params: {id: playlist.id }})"
|
||||||
:class="['ui', 'head-image', 'squares']">
|
:class="['ui', 'head-image', 'squares']">
|
||||||
<img v-lazy="url" v-for="(url, idx) in images" :key="idx" />
|
<img v-lazy="url" v-for="(url, idx) in images" :key="idx" />
|
||||||
<play-button :icon-only="true" :is-playable="playlist.is_playable" :button-classes="['ui', 'circular', 'large', 'orange', 'icon', 'button']" :playlist="playlist"></play-button>
|
<play-button :icon-only="true" :is-playable="playlist.is_playable" :button-classes="['ui', 'circular', 'large', 'vibrant', 'icon', 'button']" :playlist="playlist"></play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="extra content">
|
<div class="extra content">
|
||||||
<translate translate-context="*/*/*" :translate-params="{count: playlist.tracks_count}" :translate-n="playlist.tracks_count" translate-plural="%{ count } tracks">%{ count } track</translate>
|
<translate translate-context="*/*/*" :translate-params="{count: playlist.tracks_count}" :translate-n="playlist.tracks_count" translate-plural="%{ count } tracks">%{ count } track</translate>
|
||||||
<play-button class="right floated basic icon" :dropdown-only="true" :is-playable="playlist.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large', 'grey']" :playlist="playlist"></play-button>
|
<play-button class="right floated basic icon" :dropdown-only="true" :is-playable="playlist.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large really discrete']" :playlist="playlist"></play-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -21,7 +21,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue