Skip to main content

max / makenotwork

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