cinera.c: Reference and player tweaks
Different ISBN database, and slightly more flexible BuildReference() Permit line-breaking on '/' in the references menu cinera.css and cinera_player*.js: More subtle "click here to regain focus" - for @insofaras Persist theatre mode - for @insofaras Resume in-progress video at previous timecode - for @AsafGartner
This commit is contained in:
parent
8d75865cf3
commit
4a0630beb0
167
cinera/cinera.c
167
cinera/cinera.c
|
@ -14,7 +14,7 @@ typedef struct
|
||||||
version CINERA_APP_VERSION = {
|
version CINERA_APP_VERSION = {
|
||||||
.Major = 0,
|
.Major = 0,
|
||||||
.Minor = 5,
|
.Minor = 5,
|
||||||
.Patch = 44
|
.Patch = 45
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(matt): Copy in the DB 3 stuff from cinera_working.c
|
// TODO(matt): Copy in the DB 3 stuff from cinera_working.c
|
||||||
|
@ -657,30 +657,38 @@ CopyStringToBufferHTMLSafe(buffer *Dest, char *String)
|
||||||
}
|
}
|
||||||
switch(*String)
|
switch(*String)
|
||||||
{
|
{
|
||||||
case '<':
|
case '<': CopyStringToBuffer(Dest, "<"); break;
|
||||||
CopyStringToBuffer(Dest, "<");
|
case '>': CopyStringToBuffer(Dest, ">"); break;
|
||||||
String++;
|
case '&': CopyStringToBuffer(Dest, "&"); break;
|
||||||
break;
|
case '\"': CopyStringToBuffer(Dest, """); break;
|
||||||
case '>':
|
case '\'': CopyStringToBuffer(Dest, "'"); break;
|
||||||
CopyStringToBuffer(Dest, ">");
|
default: *Dest->Ptr++ = *String; break;
|
||||||
String++;
|
|
||||||
break;
|
|
||||||
case '&':
|
|
||||||
CopyStringToBuffer(Dest, "&");
|
|
||||||
String++;
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
CopyStringToBuffer(Dest, """);
|
|
||||||
String++;
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
CopyStringToBuffer(Dest, "'");
|
|
||||||
String++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*Dest->Ptr++ = *String++;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
++String;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CopyStringToBufferHTMLSafeBreakingOnSlash(buffer *Dest, char *String)
|
||||||
|
{
|
||||||
|
while(*String)
|
||||||
|
{
|
||||||
|
if(Dest->Ptr - Dest->Location >= Dest->Size)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "CopyStringToBufferHTMLSafeBreakingOnSlash: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
|
||||||
|
__asm__("int3");
|
||||||
|
}
|
||||||
|
switch(*String)
|
||||||
|
{
|
||||||
|
case '<': CopyStringToBuffer(Dest, "<"); break;
|
||||||
|
case '>': CopyStringToBuffer(Dest, ">"); break;
|
||||||
|
case '&': CopyStringToBuffer(Dest, "&"); break;
|
||||||
|
case '\"': CopyStringToBuffer(Dest, """); break;
|
||||||
|
case '\'': CopyStringToBuffer(Dest, "'"); break;
|
||||||
|
case '/': CopyStringToBuffer(Dest, "/\u200B"); break;
|
||||||
|
default: *Dest->Ptr++ = *String; break;
|
||||||
|
}
|
||||||
|
++String;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,7 +699,7 @@ CopyStringToBufferJSONSafe(buffer *Dest, char *String)
|
||||||
{
|
{
|
||||||
if(Dest->Ptr - Dest->Location >= Dest->Size)
|
if(Dest->Ptr - Dest->Location >= Dest->Size)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "CopyStringToBufferHTMLSafe: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
|
fprintf(stderr, "CopyStringToBufferJSONSafe: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
|
||||||
__asm__("int3");
|
__asm__("int3");
|
||||||
}
|
}
|
||||||
switch(*String)
|
switch(*String)
|
||||||
|
@ -918,7 +926,8 @@ DeclaimBuffer(buffer *Buffer)
|
||||||
Buffer->Size = 0;
|
Buffer->Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewindBuffer(buffer *Buffer)
|
void
|
||||||
|
RewindBuffer(buffer *Buffer)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
float PercentageUsed = (float)(Buffer->Ptr - Buffer->Location) / Buffer->Size * 100;
|
float PercentageUsed = (float)(Buffer->Ptr - Buffer->Location) / Buffer->Size * 100;
|
||||||
|
@ -1561,109 +1570,93 @@ BuildCredits(buffer *CreditsMenu, bool *HasCreditsMenu, HMML_VideoMetaData *Meta
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
REF_SITE = 1 << 0,
|
REF_SITE = 1 << 0,
|
||||||
REF_PAGE = 1 << 1,
|
REF_PAGE = 1 << 1,
|
||||||
REF_URL = 1 << 2,
|
REF_URL = 1 << 2,
|
||||||
REF_TITLE = 1 << 3,
|
REF_TITLE = 1 << 3,
|
||||||
REF_ARTICLE = 1 << 4,
|
REF_ARTICLE = 1 << 4,
|
||||||
REF_AUTHOR = 1 << 5,
|
REF_AUTHOR = 1 << 5,
|
||||||
REF_EDITOR = 1 << 6,
|
REF_EDITOR = 1 << 6,
|
||||||
REF_PUBLISHER = 1 << 7,
|
REF_PUBLISHER = 1 << 7,
|
||||||
REF_ISBN = 1 << 8,
|
REF_ISBN = 1 << 8,
|
||||||
} reference_fields;
|
} reference_fields;
|
||||||
|
|
||||||
int
|
int
|
||||||
BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference *Ref, HMML_Annotation *Anno)
|
BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference *Ref, HMML_Annotation *Anno)
|
||||||
{
|
{
|
||||||
int Mask = 0;
|
if(Ref->isbn)
|
||||||
|
{
|
||||||
|
CopyString(ReferencesArray[UniqueRefs].ID, Ref->isbn);
|
||||||
|
if(!Ref->url) { CopyString(ReferencesArray[UniqueRefs].URL, "https://isbndb.com/book/%s", Ref->isbn); }
|
||||||
|
else { CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url); }
|
||||||
|
}
|
||||||
|
else if(Ref->url)
|
||||||
|
{
|
||||||
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
||||||
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
||||||
|
}
|
||||||
|
else { return RC_INVALID_REFERENCE; }
|
||||||
|
|
||||||
|
int Mask = 0;
|
||||||
if(Ref->site) { Mask |= REF_SITE; }
|
if(Ref->site) { Mask |= REF_SITE; }
|
||||||
if(Ref->page) { Mask |= REF_PAGE; }
|
if(Ref->page) { Mask |= REF_PAGE; }
|
||||||
if(Ref->url) { Mask |= REF_URL; }
|
|
||||||
if(Ref->title) { Mask |= REF_TITLE; }
|
if(Ref->title) { Mask |= REF_TITLE; }
|
||||||
if(Ref->article) { Mask |= REF_ARTICLE; }
|
if(Ref->article) { Mask |= REF_ARTICLE; }
|
||||||
if(Ref->author) { Mask |= REF_AUTHOR; }
|
if(Ref->author) { Mask |= REF_AUTHOR; }
|
||||||
if(Ref->editor) { Mask |= REF_EDITOR; }
|
if(Ref->editor) { Mask |= REF_EDITOR; }
|
||||||
if(Ref->publisher) { Mask |= REF_PUBLISHER; }
|
if(Ref->publisher) { Mask |= REF_PUBLISHER; }
|
||||||
if(Ref->isbn) { Mask |= REF_ISBN; }
|
|
||||||
|
|
||||||
// TODO(matt): Consider handling the various combinations more flexibly
|
// TODO(matt): Consider handling the various combinations more flexibly, unless we defer this stuff until we have the
|
||||||
|
// reference store, in which we could optionally customise the display of each reference entry
|
||||||
switch(Mask)
|
switch(Mask)
|
||||||
{
|
{
|
||||||
case (REF_URL | REF_TITLE | REF_AUTHOR | REF_PUBLISHER | REF_ISBN):
|
case (REF_TITLE | REF_AUTHOR | REF_PUBLISHER):
|
||||||
{
|
{
|
||||||
CopyString(ReferencesArray[UniqueRefs].ID, Ref->isbn);
|
|
||||||
CopyString(ReferencesArray[UniqueRefs].Source, "%s (%s)", Ref->author, Ref->publisher);
|
CopyString(ReferencesArray[UniqueRefs].Source, "%s (%s)", Ref->author, Ref->publisher);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_AUTHOR | REF_SITE | REF_PAGE | REF_URL):
|
case (REF_AUTHOR | REF_SITE | REF_PAGE):
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
|
||||||
CopyString(ReferencesArray[UniqueRefs].RefTitle, "%s: \"%s\"", Ref->author, Ref->page);
|
CopyString(ReferencesArray[UniqueRefs].RefTitle, "%s: \"%s\"", Ref->author, Ref->page);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_PAGE | REF_URL | REF_TITLE):
|
case (REF_PAGE | REF_TITLE):
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->title);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->title);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->page);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->page);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_SITE | REF_PAGE | REF_URL):
|
case (REF_SITE | REF_PAGE):
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->page);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->page);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_SITE | REF_URL | REF_TITLE):
|
case (REF_SITE | REF_TITLE):
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_TITLE | REF_AUTHOR | REF_ISBN):
|
case (REF_TITLE | REF_AUTHOR):
|
||||||
{
|
{
|
||||||
CopyString(ReferencesArray[UniqueRefs].ID, Ref->isbn);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->author);
|
||||||
CopyString(ReferencesArray[UniqueRefs].Source, Ref->author);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
||||||
CopyString(ReferencesArray[UniqueRefs].URL, "http://www.openisbn.com/isbn/%s", Ref->isbn);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_URL | REF_ARTICLE | REF_AUTHOR):
|
case (REF_ARTICLE | REF_AUTHOR):
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->author);
|
||||||
CopyString(ReferencesArray[UniqueRefs].Source, Ref->author);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->article);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->article);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_URL | REF_TITLE | REF_AUTHOR):
|
case (REF_TITLE | REF_PUBLISHER):
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->publisher);
|
||||||
CopyString(ReferencesArray[UniqueRefs].Source, Ref->author);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_URL | REF_TITLE | REF_PUBLISHER):
|
case REF_TITLE:
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyString(ReferencesArray[UniqueRefs].Source, Ref->publisher);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
case (REF_URL | REF_TITLE):
|
case REF_SITE:
|
||||||
{
|
{
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
|
||||||
case (REF_SITE | REF_URL):
|
|
||||||
{
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
|
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->site);
|
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->site);
|
||||||
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
|
|
||||||
} break;
|
} break;
|
||||||
default: return RC_INVALID_REFERENCE; break;
|
default: return RC_INVALID_REFERENCE; break;
|
||||||
}
|
}
|
||||||
|
@ -3170,8 +3163,7 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen
|
||||||
"<div class=\"cineraMenus %s\">\n"
|
"<div class=\"cineraMenus %s\">\n"
|
||||||
" <span class=\"episode_name\">", StringsDiffer(Config.Theme, "") ? Config.Theme : HMML.metadata.project);
|
" <span class=\"episode_name\">", StringsDiffer(Config.Theme, "") ? Config.Theme : HMML.metadata.project);
|
||||||
CopyStringToBufferHTMLSafe(&CollationBuffers->Menus, HMML.metadata.title);
|
CopyStringToBufferHTMLSafe(&CollationBuffers->Menus, HMML.metadata.title);
|
||||||
CopyStringToBuffer(&CollationBuffers->Menus, "</span>\n"
|
CopyStringToBuffer(&CollationBuffers->Menus, "</span>\n");
|
||||||
" <span id=\"focus-warn\">⚠ Click here to regain focus ⚠</span>\n");
|
|
||||||
|
|
||||||
CopyStringToBuffer(&CollationBuffers->Player,
|
CopyStringToBuffer(&CollationBuffers->Player,
|
||||||
"<div class=\"cineraPlayerContainer\">\n"
|
"<div class=\"cineraPlayerContainer\">\n"
|
||||||
|
@ -3778,17 +3770,17 @@ AppendedIdentifier:
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&ReferenceMenu,
|
CopyStringToBuffer(&ReferenceMenu,
|
||||||
" <div class=\"source\">");
|
" <div class=\"source\">");
|
||||||
CopyStringToBufferHTMLSafe(&ReferenceMenu, ReferencesArray[i].Source);
|
CopyStringToBufferHTMLSafeBreakingOnSlash(&ReferenceMenu, ReferencesArray[i].Source);
|
||||||
CopyStringToBuffer(&ReferenceMenu, "</div>\n"
|
CopyStringToBuffer(&ReferenceMenu, "</div>\n"
|
||||||
" <div class=\"ref_title\">");
|
" <div class=\"ref_title\">");
|
||||||
CopyStringToBufferHTMLSafe(&ReferenceMenu, ReferencesArray[i].RefTitle);
|
CopyStringToBufferHTMLSafeBreakingOnSlash(&ReferenceMenu, ReferencesArray[i].RefTitle);
|
||||||
CopyStringToBuffer(&ReferenceMenu, "</div>\n");
|
CopyStringToBuffer(&ReferenceMenu, "</div>\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&ReferenceMenu,
|
CopyStringToBuffer(&ReferenceMenu,
|
||||||
" <div class=\"ref_title\">");
|
" <div class=\"ref_title\">");
|
||||||
CopyStringToBufferHTMLSafe(&ReferenceMenu, ReferencesArray[i].RefTitle);
|
CopyStringToBufferHTMLSafeBreakingOnSlash(&ReferenceMenu, ReferencesArray[i].RefTitle);
|
||||||
CopyStringToBuffer(&ReferenceMenu, "</div>\n");
|
CopyStringToBuffer(&ReferenceMenu, "</div>\n");
|
||||||
}
|
}
|
||||||
CopyStringToBuffer(&ReferenceMenu,
|
CopyStringToBuffer(&ReferenceMenu,
|
||||||
|
@ -5154,7 +5146,8 @@ enum
|
||||||
LINK_NEXT
|
LINK_NEXT
|
||||||
} link_directions;
|
} link_directions;
|
||||||
|
|
||||||
int InsertNeighbourLink(file_buffer *FromFile, index_metadata *From, index_metadata *To, int LinkDirection, char *ProjectName, bool FromHasOneNeighbour)
|
int
|
||||||
|
InsertNeighbourLink(file_buffer *FromFile, index_metadata *From, index_metadata *To, int LinkDirection, char *ProjectName, bool FromHasOneNeighbour)
|
||||||
{
|
{
|
||||||
if(ReadFileIntoBuffer(FromFile, 0) == RC_SUCCESS)
|
if(ReadFileIntoBuffer(FromFile, 0) == RC_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -5272,7 +5265,8 @@ int InsertNeighbourLink(file_buffer *FromFile, index_metadata *From, index_metad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DeleteNeighbourLinks(file_buffer *File, index_metadata *Metadata)
|
int
|
||||||
|
DeleteNeighbourLinks(file_buffer *File, index_metadata *Metadata)
|
||||||
{
|
{
|
||||||
if(ReadFileIntoBuffer(File, 0) == RC_SUCCESS)
|
if(ReadFileIntoBuffer(File, 0) == RC_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -5293,7 +5287,8 @@ int DeleteNeighbourLinks(file_buffer *File, index_metadata *Metadata)
|
||||||
else { return RC_ERROR_FILE; }
|
else { return RC_ERROR_FILE; }
|
||||||
}
|
}
|
||||||
|
|
||||||
int LinkNeighbours(index *Index, neighbourhood *N, char *BaseFilename, int LinkType)
|
int
|
||||||
|
LinkNeighbours(index *Index, neighbourhood *N, char *BaseFilename, int LinkType)
|
||||||
{
|
{
|
||||||
switch(ReadFileIntoBuffer(&Index->Metadata, 0))
|
switch(ReadFileIntoBuffer(&Index->Metadata, 0))
|
||||||
{
|
{
|
||||||
|
|
|
@ -131,17 +131,6 @@
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cineraMenus > #focus-warn {
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
border-radius: 16px;
|
|
||||||
color: #F00;
|
|
||||||
flex: 1;
|
|
||||||
margin: 0 auto 0 50%;
|
|
||||||
display: none;
|
|
||||||
z-index: 16;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cineraMenus > .menu {
|
.cineraMenus > .menu {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,16 @@ if(creditsMenu)
|
||||||
var sourceMenus = titleBar.querySelectorAll(".menu");
|
var sourceMenus = titleBar.querySelectorAll(".menu");
|
||||||
|
|
||||||
var helpButton = titleBar.querySelector(".help");
|
var helpButton = titleBar.querySelector(".help");
|
||||||
|
window.addEventListener("blur", function(){
|
||||||
|
helpButton.firstElementChild.innerText = "¿";
|
||||||
|
helpButton.firstElementChild.title = "Keypresses will not pass through to Cinera because focus is currently elsewhere.\n\nTo regain focus, please press Tab / Shift-Tab (multiple times) or click somewhere related to Cinera other than the video, e.g. this button";
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("focus", function(){
|
||||||
|
helpButton.firstElementChild.innerText = "?";
|
||||||
|
helpButton.firstElementChild.title = ""
|
||||||
|
});
|
||||||
|
|
||||||
var helpDocumentation = helpButton.querySelector(".help_container");
|
var helpDocumentation = helpButton.querySelector(".help_container");
|
||||||
helpButton.addEventListener("click", function(ev) {
|
helpButton.addEventListener("click", function(ev) {
|
||||||
handleMouseOverMenu(this, ev.type);
|
handleMouseOverMenu(this, ev.type);
|
||||||
|
@ -196,6 +206,13 @@ var playerContainer = document.querySelector(".cineraPlayerContainer")
|
||||||
var cinera = playerContainer.parentNode;
|
var cinera = playerContainer.parentNode;
|
||||||
|
|
||||||
var player = new Player(playerContainer, onRefChanged);
|
var player = new Player(playerContainer, onRefChanged);
|
||||||
|
|
||||||
|
var cineraViewStorageItem = "cineraView";
|
||||||
|
if(viewsMenu && localStorage.getItem(cineraViewStorageItem))
|
||||||
|
{
|
||||||
|
toggleTheatreMode();
|
||||||
|
}
|
||||||
|
|
||||||
window.addEventListener("resize", function() { player.updateSize(); });
|
window.addEventListener("resize", function() { player.updateSize(); });
|
||||||
document.addEventListener("keydown", function(ev) {
|
document.addEventListener("keydown", function(ev) {
|
||||||
var key = ev.key;
|
var key = ev.key;
|
||||||
|
@ -224,14 +241,6 @@ var prevEpisode = playerContainer.querySelector(".episodeMarker.prev");
|
||||||
var nextEpisode = playerContainer.querySelector(".episodeMarker.next");
|
var nextEpisode = playerContainer.querySelector(".episodeMarker.next");
|
||||||
var testMarkers = playerContainer.querySelectorAll(".marker");
|
var testMarkers = playerContainer.querySelectorAll(".marker");
|
||||||
|
|
||||||
window.addEventListener("blur", function(){
|
|
||||||
document.getElementById("focus-warn").style.display = "block";
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener("focus", function(){
|
|
||||||
document.getElementById("focus-warn").style.display = "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
var colouredItems = playerContainer.querySelectorAll(".author, .member, .project");
|
var colouredItems = playerContainer.querySelectorAll(".author, .member, .project");
|
||||||
for(i = 0; i < colouredItems.length; ++i)
|
for(i = 0; i < colouredItems.length; ++i)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +253,12 @@ for(var i = 0; i < topicDots.length; ++i)
|
||||||
setDotLightness(topicDots[i]);
|
setDotLightness(topicDots[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastAnnotationStorageItem = "cineraTimecode_" + window.location.pathname;
|
||||||
|
var lastAnnotation;
|
||||||
if(location.hash) {
|
if(location.hash) {
|
||||||
player.setTime(location.hash.startsWith('#') ? location.hash.substr(1) : location.hash);
|
player.setTime(location.hash.startsWith('#') ? location.hash.substr(1) : location.hash);
|
||||||
}
|
}
|
||||||
|
else if(lastAnnotation = localStorage.getItem(lastAnnotationStorageItem))
|
||||||
|
{
|
||||||
|
player.setTime(lastAnnotation);
|
||||||
|
}
|
||||||
|
|
|
@ -228,6 +228,14 @@ Player.prototype.updateProgress = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.currentMarker) {
|
if (this.currentMarker) {
|
||||||
|
if(this.currentMarkerIdx == this.markers.length - 1)
|
||||||
|
{
|
||||||
|
localStorage.removeItem(lastAnnotationStorageItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localStorage.setItem(lastAnnotationStorageItem, this.currentMarker.timestamp);
|
||||||
|
}
|
||||||
this.currentMarker.el.classList.add("current");
|
this.currentMarker.el.classList.add("current");
|
||||||
this.scrollTo = this.currentMarker.el.offsetTop + this.currentMarker.el.offsetHeight/2.0;
|
this.scrollTo = this.currentMarker.el.offsetTop + this.currentMarker.el.offsetHeight/2.0;
|
||||||
this.scrollPosition = this.markersContainer.scrollTop;
|
this.scrollPosition = this.markersContainer.scrollTop;
|
||||||
|
@ -283,12 +291,16 @@ Player.prototype.onYoutubePlayerStateChange = function(ev) {
|
||||||
if (ev.data == YT.PlayerState.PLAYING) {
|
if (ev.data == YT.PlayerState.PLAYING) {
|
||||||
this.playing = true;
|
this.playing = true;
|
||||||
this.currentTime = this.youtubePlayer.getCurrentTime();
|
this.currentTime = this.youtubePlayer.getCurrentTime();
|
||||||
} else if (ev.data == YT.PlayerState.PAUSED || ev.data == YT.PlayerState.BUFFERING) {
|
|
||||||
this.playing = false;
|
|
||||||
this.currentTime = this.youtubePlayer.getCurrentTime();
|
|
||||||
this.updateProgress();
|
|
||||||
} else {
|
} else {
|
||||||
this.playing = false;
|
this.playing = false;
|
||||||
|
if (ev.data == YT.PlayerState.PAUSED || ev.data == YT.PlayerState.BUFFERING) {
|
||||||
|
this.currentTime = this.youtubePlayer.getCurrentTime();
|
||||||
|
this.updateProgress();
|
||||||
|
} else if (ev.data == YT.PlayerState.ENDED) {
|
||||||
|
localStorage.removeItem(lastAnnotationStorageItem);
|
||||||
|
this.currentTime = null;
|
||||||
|
this.updateProgress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.buffering = ev.data == YT.PlayerState.BUFFERING;
|
this.buffering = ev.data == YT.PlayerState.BUFFERING;
|
||||||
|
@ -482,7 +494,7 @@ function toggleTheatreMode() {
|
||||||
viewItems[0].setAttribute("data-id", "regular");
|
viewItems[0].setAttribute("data-id", "regular");
|
||||||
viewItems[0].setAttribute("title", "Regular mode");
|
viewItems[0].setAttribute("title", "Regular mode");
|
||||||
viewItems[0].firstChild.nodeValue = "📺";
|
viewItems[0].firstChild.nodeValue = "📺";
|
||||||
} cineraProps.V = views.THEATRE; break;
|
} cineraProps.V = views.THEATRE; localStorage.setItem(cineraViewStorageItem, views.THEATRE); break;
|
||||||
case views.SUPERTHEATRE:
|
case views.SUPERTHEATRE:
|
||||||
{
|
{
|
||||||
leaveFullScreen_();
|
leaveFullScreen_();
|
||||||
|
@ -502,7 +514,7 @@ function toggleTheatreMode() {
|
||||||
viewItems[0].setAttribute("data-id", "theatre");
|
viewItems[0].setAttribute("data-id", "theatre");
|
||||||
viewItems[0].setAttribute("title", "Theatre mode");
|
viewItems[0].setAttribute("title", "Theatre mode");
|
||||||
viewItems[0].firstChild.nodeValue = "🎭";
|
viewItems[0].firstChild.nodeValue = "🎭";
|
||||||
} cineraProps.V = views.REGULAR; break;
|
} cineraProps.V = views.REGULAR; localStorage.removeItem(cineraViewStorageItem); break;
|
||||||
}
|
}
|
||||||
player.updateSize();
|
player.updateSize();
|
||||||
}
|
}
|
||||||
|
@ -518,12 +530,12 @@ function toggleSuperTheatreMode()
|
||||||
case views.THEATRE:
|
case views.THEATRE:
|
||||||
{
|
{
|
||||||
enterFullScreen_();
|
enterFullScreen_();
|
||||||
} cineraProps.V = views.SUPERTHEATRE; break;
|
} cineraProps.V = views.SUPERTHEATRE; localStorage.setItem(cineraViewStorageItem, views.SUPERTHEATRE); break;
|
||||||
case views.SUPERTHEATRE:
|
case views.SUPERTHEATRE:
|
||||||
{
|
{
|
||||||
leaveFullScreen_();
|
leaveFullScreen_();
|
||||||
toggleTheatreMode();
|
toggleTheatreMode();
|
||||||
} cineraProps.V = views.REGULAR; break;
|
} cineraProps.V = views.REGULAR; localStorage.removeItem(cineraViewStorageItem); break;
|
||||||
}
|
}
|
||||||
player.updateSize();
|
player.updateSize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue