Skip to main content

max / makenotwork

6.5 KB · 157 lines History Blame Raw
1 {% extends "base.html" %}
2 {% import "_sheet.html" as sheet %}
3 {% import "_island.html" as island %}
4
5 {% block title %}{{ item.title }} - Library - Makenotwork{% endblock %}
6
7 {% block head %}
8 <meta name="robots" content="noindex">
9 {% call sheet::sheet("media-player.css") %}{% endcall %}
10 {% endblock %}
11
12 {% block content %}
13 {% include "partials/site_header.html" %}
14
15 <article class="media-container">
16 <p class="library-back">
17 <a href="/i/{{ item.id }}">&larr; Store page</a> &middot;
18 <a href="/library">Your library</a>
19 </p>
20
21 <header class="author-header">
22 <div class="author-avatar">{{ creator_avatar_initials }}</div>
23 <div class="author-info">
24 <div class="author-name"><a href="/u/{{ creator_username }}">{% if let Some(name) = creator_display_name %}{{ name }}{% else %}{{ creator_username }}{% endif %}</a></div>
25 <div class="media-meta">{{ item.release_date }}{% match item.content %}{% when crate::types::ItemContent::Video with { duration, .. } %}{% if let Some(dur) = duration %} | {{ dur }}{% endif %}{% when _ %}{% endmatch %}</div>
26 </div>
27 </header>
28
29 <h1 class="media-title">{{ item.title }}</h1>
30
31 {% if let Some(project_title) = project_title %}
32 <p class="media-series">
33 <a href="/p/{{ project_slug }}">{{ project_title }}</a>
34 </p>
35 {% endif %}
36
37 <div class="video-display">
38 <video id="media-a" preload="metadata"
39 {% match item.content %}{% when crate::types::ItemContent::Video with { cover_url, .. } %}{% if let Some(url) = cover_url %}poster="{{ url }}"{% endif %}{% when _ %}{% endmatch %}>
40 {% if let Some(vurl) = video_url %}
41 <source src="{{ vurl }}">
42 {% endif %}
43 </video>
44 <!-- Standby element for gapless segment transitions (pre/mid/post-roll clips). -->
45 <video id="media-b" class="is-standby" preload="metadata"></video>
46 </div>
47
48 <div class="media-player">
49 <div class="player-controls">
50 <button class="play-button" id="play-btn" aria-label="Play">
51 <svg id="play-icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
52 <path d="M8 5v14l11-7z"/>
53 </svg>
54 <svg id="pause-icon" class="media-icon-hidden" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
55 <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
56 </svg>
57 </button>
58 <div class="progress-container">
59 <div class="progress-bar" id="progress-bar">
60 <div class="progress-fill" id="progress-fill"></div>
61 </div>
62 <div class="time-display">
63 <span id="current-time">0:00</span>
64 <span id="duration">0:00</span>
65 </div>
66 </div>
67 </div>
68
69 <div class="insertion-label" id="insertion-label"></div>
70 <button class="skip-insertion" id="skip-btn" type="button">Skip &#8250;</button>
71
72 <div class="player-secondary">
73 <div class="speed-control">
74 <span>Speed:</span>
75 <button class="speed-button" data-speed="0.5">0.5x</button>
76 <button class="speed-button is-selected" data-speed="1">1x</button>
77 <button class="speed-button" data-speed="1.5">1.5x</button>
78 <button class="speed-button" data-speed="2">2x</button>
79 </div>
80 <div class="volume-control">
81 <span class="volume-icon">
82 <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
83 <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
84 </svg>
85 </span>
86 <input type="range" class="volume-slider" id="volume-slider" min="0" max="100" value="75" />
87 </div>
88 </div>
89 </div>
90
91 {% if !chapters.is_empty() %}
92 <div class="chapters">
93 <h3>Chapters</h3>
94 <ul class="chapter-list">
95 {% for chapter in chapters %}
96 <li class="chapter-item" data-time="{{ chapter.start_seconds }}">
97 <span class="chapter-title">{{ chapter.title }}</span>
98 <span class="chapter-time">{{ chapter.timestamp }}</span>
99 </li>
100 {% endfor %}
101 </ul>
102 </div>
103 {% endif %}
104
105 {% if !item.description.is_empty() %}
106 <div class="media-description">
107 <p>{{ item.description }}</p>
108 </div>
109 {% endif %}
110
111 {% if !versions.is_empty() %}
112 <section class="library-downloads raised">
113 <h3>Source files</h3>
114 {% for version in versions %}
115 {% if version.has_file %}
116 <div class="download-row">
117 <span class="download-version">v{{ version.number }}</span>
118 {% if let Some(label) = version.label %}
119 <span class="download-label">{{ label }}</span>
120 {% else %}
121 <span class="download-label download-label--empty">{% match version.file_name %}{% when Some with (name) %}{{ name }}{% when None %}Download{% endmatch %}</span>
122 {% endif %}
123 <span class="download-size">{{ version.size }}</span>
124 <button class="btn-secondary btn-download-compact"
125 data-action="downloadVersion" data-arg="{{ version.id }}">Download</button>
126 </div>
127 {% endif %}
128 {% endfor %}
129 </section>
130 {% endif %}
131 </article>
132
133 {% include "partials/discussion_section.html" %}
134
135 <footer class="media-player-footer">
136 {% if is_owner %}
137 <a href="/dashboard/item/{{ item.id }}">Edit</a> &middot;
138 {% endif %}
139 <a href="/i/{{ item.id }}">Store page</a> &middot;
140 <a href="/library">Your library</a>
141 </footer>
142 {% endblock %}
143
144 {% block scripts %}
145 <mnw-media-player>
146 <script id="media-player-data" type="application/json">
147 {
148 "segments": {{ segments_json|safe }},
149 "mediaType": "video",
150 "itemId": "{{ item.id }}"
151 }
152 </script>
153 </mnw-media-player>
154 {% call island::island("media-player") %}{% endcall %}
155 <script src="/static/page-library-video.js?v=0623" defer></script>
156 {% endblock %}
157