diff --git a/.css-config-sample/_instance-settings.scss b/.css-config-sample/_instance-settings.scss deleted file mode 100644 index e86c1ce00..000000000 --- a/.css-config-sample/_instance-settings.scss +++ /dev/null @@ -1,3 +0,0 @@ -@charset "utf-8"; - -// Copy this file to bookwyrm/static/css/ and set your instance custom styles. diff --git a/.gitignore b/.gitignore index 92fc85bc0..ec2a08f80 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,8 @@ .env /images/ bookwyrm/static/css/bookwyrm.css -bookwyrm/static/css/_instance-settings.scss +bookwyrm/static/css/themes/ +!bookwyrm/static/css/themes/bookwyrm-*.scss # Testing .coverage diff --git a/README.md b/README.md index 161f91b94..bd7344df9 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Social reading and reviewing, decentralized with ActivityPub - [Set up Bookwyrm](#set-up-bookwyrm) ## Joining BookWyrm -BookWyrm is still a young piece of software, and isn't at the level of stability and feature-richness that you'd find in a production-ready application. But it does what it says on the box! If you'd like to join an instance, you can check out the [instances](https://docs.joinbookwyrm.com/instances.html) list. +BookWyrm is still a young piece of software, and isn't at the level of stability and feature-richness that you'd find in a production-ready application. But it does what it says on the box! If you'd like to join an instance, you can check out the [instances](https://joinbookwyrm.com/instances/) list. You can request an invite by entering your email address at https://bookwyrm.social. diff --git a/bookwyrm/activitypub/person.py b/bookwyrm/activitypub/person.py index 576e7f9a6..61c15a579 100644 --- a/bookwyrm/activitypub/person.py +++ b/bookwyrm/activitypub/person.py @@ -39,4 +39,5 @@ class Person(ActivityObject): bookwyrmUser: bool = False manuallyApprovesFollowers: str = False discoverable: str = False + hideFollows: str = False type: str = "Person" diff --git a/bookwyrm/context_processors.py b/bookwyrm/context_processors.py index 309e84ed1..0047bfce1 100644 --- a/bookwyrm/context_processors.py +++ b/bookwyrm/context_processors.py @@ -8,8 +8,20 @@ def site_settings(request): # pylint: disable=unused-argument if not request.is_secure(): request_protocol = "http://" + site = models.SiteSettings.objects.get() + theme = "css/themes/bookwyrm-light.scss" + if ( + hasattr(request, "user") + and request.user.is_authenticated + and request.user.theme + ): + theme = request.user.theme.path + elif site.default_theme: + theme = site.default_theme.path + return { - "site": models.SiteSettings.objects.get(), + "site": site, + "site_theme": theme, "active_announcements": models.Announcement.active_announcements(), "thumbnail_generation_enabled": settings.ENABLE_THUMBNAIL_GENERATION, "media_full_url": settings.MEDIA_FULL_URL, diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 7ae4e446f..f152ed4ea 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -153,8 +153,10 @@ class EditUserForm(CustomForm): "manually_approves_followers", "default_post_privacy", "discoverable", + "hide_follows", "preferred_timezone", "preferred_language", + "theme", ] help_texts = {f: None for f in fields} widgets = { @@ -454,6 +456,22 @@ class SiteForm(CustomForm): } +class SiteThemeForm(CustomForm): + class Meta: + model = models.SiteSettings + fields = ["default_theme"] + + +class ThemeForm(CustomForm): + class Meta: + model = models.Theme + fields = ["name", "path"] + widgets = { + "name": forms.TextInput(attrs={"aria-describedby": "desc_name"}), + "path": forms.Select(attrs={"aria-describedby": "desc_path"}), + } + + class AnnouncementForm(CustomForm): class Meta: model = models.Announcement diff --git a/bookwyrm/migrations/0142_auto_20220227_1752.py b/bookwyrm/migrations/0142_auto_20220227_1752.py new file mode 100644 index 000000000..2282679da --- /dev/null +++ b/bookwyrm/migrations/0142_auto_20220227_1752.py @@ -0,0 +1,68 @@ +# Generated by Django 3.2.12 on 2022-02-27 17:52 + +from django.db import migrations, models +import django.db.models.deletion + + +def add_default_themes(apps, schema_editor): + """add light and dark themes""" + db_alias = schema_editor.connection.alias + theme_model = apps.get_model("bookwyrm", "Theme") + theme_model.objects.using(db_alias).create( + name="BookWyrm Light", + path="css/themes/bookwyrm-light.scss", + ) + theme_model.objects.using(db_alias).create( + name="BookWyrm Dark", + path="css/themes/bookwyrm-dark.scss", + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0141_alter_report_status"), + ] + + operations = [ + migrations.CreateModel( + name="Theme", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_date", models.DateTimeField(auto_now_add=True)), + ("name", models.CharField(max_length=50, unique=True)), + ("path", models.CharField(max_length=50, unique=True)), + ], + ), + migrations.AddField( + model_name="sitesettings", + name="default_theme", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="bookwyrm.theme", + ), + ), + migrations.AddField( + model_name="user", + name="theme", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="bookwyrm.theme", + ), + ), + migrations.RunPython( + add_default_themes, reverse_code=migrations.RunPython.noop + ), + ] diff --git a/bookwyrm/migrations/0142_user_hide_follows.py b/bookwyrm/migrations/0142_user_hide_follows.py new file mode 100644 index 000000000..f052d7ef5 --- /dev/null +++ b/bookwyrm/migrations/0142_user_hide_follows.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.12 on 2022-02-28 19:44 + +import bookwyrm.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0141_alter_report_status"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="hide_follows", + field=bookwyrm.models.fields.BooleanField(default=False), + ), + ] diff --git a/bookwyrm/migrations/0143_merge_0142_auto_20220227_1752_0142_user_hide_follows.py b/bookwyrm/migrations/0143_merge_0142_auto_20220227_1752_0142_user_hide_follows.py new file mode 100644 index 000000000..b36fa9f9c --- /dev/null +++ b/bookwyrm/migrations/0143_merge_0142_auto_20220227_1752_0142_user_hide_follows.py @@ -0,0 +1,13 @@ +# Generated by Django 3.2.12 on 2022-02-28 21:28 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0142_auto_20220227_1752"), + ("bookwyrm", "0142_user_hide_follows"), + ] + + operations = [] diff --git a/bookwyrm/migrations/0144_alter_announcement_display_type.py b/bookwyrm/migrations/0144_alter_announcement_display_type.py new file mode 100644 index 000000000..246dd5b4e --- /dev/null +++ b/bookwyrm/migrations/0144_alter_announcement_display_type.py @@ -0,0 +1,39 @@ +# Generated by Django 3.2.12 on 2022-03-01 18:46 + +from django.db import migrations, models + + +def remove_white(apps, schema_editor): + """don't hardcode white announcements""" + db_alias = schema_editor.connection.alias + announcement_model = apps.get_model("bookwyrm", "Announcement") + announcement_model.objects.using(db_alias).filter(display_type="white-ter").update( + display_type=None + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0143_merge_0142_auto_20220227_1752_0142_user_hide_follows"), + ] + + operations = [ + migrations.AlterField( + model_name="announcement", + name="display_type", + field=models.CharField( + blank=True, + choices=[ + ("primary-light", "Primary"), + ("success-light", "Success"), + ("link-light", "Link"), + ("warning-light", "Warning"), + ("danger-light", "Danger"), + ], + max_length=20, + null=True, + ), + ), + migrations.RunPython(remove_white, reverse_code=migrations.RunPython.noop), + ] diff --git a/bookwyrm/models/__init__.py b/bookwyrm/models/__init__.py index 440d18d95..a8a84f095 100644 --- a/bookwyrm/models/__init__.py +++ b/bookwyrm/models/__init__.py @@ -26,7 +26,7 @@ from .group import Group, GroupMember, GroupMemberInvitation from .import_job import ImportJob, ImportItem -from .site import SiteSettings, SiteInvite +from .site import SiteSettings, Theme, SiteInvite from .site import PasswordReset, InviteRequest from .announcement import Announcement from .antispam import EmailBlocklist, IPBlocklist, AutoMod, automod_task diff --git a/bookwyrm/models/announcement.py b/bookwyrm/models/announcement.py index cbed38aee..4581dbdae 100644 --- a/bookwyrm/models/announcement.py +++ b/bookwyrm/models/announcement.py @@ -8,7 +8,6 @@ from .base_model import BookWyrmModel DisplayTypes = [ - ("white-ter", _("None")), ("primary-light", _("Primary")), ("success-light", _("Success")), ("link-light", _("Link")), @@ -28,11 +27,7 @@ class Announcement(BookWyrmModel): end_date = models.DateTimeField(blank=True, null=True) active = models.BooleanField(default=True) display_type = models.CharField( - max_length=20, - blank=False, - null=False, - choices=DisplayTypes, - default="white-ter", + max_length=20, choices=DisplayTypes, null=True, blank=True ) @classmethod diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index a40d295bc..c6c53f765 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -24,6 +24,9 @@ class SiteSettings(models.Model): ) instance_description = models.TextField(default="This instance has no description.") instance_short_description = models.CharField(max_length=255, blank=True, null=True) + default_theme = models.ForeignKey( + "Theme", null=True, blank=True, on_delete=models.SET_NULL + ) # admin setup options install_mode = models.BooleanField(default=False) @@ -104,6 +107,18 @@ class SiteSettings(models.Model): super().save(*args, **kwargs) +class Theme(models.Model): + """Theme files""" + + created_date = models.DateTimeField(auto_now_add=True) + name = models.CharField(max_length=50, unique=True) + path = models.CharField(max_length=50, unique=True) + + def __str__(self): + # pylint: disable=invalid-str-returned + return self.name + + class SiteInvite(models.Model): """gives someone access to create an account on the instance""" diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 29b3ba9cc..17fcd4587 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -227,7 +227,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): @classmethod def privacy_filter(cls, viewer, privacy_levels=None): queryset = super().privacy_filter(viewer, privacy_levels=privacy_levels) - return queryset.filter(deleted=False) + return queryset.filter(deleted=False, user__is_active=True) @classmethod def direct_filter(cls, queryset, viewer): diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 6367dcaef..be5c19922 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -136,6 +136,8 @@ class User(OrderedCollectionPageMixin, AbstractUser): updated_date = models.DateTimeField(auto_now=True) last_active_date = models.DateTimeField(default=timezone.now) manually_approves_followers = fields.BooleanField(default=False) + theme = models.ForeignKey("Theme", null=True, blank=True, on_delete=models.SET_NULL) + hide_follows = fields.BooleanField(default=False) # options to turn features on and off show_goal = models.BooleanField(default=True) @@ -478,10 +480,13 @@ def set_remote_server(user_id): get_remote_reviews.delay(user.outbox) -def get_or_create_remote_server(domain): +def get_or_create_remote_server(domain, refresh=False): """get info on a remote server""" + server = FederatedServer() try: - return FederatedServer.objects.get(server_name=domain) + server = FederatedServer.objects.get(server_name=domain) + if not refresh: + return server except FederatedServer.DoesNotExist: pass @@ -496,13 +501,15 @@ def get_or_create_remote_server(domain): application_type = data.get("software", {}).get("name") application_version = data.get("software", {}).get("version") except ConnectorException: + if server.id: + return server application_type = application_version = None - server = FederatedServer.objects.create( - server_name=domain, - application_type=application_type, - application_version=application_version, - ) + server.server_name = domain + server.application_type = application_type + server.application_version = application_version + + server.save() return server diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 7a37499ef..d698a34db 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -11,7 +11,7 @@ from django.utils.translation import gettext_lazy as _ env = Env() env.read_env() DOMAIN = env("DOMAIN") -VERSION = "0.3.1" +VERSION = "0.3.2" RELEASE_API = env( "RELEASE_API", @@ -21,7 +21,7 @@ RELEASE_API = env( PAGE_LENGTH = env("PAGE_LENGTH", 15) DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English") -JS_CACHE = "a60e5a55" +JS_CACHE = "c7154efb" # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") diff --git a/bookwyrm/static/css/bookwyrm.scss b/bookwyrm/static/css/bookwyrm.scss index 6b5e7e6b5..437795457 100644 --- a/bookwyrm/static/css/bookwyrm.scss +++ b/bookwyrm/static/css/bookwyrm.scss @@ -1,7 +1,4 @@ @charset "utf-8"; -@import "instance-settings"; -@import "themes/light.scss"; @import "vendor/bulma/bulma.sass"; -@import "vendor/icons.css"; @import "bookwyrm/all.scss"; diff --git a/bookwyrm/static/css/bookwyrm/_all.scss b/bookwyrm/static/css/bookwyrm/_all.scss index 11d7e403d..f01cec606 100644 --- a/bookwyrm/static/css/bookwyrm/_all.scss +++ b/bookwyrm/static/css/bookwyrm/_all.scss @@ -115,7 +115,7 @@ button .button-invisible-overlay { align-items: center; flex-direction: column; justify-content: center; - background: rgba($scheme-invert, 0.66); + background: $invisible-overlay-background-color; color: white; opacity: 0; transition: opacity 0.2s ease; diff --git a/bookwyrm/static/css/bookwyrm/components/_details.scss b/bookwyrm/static/css/bookwyrm/components/_details.scss index 645de4a1d..5708c9461 100644 --- a/bookwyrm/static/css/bookwyrm/components/_details.scss +++ b/bookwyrm/static/css/bookwyrm/components/_details.scss @@ -53,7 +53,7 @@ details.dropdown .dropdown-menu a:focus-visible { @media only screen and (max-width: 768px) { details.dropdown[open] summary.dropdown-trigger::before { - background-color: rgba($scheme-invert, 0.5); + background-color: $modal-background-background-color; z-index: 30; } diff --git a/bookwyrm/static/css/bookwyrm/components/_toggle.scss b/bookwyrm/static/css/bookwyrm/components/_toggle.scss index c2c07dfb8..74d7f0d92 100644 --- a/bookwyrm/static/css/bookwyrm/components/_toggle.scss +++ b/bookwyrm/static/css/bookwyrm/components/_toggle.scss @@ -3,7 +3,7 @@ .toggle-button[aria-pressed="true"], .toggle-button[aria-pressed="true"]:hover { - background-color: hsl(171deg, 100%, 41%); + background-color: $primary; color: white; } diff --git a/bookwyrm/static/css/themes/bookwyrm-dark.scss b/bookwyrm/static/css/themes/bookwyrm-dark.scss new file mode 100644 index 000000000..466d8026d --- /dev/null +++ b/bookwyrm/static/css/themes/bookwyrm-dark.scss @@ -0,0 +1,84 @@ +@import "../vendor/bulma/sass/utilities/initial-variables.sass"; + +/* Colors + ******************************************************************************/ + +/* states */ +$primary: #005e50; +$primary-light: #1d2b28; +$info: #1f4666; +$success: #246447; +$warning: #8b6c15; +$danger: #872538; +$danger-light: #481922; +$light: #393939; +$red: #ffa1b4; + +/* book cover standins */ +$no-cover-color: #002549; + +/* background colors */ +$scheme-main: rgb(24, 27, 28); +$scheme-invert: #fff; +$scheme-main-bis: rgb(28, 30, 32); +$scheme-main-ter: rgb(32, 34, 36); +$background-body: rgb(24, 27, 28); +$background-secondary: rgb(28, 30, 32); +$background-tertiary: rgb(32, 34, 36); +$modal-background-background-color: rgba($black, 0.8); + +/* highlight colors */ +$primary-highlight: $primary; +$info-highlight: $info; +$success-highlight: $success; + +/* borders */ +$border: #2b3031; +$border-light: #444; +$border-hover: #51595d; + +/* text */ +$text: $grey-lightest; +$text-light: $grey-lighter; +$text-strong: $white-ter; + +/* links */ +$link: #2e7eb9; +$link-background: $background-tertiary; +$link-hover: $white-bis; +$link-hover-border: #51595d; +$link-focus: $white-bis; +$link-active: $white-bis; + +/* bulma overrides */ +$background: $background-secondary; +$menu-item-active-background-color: $link-background; +$navbar-dropdown-item-hover-color: $white; + +/* These element's colors are hardcoded, probably a bug in bulma? */ +@media screen and (min-width: 769px) { + .navbar-dropdown { + box-shadow: 0 8px 8px rgba($black, 0.2) !important; + } +} + +@media screen and (max-width: 768px) { + .navbar-menu { + box-shadow: 0 8px 8px rgba($black, 0.2) !important; + } +} + +/* misc */ +$shadow: 0 0.5em 1em -0.125em rgba($black, 0.2), 0 0px 0 1px rgba($black, 0.02); +$card-header-shadow: 0 0.125em 0.25em rgba($black, 0.1); +$invisible-overlay-background-color: rgba($black, 0.66); +$progress-value-background-color: $border-light; + +/* Fonts + ******************************************************************************/ +$family-primary: $family-sans-serif; +$family-secondary: $family-sans-serif; + + +@import "../bookwyrm.scss"; +@import "../vendor/icons.css"; diff --git a/bookwyrm/static/css/themes/light.scss b/bookwyrm/static/css/themes/bookwyrm-light.scss similarity index 90% rename from bookwyrm/static/css/themes/light.scss rename to bookwyrm/static/css/themes/bookwyrm-light.scss index 339fc2c36..c74d2ee20 100644 --- a/bookwyrm/static/css/themes/light.scss +++ b/bookwyrm/static/css/themes/bookwyrm-light.scss @@ -47,7 +47,13 @@ $link-active: $grey-darker; $background: $background-secondary; $menu-item-active-background-color: $link-background; +/* misc */ +$invisible-overlay-background-color: rgba($scheme-invert, 0.66); + /* Fonts ******************************************************************************/ $family-primary: $family-sans-serif; $family-secondary: $family-sans-serif; + +@import "../bookwyrm.scss"; +@import "../vendor/icons.css"; diff --git a/bookwyrm/static/css/themes/dark.scss b/bookwyrm/static/css/themes/dark.scss deleted file mode 100644 index 8df4ce500..000000000 --- a/bookwyrm/static/css/themes/dark.scss +++ /dev/null @@ -1,55 +0,0 @@ -@import "../vendor/bulma/sass/utilities/derived-variables.sass"; - -/* Colors - ******************************************************************************/ - -/* states */ -$primary: #016a5b; -$info: #1f4666; -$success: #246447; -$warning: #8b6c15; -$danger: #872538; - -/* book cover standins */ -$no-cover-color: #002549; - -/* background colors */ -$scheme-main: $grey-darker; -$scheme-main-bis: $black-ter; -$background-body: $grey-darker; -$background-secondary: $grey-dark; -$background-tertiary: #555; - -/* highlight colors */ -$primary-highlight: $primary; -$info-highlight: $info; -$success-highlight: $success; - -/* borders */ -$border: $grey; -$border-hover: $grey-light; -$border-light: $grey; -$border-light-hover: $grey-light; - -/* text */ -$text: $grey-lightest; -$text-light: $grey-lighter; -$text-strong: $white-ter; - -/* links */ -$link: $white; -$link-background: $background-tertiary; -$link-hover: $white-bis; -$link-focus: $white-bis; -$link-active: $white-bis; - -/* misc */ - -/* bulma overrides */ -$background: $background-secondary; -$menu-item-active-background-color: $link-background; - -/* Fonts - ******************************************************************************/ -$family-primary: $family-sans-serif; -$family-secondary: $family-sans-serif; diff --git a/bookwyrm/static/js/vendor/tabs.js b/bookwyrm/static/js/tabs.js similarity index 70% rename from bookwyrm/static/js/vendor/tabs.js rename to bookwyrm/static/js/tabs.js index 0535cc869..1dcb0cace 100644 --- a/bookwyrm/static/js/vendor/tabs.js +++ b/bookwyrm/static/js/tabs.js @@ -1,11 +1,11 @@ /* exported TabGroup */ /* -* The content below is licensed according to the W3C Software License at -* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document -* Heavily modified to web component by Zach Leatherman -* Modified back to vanilla JavaScript with support for Bulma markup and nested tabs by Ned Zimmerman -*/ + * The content below is licensed according to the W3C Software License at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * Heavily modified to web component by Zach Leatherman + * Modified back to vanilla JavaScript with support for Bulma markup and nested tabs by Ned Zimmerman + */ class TabGroup { constructor(container) { this.container = container; @@ -15,7 +15,7 @@ class TabGroup { this.panels = this.container.querySelectorAll(':scope > [role="tabpanel"]'); this.delay = this.determineDelay(); - if(!this.tablist || !this.tabs.length || !this.panels.length) { + if (!this.tablist || !this.tabs.length || !this.panels.length) { return; } @@ -32,7 +32,7 @@ class TabGroup { left: 37, up: 38, right: 39, - down: 40 + down: 40, }; } @@ -42,23 +42,21 @@ class TabGroup { 37: -1, 38: -1, 39: 1, - 40: 1 + 40: 1, }; } initTabs() { let count = 0; - for(let tab of this.tabs) { + + for (let tab of this.tabs) { let isSelected = tab.getAttribute("aria-selected") === "true"; + tab.setAttribute("tabindex", isSelected ? "0" : "-1"); - tab.addEventListener('click', this.clickEventListener.bind(this)); - tab.addEventListener('keydown', this.keydownEventListener.bind(this)); - tab.addEventListener('keyup', this.keyupEventListener.bind(this)); - - if (isSelected) { - tab.scrollIntoView(); - } + tab.addEventListener("click", this.clickEventListener.bind(this)); + tab.addEventListener("keydown", this.keydownEventListener.bind(this)); + tab.addEventListener("keyup", this.keyupEventListener.bind(this)); tab.index = count++; } @@ -68,8 +66,9 @@ class TabGroup { let selectedPanelId = this.tablist .querySelector('[role="tab"][aria-selected="true"]') .getAttribute("aria-controls"); - for(let panel of this.panels) { - if(panel.getAttribute("id") !== selectedPanelId) { + + for (let panel of this.panels) { + if (panel.getAttribute("id") !== selectedPanelId) { panel.setAttribute("hidden", ""); } panel.setAttribute("tabindex", "0"); @@ -86,16 +85,18 @@ class TabGroup { // Handle keydown on tabs keydownEventListener(event) { - var key = event.keyCode; + const key = event.keyCode; switch (key) { case this.keys.end: event.preventDefault(); + // Activate last tab this.activateTab(this.tabs[this.tabs.length - 1]); break; case this.keys.home: event.preventDefault(); + // Activate first tab this.activateTab(this.tabs[0]); break; @@ -111,7 +112,7 @@ class TabGroup { // Handle keyup on tabs keyupEventListener(event) { - var key = event.keyCode; + const key = event.keyCode; switch (key) { case this.keys.left: @@ -125,17 +126,16 @@ class TabGroup { // only up and down arrow should function. // In all other cases only left and right arrow function. determineOrientation(event) { - var key = event.keyCode; - var vertical = this.tablist.getAttribute('aria-orientation') == 'vertical'; - var proceed = false; + const key = event.keyCode; + const vertical = this.tablist.getAttribute("aria-orientation") == "vertical"; + let proceed = false; if (vertical) { if (key === this.keys.up || key === this.keys.down) { event.preventDefault(); proceed = true; } - } - else { + } else { if (key === this.keys.left || key === this.keys.right) { proceed = true; } @@ -149,22 +149,21 @@ class TabGroup { // Either focus the next, previous, first, or last tab // depending on key pressed switchTabOnArrowPress(event) { - var pressed = event.keyCode; + const pressed = event.keyCode; for (let tab of this.tabs) { - tab.addEventListener('focus', this.focusEventHandler.bind(this)); + tab.addEventListener("focus", this.focusEventHandler.bind(this)); } if (this.direction[pressed]) { - var target = event.target; + const target = event.target; + if (target.index !== undefined) { if (this.tabs[target.index + this.direction[pressed]]) { this.tabs[target.index + this.direction[pressed]].focus(); - } - else if (pressed === this.keys.left || pressed === this.keys.up) { + } else if (pressed === this.keys.left || pressed === this.keys.up) { this.focusLastTab(); - } - else if (pressed === this.keys.right || pressed == this.keys.down) { + } else if (pressed === this.keys.right || pressed == this.keys.down) { this.focusFirstTab(); } } @@ -172,8 +171,8 @@ class TabGroup { } // Activates any given tab panel - activateTab (tab, setFocus) { - if(tab.getAttribute("role") !== "tab") { + activateTab(tab, setFocus) { + if (tab.getAttribute("role") !== "tab") { tab = tab.closest('[role="tab"]'); } @@ -183,19 +182,19 @@ class TabGroup { this.deactivateTabs(); // Remove tabindex attribute - tab.removeAttribute('tabindex'); + tab.removeAttribute("tabindex"); // Set the tab as selected - tab.setAttribute('aria-selected', 'true'); + tab.setAttribute("aria-selected", "true"); // Give the tab is-active class - tab.classList.add('is-active'); + tab.classList.add("is-active"); // Get the value of aria-controls (which is an ID) - var controls = tab.getAttribute('aria-controls'); + const controls = tab.getAttribute("aria-controls"); // Remove hidden attribute from tab panel to make it visible - document.getElementById(controls).removeAttribute('hidden'); + document.getElementById(controls).removeAttribute("hidden"); // Set focus when required if (setFocus) { @@ -206,14 +205,14 @@ class TabGroup { // Deactivate all tabs and tab panels deactivateTabs() { for (let tab of this.tabs) { - tab.classList.remove('is-active'); - tab.setAttribute('tabindex', '-1'); - tab.setAttribute('aria-selected', 'false'); - tab.removeEventListener('focus', this.focusEventHandler.bind(this)); + tab.classList.remove("is-active"); + tab.setAttribute("tabindex", "-1"); + tab.setAttribute("aria-selected", "false"); + tab.removeEventListener("focus", this.focusEventHandler.bind(this)); } for (let panel of this.panels) { - panel.setAttribute('hidden', 'hidden'); + panel.setAttribute("hidden", "hidden"); } } @@ -228,15 +227,15 @@ class TabGroup { // Determine whether there should be a delay // when user navigates with the arrow keys determineDelay() { - var hasDelay = this.tablist.hasAttribute('data-delay'); - var delay = 0; + const hasDelay = this.tablist.hasAttribute("data-delay"); + let delay = 0; if (hasDelay) { - var delayValue = this.tablist.getAttribute('data-delay'); + const delayValue = this.tablist.getAttribute("data-delay"); + if (delayValue) { delay = delayValue; - } - else { + } else { // If no value is specified, default to 300ms delay = 300; } @@ -246,7 +245,7 @@ class TabGroup { } focusEventHandler(event) { - var target = event.target; + const target = event.target; setTimeout(this.checkTabFocus.bind(this), this.delay, target); } diff --git a/bookwyrm/templates/about/about.html b/bookwyrm/templates/about/about.html index 553bfee11..f1ddd2f38 100644 --- a/bookwyrm/templates/about/about.html +++ b/bookwyrm/templates/about/about.html @@ -14,23 +14,25 @@ {% cache 604800 about_page %} {% get_book_superlatives as superlatives %} -
-

- {% blocktrans with site_name=site.name %}Welcome to {{ site_name }}!{% endblocktrans %} -

+
+
+

+ {% blocktrans with site_name=site.name %}Welcome to {{ site_name }}!{% endblocktrans %} +

-

- {% blocktrans trimmed with site_name=site.name %} - {{ site_name }} is part of BookWyrm, a network of independent, self-directed communities for readers. - While you can interact seamlessly with users anywhere in the BookWyrm network, this community is unique. - {% endblocktrans %} -

+

+ {% blocktrans trimmed with site_name=site.name %} + {{ site_name }} is part of BookWyrm, a network of independent, self-directed communities for readers. + While you can interact seamlessly with users anywhere in the BookWyrm network, this community is unique. + {% endblocktrans %} +

+
{% if superlatives.top_rated %} {% with book=superlatives.top_rated.default_edition rating=superlatives.top_rated.rating %}
-
+
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' size='medium' aria='show' %} @@ -49,7 +51,7 @@ {% if superlatives.wanted %} {% with book=superlatives.wanted.default_edition %}
-
+
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' size='medium' aria='show' %} @@ -68,7 +70,7 @@ {% if superlatives.controversial %} {% with book=superlatives.controversial.default_edition %}
-
+
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' size='medium' aria='show' %} diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index e15b656cf..0e2fd5d39 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -352,7 +352,7 @@ {% endfor %} - {% if request.user.list_set.exists %} + {% if list_options.exists %}
{% csrf_token %} @@ -361,7 +361,7 @@
@@ -386,6 +386,6 @@ {% endblock %} {% block scripts %} - + {% endblock %} diff --git a/bookwyrm/templates/directory/user_card.html b/bookwyrm/templates/directory/user_card.html index ccae925a1..5a17dbe42 100644 --- a/bookwyrm/templates/directory/user_card.html +++ b/bookwyrm/templates/directory/user_card.html @@ -33,7 +33,7 @@