Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
8aff1d0
Create compilations file
broquemonsieur Jun 5, 2023
5fb47c5
add Compilation symbols
broquemonsieur Jun 7, 2023
d0a3c99
Add Compilation symbols until "Compilations" appears in feeds menu
broquemonsieur Jun 7, 2023
24f55a7
Add backend Compilation symbols
broquemonsieur Jun 7, 2023
bef234f
Add compilations to DB
broquemonsieur Jun 15, 2023
6b984c6
Remove files that were prematurely added and add backend Compilation …
broquemonsieur Jun 15, 2023
696ca42
Add structs and DB methods for Compilations
broquemonsieur Jun 15, 2023
7c92b05
Add custom item for CompilationVideo
broquemonsieur Jun 16, 2023
b6181b9
Add authenticated API for compilation creation
broquemonsieur Jun 16, 2023
bac4fd9
Add create_compilation route and ecr
broquemonsieur Jun 16, 2023
74d42c1
Add ecr for individual compilation items (videos)
broquemonsieur Jun 16, 2023
ea48239
Add erc for viewing one compliation
broquemonsieur Jun 16, 2023
7cfa099
Add compilations to feeds menu
broquemonsieur Jun 18, 2023
1d209c4
getcompilation route to routes that are registered
broquemonsieur Jun 27, 2023
8c15c1e
Add migration table for compilations
broquemonsieur Jun 29, 2023
128d541
Remove compid check for Nil error debugging
broquemonsieur Jun 30, 2023
2a9789c
Add CSS element for compilation video
broquemonsieur Jul 4, 2023
0e2fefe
Add arrows to change video order
broquemonsieur Jul 4, 2023
bfa9f77
Add margins to video panel elements
broquemonsieur Jul 5, 2023
b95a4e8
Use text input for timestamp
broquemonsieur Jul 7, 2023
7b757aa
Address gitignore persistence
broquemonsieur Jul 8, 2023
ff6a9b9
Make the layout nice for video panels
broquemonsieur Jul 8, 2023
da290e5
Add timestamps to update compilation POST request
broquemonsieur Jul 17, 2023
be42dd0
Redo conflict resolution
broquemonsieur Jul 17, 2023
60a184e
Add timestamp DB handling
broquemonsieur Jul 19, 2023
ea878e2
Debug the DB methods for compilations
broquemonsieur Jul 23, 2023
a8c0023
Debug SQL query for timestamp adjustment
broquemonsieur Jul 24, 2023
8908024
Use ion for arrow swap icons
broquemonsieur Jul 24, 2023
0211d69
Enable swap arrows to rearrange order of videos
broquemonsieur Jul 25, 2023
f05d38a
Prevent autoplay breakage by vetting each change from top to compilat…
broquemonsieur Aug 3, 2023
d7a53d0
Finish vetting changes for autoplay stability
broquemonsieur Aug 3, 2023
472a2d7
Use markers to implement timestamps
broquemonsieur Aug 5, 2023
510d85c
Query DB for timestamps after current id
broquemonsieur Aug 6, 2023
f48083d
Add end marker continuation utility
broquemonsieur Aug 6, 2023
f7fc05e
Remove development-purpose file ignores
broquemonsieur Aug 6, 2023
0d968a3
Remove LOGGER statements
broquemonsieur Aug 6, 2023
212509e
Revert docker-compose
broquemonsieur Aug 6, 2023
205c549
Replace EOF carriage returns
broquemonsieur Aug 6, 2023
93ac7cd
Run Crystal formatting tool
broquemonsieur Aug 6, 2023
75cc189
Merge branch 'iv-org:master' into main
broquemonsieur Sep 18, 2023
cd3256f
Merge branch 'iv-org:master' into main
broquemonsieur Sep 22, 2023
fa50e5d
Merge branch 'iv-org:master' into main
broquemonsieur Oct 8, 2023
5cc6b85
Merge branch 'iv-org:master' into main
broquemonsieur Oct 15, 2023
ee5d7f2
Merge branch 'iv-org:master' into main
broquemonsieur Oct 21, 2023
3758d22
Resolve merge conflict
broquemonsieur Oct 21, 2023
5fdaa1b
Merge branch 'iv-org:master' into main
broquemonsieur Dec 3, 2023
379761a
Change "list" to "comp"
broquemonsieur Dec 4, 2023
df188c0
Complete the bifurcation of "list" and "comp"
broquemonsieur Dec 4, 2023
7a31ca7
Revert mistake
broquemonsieur Dec 5, 2023
f02ac49
Merge branch 'iv-org:master' into main
broquemonsieur Dec 6, 2023
0284d37
Merge branch 'iv-org:master' into main
broquemonsieur Dec 18, 2023
3848e0d
Merge branch 'iv-org:master' into main
broquemonsieur Dec 21, 2023
a33c01b
Fix version number
broquemonsieur Dec 29, 2023
22455bb
Add new enum
broquemonsieur Dec 29, 2023
10d8a4b
Add new migration
broquemonsieur Dec 29, 2023
c4e245f
Merge branch 'iv-org:master' into main
broquemonsieur Jan 22, 2024
870dff4
Merge branch 'iv-org:master' into main
broquemonsieur Feb 7, 2024
a777695
Merge branch 'iv-org:master' into main
broquemonsieur Mar 23, 2024
0bee2e9
Merge branch 'iv-org:master' into main
broquemonsieur May 31, 2024
0cf71b2
Merge branch 'iv-org:master' into main
broquemonsieur Sep 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
/invidious
/sentry
/config/config.yml
.DS_Store
64 changes: 63 additions & 1 deletion assets/css/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -814,5 +814,67 @@ h1, h2, h3, h4, h5, p,
}

#download_widget {
width: 100%;
width: 100%;
}

/*
* Compilations
*/

input.compilation-video-timestamp {
width: 50px;
height: 20px;
}

div.compilation-video-panel {
display:flex;
justify-content:flex-start;
width:calc(100% - 20px);
height:100px;
border:2px solid #ccc;
margin: 10px;
/*background: #d9d9d9;*/
}

div.compilation-order-swap-arrows {
display:flex;
flex-direction:column;
justify-content:space-between;
}

svg.compilation-video-swap-arrow {
border: solid black;
width:20px;
height:50%;
background-color: beige;
margin: 10px;
}

div.compilation-video-input-panel {
display:flex;
flex-direction:column;
min-width: 0;
margin: 10px;
}

div.compilation-video-title {
display:flex;
justify-content:flex-start;
}

span.compilation-video-title {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

div.compilation-video-timestamp-set {
display:flex;
justify-content: flex-start;
align-items: center;
}

div.compilation-video-thumbnail {
position: relative;
box-sizing: border-box;
}
63 changes: 63 additions & 0 deletions assets/js/compilation_widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict';
var compilation_data = JSON.parse(document.getElementById('compilation_data').textContent);
var payload = 'csrf_token=' + compilation_data.csrf_token;

function add_compilation_video(target) {
var select = target.parentNode.children[0].children[1];
var option = select.children[select.selectedIndex];

var url = '/compilation_ajax?action_add_video=1&redirect=false' +
'&video_id=' + target.getAttribute('data-id') +
'&compilation_id=' + option.getAttribute('data-compid');

helpers.xhr('POST', url, {payload: payload}, {
on200: function (response) {
option.textContent = '✓' + option.textContent;
}
});
}

function add_compilation_item(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none';

var url = '/compilation_ajax?action_add_video=1&redirect=false' +
'&video_id=' + target.getAttribute('data-id') +
'&compilation_id=' + target.getAttribute('data-compid');

helpers.xhr('POST', url, {payload: payload}, {
onNon200: function (xhr) {
tile.style.display = '';
}
});
}

function remove_compilation_item(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none';

var url = '/compilation_ajax?action_remove_video=1&redirect=false' +
'&set_video_id=' + target.getAttribute('data-index') +
'&compilation_id=' + target.getAttribute('data-compid');

helpers.xhr('POST', url, {payload: payload}, {
onNon200: function (xhr) {
tile.style.display = '';
}
});
}

function move_compilation_video_before(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none';

var url = '/compilation_ajax?action_move_video_before=1&redirect=false' +
'&set_video_id=' + target.getAttribute('data-index') +
'&compilation_id=' + target.getAttribute('data-compid');

helpers.xhr('POST', url, {payload: payload}, {
onNon200: function (xhr) {
tile.style.display = '';
}
});
}
35 changes: 35 additions & 0 deletions assets/js/embed.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
'use strict';
var video_data = JSON.parse(document.getElementById('video_data').textContent);

function get_compilation(compid) {
var compid_url;
compid_url = '/api/v1/compilations/' + compid +
'?index=' + video_data.index +
'&continuation' + video_data.id +
'&format=html&hl=' + video_data.preferences.locale;

helpers.xhr('GET', compid_url, {retries: 5, entity_name: 'compilation'}, {
on200: function (response) {
if (!response.nextVideo)
return;

player.on('ended', function () {
var url = new URL('https://example.com/embed/' + response.nextVideo);

url.searchParams.set('comp', compid);
if (!compid.startsWith('RD'))
url.searchParams.set('index', response.index);
if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1');
if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local);

location.assign(url.pathname + url.search);
});
}
});
}

function get_playlist(plid) {
var plid_url;
if (plid.startsWith('RD')) {
Expand Down Expand Up @@ -43,6 +76,8 @@ function get_playlist(plid) {
addEventListener('load', function (e) {
if (video_data.plid) {
get_playlist(video_data.plid);
} else if (video_data.compid) {
get_compilation(video_data.compid)
} else if (video_data.video_series) {
player.on('ended', function () {
var url = new URL('https://example.com/embed/' + video_data.video_series.shift());
Expand Down
9 changes: 9 additions & 0 deletions assets/js/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,21 @@
document.querySelectorAll('[data-onclick="add_playlist_video"]').forEach(function (el) {
el.onclick = function () { add_playlist_video(el); };
});
document.querySelectorAll('[data-onclick="add_compilation_video"]').forEach(function (el) {
el.onclick = function () { add_compilation_video(el); };
});
document.querySelectorAll('[data-onclick="add_playlist_item"]').forEach(function (el) {
el.onclick = function () { add_playlist_item(el); };
});
document.querySelectorAll('[data-onclick="add_compilation_item"]').forEach(function (el) {
el.onclick = function () { add_compilation_item(el); };
});
document.querySelectorAll('[data-onclick="remove_playlist_item"]').forEach(function (el) {
el.onclick = function () { remove_playlist_item(el); };
});
document.querySelectorAll('[data-onclick="remove_compilation_item"]').forEach(function (el) {
el.onclick = function () { remove_compilation_item(el); };
});
document.querySelectorAll('[data-onclick="revoke_token"]').forEach(function (el) {
el.onclick = function () { revoke_token(el); };
});
Expand Down
9 changes: 7 additions & 2 deletions assets/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,13 @@ if (video_data.params.video_start > 0 || video_data.params.video_end > 0) {

player.markers({
onMarkerReached: function (marker) {
if (marker.text === 'End')
player.loop() ? player.markers.prev('Start') : player.pause();
if (marker.text === 'End') {
if (video_data.ending_timestamp_seconds) {
player.currentTime(player.duration());
} else {
player.loop() ? player.markers.prev('Start') : player.pause();
}
}
},
markers: markers
});
Expand Down
56 changes: 55 additions & 1 deletion assets/js/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,59 @@ function continue_autoplay(event) {
}
}

function get_compilation(compid) {
var compilation = document.getElementById('compilation');

compilation.innerHTML = spinnerHTMLwithHR;

var compid_url;
compid_url = '/api/v1/compilations/' + compid +
'?index=' + video_data.index +
'&continuation=' + video_data.id +
'&format=html&hl=' + video_data.preferences.locale;

helpers.xhr('GET', compid_url, {retries: 5, entity_name: 'compilation'}, {
on200: function (response) {
compilation.innerHTML = response.compilationHtml;

if (!response.nextVideo) return;

var nextVideo = document.getElementById(response.nextVideo);
nextVideo.parentNode.parentNode.scrollTop = nextVideo.offsetTop;

player.on('ended', function () {
var url = new URL('https://example.com/watch?v=' + response.nextVideo);

url.searchParams.set('comp', compid);
if (!compid.startsWith('RD'))
url.searchParams.set('index', response.index);
if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1');
if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local);
url.searchParams.set('t',video_data.starting_timestamp_seconds);
url.searchParams.set('end',video_data.ending_timestamp_seconds);

location.assign(url.pathname + url.search);
});
},
onNon200: function (xhr) {
compilation.innerHTML = '';
document.getElementById('continue').style.display = '';
},
onError: function (xhr) {
compilation.innerHTML = spinnerHTMLwithHR;
},
onTimeout: function (xhr) {
compilation.innerHTML = spinnerHTMLwithHR;
}
});
}

function get_playlist(plid) {
var playlist = document.getElementById('playlist');

Expand Down Expand Up @@ -177,7 +230,8 @@ if (video_data.play_next) {
addEventListener('load', function (e) {
if (video_data.plid)
get_playlist(video_data.plid);

if (video_data.compid)
get_compilation(video_data.compid);
if (video_data.params.comments[0] === 'youtube') {
get_youtube_comments();
} else if (video_data.params.comments[0] === 'reddit') {
Expand Down
8 changes: 8 additions & 0 deletions config/config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,14 @@ hmac_key: "CHANGE_ME!!"
##
#playlist_length_limit: 500

##
## Maximum custom compilation length limit.
##
## Accepted values: Integer
## Default: 500
##
#compilation_length_limit: 500

#########################################
#
# Default user preferences
Expand Down
21 changes: 21 additions & 0 deletions config/sql/compilation_videos.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- Table: public.compilation_videos

-- DROP TABLE public.compilation_videos;

CREATE TABLE IF NOT EXISTS public.compilation_videos
(
title text,
id text,
author text,
ucid text,
length_seconds integer,
starting_timestamp_seconds integer,
ending_timestamp_seconds integer,
published timestamptz,
compid text references compilations(id),
index int8,
order_index integer,
PRIMARY KEY (index,compid)
);

GRANT ALL ON TABLE public.compilation_videos TO current_user;
31 changes: 31 additions & 0 deletions config/sql/compilations.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-- Type: public.compilation_privacy

-- DROP TYPE public.compilation_privacy;

CREATE TYPE public.compilation_privacy AS ENUM
(
'Unlisted',
'Private'
);

-- Table: public.compilations

-- DROP TABLE public.compilations;

CREATE TABLE IF NOT EXISTS public.compilations
(
title text,
id text primary key,
author text,
description text,
video_count integer,
created timestamptz,
updated timestamptz,
privacy compilation_privacy,
index int8[],
first_video_id text,
first_video_starting_timestamp_seconds integer,
first_video_ending_timestamp_seconds integer
);

GRANT ALL ON public.compilations TO current_user;
2 changes: 2 additions & 0 deletions docker/init-invidious-db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/nonces.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/annotations.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/playlists.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/playlist_videos.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/compilations.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/compilation_videos.sql
Loading