Compare commits

..

12 Commits

Author SHA1 Message Date
df9e3a9f61 add missing migration 2024-05-27 14:45:51 +02:00
378a2fca46 fix styles 2024-05-04 04:09:45 +02:00
fbeae81abb styles fix 2024-05-01 02:26:14 +02:00
b40cca8a95 styles fix 2024-05-01 02:18:36 +02:00
7cccb6182e styles fix 2024-05-01 02:12:01 +02:00
6b7cfbdadf player 2024-04-30 22:27:05 +02:00
202f31d169 fix page load 2024-04-30 21:54:34 +02:00
31e22beaab fix podcasts 2024-04-30 21:47:07 +02:00
1344e2dce1 fix 2024-04-30 20:14:43 +02:00
0d5dd43a60 fix 2024-04-30 20:06:12 +02:00
5ed1a3e241 fix 2024-04-30 20:03:11 +02:00
5a074f6b94 fix removed depedency 2024-04-30 19:42:16 +02:00
25 changed files with 142 additions and 55 deletions

View File

@ -126,11 +126,11 @@ msgstr "type"
#: models/diffusion.py:137 models/log.py:131
msgid "Diffusion"
msgstr "Date de diffusion"
msgstr "Diffusion"
#: models/diffusion.py:138
msgid "Diffusions"
msgstr "Dates de diffusion"
msgstr "Diffusions"
#: models/diffusion.py:139
msgid "edit the diffusions' planification"
@ -325,7 +325,7 @@ msgstr "Page d'accueil"
#: models/page.py:291
msgid "Timetable"
msgstr "Temps"
msgstr "Horaires"
#: models/page.py:292
msgid "Programs list"

View File

@ -0,0 +1,64 @@
# Generated by Django 5.0.4 on 2024-05-27 12:40
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("aircox", "0027_remove_page_parent_remove_staticpage_parent_and_more"),
]
operations = [
migrations.AlterModelOptions(
name="episodesound",
options={"verbose_name": "Podcast", "verbose_name_plural": "Podcasts"},
),
migrations.AlterField(
model_name="diffusion",
name="initial",
field=models.ForeignKey(
blank=True,
limit_choices_to=models.Q(("initial__isnull", True), ("program", models.F("program"))),
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rerun_set",
to="aircox.diffusion",
verbose_name="rerun of",
),
),
migrations.AlterField(
model_name="log",
name="source",
field=models.CharField(
blank=True, help_text="Identifier of the log's source.", max_length=64, null=True, verbose_name="source"
),
),
migrations.AlterField(
model_name="program",
name="active",
field=models.BooleanField(
default=True, help_text="if not checked this program is no longer active", verbose_name="active"
),
),
migrations.AlterField(
model_name="schedule",
name="initial",
field=models.ForeignKey(
blank=True,
limit_choices_to=models.Q(("initial__isnull", True), ("program", models.F("program"))),
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rerun_set",
to="aircox.schedule",
verbose_name="rerun of",
),
),
migrations.AlterField(
model_name="sound",
name="is_downloadable",
field=models.BooleanField(
default=False, help_text="Sound can be downloaded by website visitors.", verbose_name="downloadable"
),
),
]

View File

@ -16,7 +16,7 @@ __all__ = ("Episode",)
class EpisodeQuerySet(ProgramChildQuerySet):
def with_podcasts(self):
return self.filter(episodesound__sound__is_public=True).distinct()
return self.filter(episodesound__sound__is_public=True, episodesound__sound__is_removed=False).distinct()
class Episode(ChildPage):
@ -37,7 +37,7 @@ class Episode(ChildPage):
@cached_property
def podcasts(self):
"""Return serialized data about podcasts."""
query = self.episodesound_set.all().public().order_by("-broadcast", "position")
query = self.episodesound_set.available().public().order_by("-broadcast", "position")
return self._to_podcasts(query)
@cached_property

View File

@ -40,7 +40,7 @@ class PagePermissions:
if user.is_superuser:
return True
perm = self.perms_codename_format.format(self=self, perm=perm)
perm = self.perms_codename_format.format(self=self, perm=perm, obj=obj)
return user.has_perm(perm)
def init(self, obj, model=None):

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -58,7 +58,7 @@
{% if podcasts %}
<section class="container">
<h2 class="title is-3 p-2">{% translate "Last podcasts" %}</h2>
<h2 class="title">{% translate "Last podcasts" %}</h2>
{% include "./widgets/carousel.html" with objects=podcasts url_name="podcast-list" url_label=_("All podcasts") %}
</section>
{% endif %}

View File

@ -2,10 +2,12 @@
{% comment %}Detail page of a show{% endcomment %}
{% load i18n aircox %}
{% block content-container %}
{% block content %}
{{ block.super }}
{% with schedules=object.schedule_set.all %}
{% if schedules %}
<header class="container schedules">
{% if object.active and schedules %}
<header class="schedules mt-3">
{% for schedule in schedules %}
<div class="schedule">
<div class="heading">
@ -33,8 +35,13 @@
{% endif %}
{% endwith %}
{% endblock %}
{% block main %}
{{ block.super }}
{% if episodes %}
<section class="container">
<h2 class="title is-2">{% translate "Last Episodes" %}</h2>

View File

@ -58,8 +58,8 @@
{% block actions %}
{{ block.super }}
{% if object.sound_set.count %}
<button class="button action" @click="player.playButtonClick($event)"
{% if object.episodesound_set.available.public.count %}
<button type="button" class="button action" @click="player.playButtonClick($event)"
data-sounds="{{ object.podcasts|json }}">
<span class="icon is-small">
<span class="fas fa-play"></span>

View File

@ -29,8 +29,8 @@ class TimeTableView(GetDateMixin, BaseDiffusionListView):
attach_to_value = StaticPage.Target.TIMETABLE
template_name = "aircox/timetable_list.html"
def get_date(self):
date = super().get_date()
def get_date(self, param="date"):
date = super().get_date(param)
return date if date is not None else datetime.date.today()
def get_logs(self, date):

View File

@ -126,8 +126,8 @@ class LogListAPIView(LogListMixin, BaseAPIView, ListAPIView):
self.min_date = tz.now() - tz.timedelta(minutes=30)
return date
def get_object_list(self, logs, full):
return [LogInfo(obj) for obj in super().get_object_list(logs, full)]
def get_object_list(self, logs, *args, **kwargs):
return [LogInfo(obj) for obj in super().get_object_list(logs, *args, **kwargs)]
def get_serializer(self, queryset, *args, **kwargs):
full = bool(self.request.GET.get("full"))

View File

@ -14,7 +14,7 @@
<small v-if="source.isPaused || source.isPlaying">([[ source.remainingString ]])</small>
<a v-if="source.data.program !== undefined"
:href="'{% url 'aircox:program_edit' "$$" %}'.replace('$$', source.data.program)"
:href="'{% url 'program-edit' "$$" %}'.replace('$$', source.data.program)"
title="{% translate "Edit program" %}">
<span class="icon">
<span class="fas fa-edit"></span>

View File

@ -16,7 +16,7 @@
</template>
<script>
export default {
emits: ['select', 'unselect', 'move'],
emits: ['select', 'unselect', 'move', 'remove'],
data() {
return {
selectedIndex: this.defaultIndex,
@ -50,11 +50,16 @@ export default {
findIndex(pred) { return this.set.findIndex(pred) },
remove(index, select=false) {
const item = this.set.get(index)
if(!item)
return
this.set.remove(index);
if(index < this.selectedIndex)
this.selectedIndex--;
if(select && this.selectedIndex == index)
this.select(index)
this.$emit('remove', {index, item, set: this.set})
},
select(index) {

View File

@ -274,7 +274,6 @@ export default {
if(event.type == 'ended' && (!this.playlist || this.playlist.selectNext() == -1))
this.play();
},
},
mounted() {

View File

@ -29,7 +29,7 @@ import ASoundItem from './ASoundItem';
export default {
extends: AList,
emits: [...AList.emits, 'remove'],
emits: [...AList.emits],
components: { ASoundItem },
props: {

View File

@ -141,7 +141,7 @@ export default class PageLoad {
let submit = event.type == 'submit';
let target = submit || event.target.tagName == 'A'
? event.target : event.target.closest('a');
if(!target || target.hasAttribute('target') || target.data.forceReload)
if(!target || target.hasAttribute('target') || (target.dataset && target.dataset.forceReload))
return;
let url = submit ? target.getAttribute('action') || ''

View File

@ -16,7 +16,7 @@ input.half-field:not(:active):not(:hover) {
--body-bg: #fff;
--text-color: black;
--text-color-light: #555;
--break-color: rgb(225, 225, 225);
--break-color: rgb(225, 225, 225, 0.8);
--main-color: #EFCA08;
--main-color-light: #F4da51;
@ -67,7 +67,7 @@ body.mobile {
}
@media screen and (max-width: v.$screen-normal) {
html { font-size: 18px !important; }
html { font-size: 16px !important; }
}
@media screen and (max-width: v.$screen-wider) {
@ -75,7 +75,7 @@ body.mobile {
}
@media screen and (min-width: v.$screen-wider) {
html { font-size: 24px !important; }
html { font-size: 20px !important; }
}
h1, h2, h3, h4, h5, h6, .heading, .title, .subtitle {

View File

@ -1,10 +1,10 @@
@use "vars" as v;
:root {
--title-1-sz: 1.6rem;
--title-2-sz: 1.4rem;
--title-3-sz: 1.3rem;
--title-4-sz: 1.2rem;
--title-1-sz: 1.4rem;
--title-2-sz: 1.3rem;
--title-3-sz: 1.1rem;
--title-4-sz: 1.0rem;
--subtitle-1-sz: 1.6rem;
--subtitle-2-sz: 1.4rem;
--subtitle-3-sz: 1.2rem;
@ -16,22 +16,17 @@
--heading-hg-bg: var(--secondary-color);
--heading-link-hv-fg: var(--link-fg);
--cover-w: 14rem;
--cover-h: 14rem;
--cover-w: 10rem;
--cover-h: 10rem;
--cover-small-w: 10rem;
--cover-small-h: 10rem;
--cover-tiny-w: 10rem;
--cover-tiny-h: 10rem;
--card-w: var(--cover-w);
--preview-bg: var(--body-bg);
--preview-title-sz: var(--title-3-sz);
--preview-subtitle-sz: var(--title-3-sz);
--preview-cover-size: 14rem;
--preview-cover-small-size: 10rem;
--preview-cover-tiny-size: 4rem;
--preview-title-sz: var(--title-4-sz);
--preview-subtitle-sz: var(--title-4-sz);
--preview-wide-content-sz: #{v.$text-size-2};
--preview-heading-bg-color: var(--main-color);
--header-height: var(--cover-h);
@ -96,6 +91,23 @@
}
}
@media screen and (max-width: v.$screen-wide) {
:root {
--cover-w: 8rem;
--cover-h: 8rem;
--cover-small-w: 4rem;
--cover-small-h: 4rem;
--cover-tiny-w: 2rem;
--cover-tiny-h: 2rem;
--section-content-sz: 1rem;
// --preview-title-sz: #{v.$text-size};
// --preview-subtitle-sz: #{v.$text-size-smaller};
// --preview-wide-content-sz: #{v.$text-size};
}
}
// ---- headings
.no-reset h1 { font-size: var(--title-1-sz); }
@ -133,7 +145,7 @@
&:not(:empty) {
// border-bottom: 1px var(--heading-bg) solid;
// color: var(--heading-fg);
padding: v.$mp-2;
//padding: v.$mp-2;
margin-top: 0em !important;
vertical-align: top;
@ -306,21 +318,21 @@
&.small, .preview.small & {
min-width: unset;
height: var(--preview-cover-small-size);
width: var(--preview-cover-small-size) !important;
min-width: var(--preview-cover-small-size);
height: var(--cover-small-h);
width: var(--cover-small-w) !important;
min-width: var(--cover-small-w);
}
&.tiny, .preview.tiny & {
min-width: unset;
height: var(--preview-cover-tiny-size);
width: var(--preview-cover-tiny-size) !important;
min-width: var(--preview-cover-tiny-size);
height: var(--cover-tiny-h);
width: var(--cover-tiny-w) !important;
min-width: var(--cover-tiny-w);
}
}
.preview-header {
width: 100%;
// width: 100%;
/*&:not(.no-cover) {
min-height: var(--header-height);
@ -378,7 +390,7 @@
margin-bottom: unset;
.list-item:not(.no-cover) & {
min-height: var(--preview-cover-small-size);
min-height: var(--cover-small-h);
}
}

View File

@ -22,7 +22,7 @@
&:not(:last-child) {
padding-bottom: calc(v.$mp-4 / 2);
border-bottom: 2px var(--break-color) solid;
// border-bottom: 2px var(--break-color) solid;
}
> .title, h3.title {
@ -60,7 +60,8 @@
margin: v.$mp-3;
margin-left: 0rem;
padding: v.$mp-2;
border-bottom: 1px var(--main-color) solid;
text-color: var(--main-color);
background-color: var(--main-color-light);
.heading {
padding: 0em;

View File

@ -27,7 +27,6 @@ urlpatterns = [
path("streamer/", include((aircox_streamer.urls.urls, "aircox_streamer"), namespace="streamer")),
path("admin/", admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")),
path("ckeditor/", include("ckeditor_uploader.urls")),
path("filer/", include("filer.urls")),
]

View File

@ -1,7 +1,7 @@
{% extends "aircox/base.html" %}
{% load static %}
{% block assets %}
{% block head %}
{{ block.super }}
<style>
:root {