diff --git a/cinera/cinera.c b/cinera/cinera.c index 7672db7..5481538 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -16,7 +16,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 5, - .Patch = 51 + .Patch = 52 }; // TODO(matt): Copy in the DB 3 stuff from cinera_working.c @@ -1348,7 +1348,6 @@ SearchCredentials(buffer *CreditsMenu, bool *HasCreditsMenu, char *Person, char { CopyStringToBuffer(CreditsMenu, "
\n" - "
\n" " Credits\n" "
\n"); @@ -3433,7 +3432,6 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen CopyStringToBuffer(&ReferenceMenu, "
\n" " References ▼\n" - "
\n" "
\n"); if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, CurrentRef, Anno) == RC_INVALID_REFERENCE) @@ -3589,7 +3587,6 @@ AppendedIdentifier: CopyStringToBuffer(&QuoteMenu, "
\n" " Quotes ▼\n" - "
\n" "
\n"); HasQuoteMenu = TRUE; @@ -3969,7 +3966,14 @@ AppendedIdentifier: "
\n" "
🏟
\n" "
\n" - "
\n"); + "
\n" + "
\n" + " 🔗\n" + " \n" + "
\n"); if(HasCreditsMenu) { @@ -3992,7 +3996,7 @@ AppendedIdentifier: if(HasFilterMenu) { CopyStringToBuffer(&CollationBuffers->Menus, - " z Toggle filter mode V Revert filter to original state\n"); + " V Revert filter to original state Y Select link (requires manual Ctrl-c)\n"); } else { @@ -4037,6 +4041,9 @@ AppendedIdentifier: " f Filter\n"); } + CopyStringToBuffer(&CollationBuffers->Menus, + " y Link\n"); + if(HasCreditsMenu) { CopyStringToBuffer(&CollationBuffers->Menus, @@ -4206,7 +4213,10 @@ AppendedIdentifier: "

Filter Menu

\n" " x, Space Toggle category and focus next
\n" " X, ShiftSpace Toggle category and focus previous
\n" - " v Invert topics / media as per focus\n"); + " v Invert topics / media as per focus\n" + "\n" + "

Filter and Link Menus

\n" + " z Toggle filter / linking mode\n"); } else { @@ -4214,7 +4224,10 @@ AppendedIdentifier: "

Filter Menu

\n" " x, Space Toggle category and focus next
\n" " X, ShiftSpace Toggle category and focus previous
\n" - " v Invert topics / media as per focus\n"); + " v Invert topics / media as per focus\n" + "\n" + "

Filter and Link Menus

\n" + " z Toggle filter / linking mode\n"); } CopyStringToBuffer(&CollationBuffers->Menus, "\n"); diff --git a/cinera/cinera.css b/cinera/cinera.css index a36ecae..9b690c7 100644 --- a/cinera/cinera.css +++ b/cinera/cinera.css @@ -135,15 +135,8 @@ position: relative; } -.cineraMenus > .menu .mouse_catcher { - position: absolute; - height: 100%; - width: 100%; - top: 0; - right: 0; -} - .cineraMenus > .menu.filter.responsible, +.cineraMenus > .menu.link.responsible, .cineraMenus .filter_content.responsible, .cineraMenus .filter_content.responsible .cineraText, .cineraMenus > .menu > .filter_container .filter_mode.responsible { @@ -249,10 +242,12 @@ display: block; } -.cineraMenus > .menu .refs, +.cineraMenus > .menu .quotes_container, +.cineraMenus > .menu .references_container, .cineraMenus > .menu .filter_container, .cineraMenus > .menu .views_container, -.cineraMenus > .menu .credits_container{ +.cineraMenus > .menu .link_container, +.cineraMenus > .menu .credits_container { border: 1px solid; border-top: none; display: none; @@ -265,7 +260,8 @@ z-index: 1; } -.cineraMenus > .menu .refs { +.cineraMenus > .menu .refs, +.cineraMenus > .menu .link_container { width: 350px; } @@ -277,13 +273,7 @@ min-width: 240px; } -/*.title > .menu:hover .refs,*/ -.cineraMenus > .menu.quotes .refs.visible, -.cineraMenus > .menu.references .refs.visible, -/*.title > .menu:hover .filter_container,*/ -.cineraMenus > .menu.filter .filter_container.visible, -.cineraMenus > .menu.credits .credits_container.visible { -/*.title > .menu:hover .credits_container {*/ +.cineraMenus > .menu .visible { display: block; } @@ -291,15 +281,15 @@ flex-direction: column; } +.cineraMenus > .menu { + cursor: default; +} + .cineraMenus > .menu > .view, .cineraMenus > .menu > .views_container .view { cursor: pointer; } -.cineraMenus > .menu > .credits_container .credit { - cursor: default; -} - .cineraMenus > .menu > .credits_container .credit .person { flex-grow: 1; text-decoration: none; @@ -320,10 +310,18 @@ } .cineraMenus > .menu > .refs .ref .timecode, -.cineraMenus > .menu > .filter_container .filter_mode { +.cineraMenus > .menu > .filter_container .filter_mode, +.cineraMenus > .menu > .link_container #cineraLinkMode { font-size: 12px; } +.cineraMenus > .menu > .filter_container .filter_mode, +.cineraMenus > .menu > .link_container #cineraLinkMode { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} + .cineraMenus > .menu > .refs .ref .timecode { cursor: pointer; display: inline-block; @@ -379,7 +377,8 @@ margin-right: 4px; } -.cineraMenus > .menu > .filter_container .filter_mode { +.cineraMenus > .menu > .filter_container .filter_mode, +.cineraMenus > .menu > .link_container #cineraLinkMode { cursor: pointer; border-bottom: 1px solid; text-align: center; @@ -448,6 +447,15 @@ font-variant: small-caps; } +.cineraMenus > .menu > .link_container #cineraLink { + border: 0; + cursor: pointer; + height: 100%; + padding: 4px; + resize: none; + width: 100%; +} + .cineraPlayerContainer { display: flex; flex-direction: row; diff --git a/cinera/cinera_player_post.js b/cinera/cinera_player_post.js index 533c3b3..dcf3d53 100644 --- a/cinera/cinera_player_post.js +++ b/cinera/cinera_player_post.js @@ -131,6 +131,7 @@ var cineraProps = { var viewsMenu = titleBar.querySelector(".views"); if(viewsMenu) { + menuState.push(viewsMenu); var viewsContainer = viewsMenu.querySelector(".views_container"); viewsMenu.addEventListener("mouseenter", function(ev) { handleMouseOverViewsMenu(); @@ -159,6 +160,26 @@ if(viewsMenu) } } +var baseURL = location.hash ? (location.toString().substr(0, location.toString().length - location.hash.length)) : location; +var linkMenu = titleBar.querySelector(".link_container"); +linkAnnotation = true; +if(linkMenu) +{ + menuState.push(linkMenu); + + var linkMode = linkMenu.querySelector("#cineraLinkMode"); + var link = linkMenu.querySelector("#cineraLink"); + + linkMode.addEventListener("click", function(ev) { + toggleLinkMode(linkMode, link); + }); + + link.addEventListener("click", function(ev) { + CopyToClipboard(link); + toggleMenuVisibility(linkMenu); + }); +} + var creditsMenu = titleBar.querySelector(".credits_container"); if(creditsMenu) { @@ -237,7 +258,7 @@ document.addEventListener("keydown", function(ev) { key = "capitalSpace"; } - if(handleKey(key) == true && focusedElement) + if(!ev.getModifierState("Control") && handleKey(key) == true && focusedElement) { ev.preventDefault(); } diff --git a/cinera/cinera_player_pre.js b/cinera/cinera_player_pre.js index 2a7ee7c..ebc4414 100644 --- a/cinera/cinera_player_pre.js +++ b/cinera/cinera_player_pre.js @@ -267,6 +267,7 @@ Player.prototype.doFrame = function() { } this.nextFrame = requestAnimationFrame(this.doFrame.bind(this)); + updateLink(); }; Player.prototype.onYoutubePlayerReady = function() { @@ -331,13 +332,83 @@ Player.youtubePlayerCount = 0; // NOTE(matt): Hereafter is my stuff. Beware! +function toggleFilterMode() { + if(filterMode == "inclusive") + { + filterModeElement.classList.remove("inclusive"); + filterModeElement.classList.add("exclusive"); + filterMode = "exclusive"; + } + else + { + filterModeElement.classList.remove("exclusive"); + filterModeElement.classList.add("inclusive"); + filterMode = "inclusive"; + } + applyFilter(); +} + +function updateLink() +{ + if(link && player) + { + if(linkAnnotation == true) + { + if(player.currentMarker) + { + link.value = baseURL + "#" + player.currentMarker.timestamp; + } + else + { + link.value = baseURL; + } + } + else + { + link.value = baseURL + "#" + Math.round(player.youtubePlayer.getCurrentTime()); + } + } +} + +function toggleLinkMode(linkMode, link) +{ + linkAnnotation = !linkAnnotation; + if(linkAnnotation == true) + { + linkMode.textContent = "Link to current annotation"; + } + else + { + linkMode.textContent = "Link to nearest second"; + } + updateLink(); +} + +function toggleFilterOrLinkMode() +{ + for(menuIndex in menuState) + { + if(menuState[menuIndex].classList.contains("filter_container") && menuState[menuIndex].classList.contains("visible")) + { + toggleFilterMode(); + } + if(menuState[menuIndex].classList.contains("link_container") && menuState[menuIndex].classList.contains("visible")) + { + toggleLinkMode(linkMode, link); + } + } +} + function toggleMenuVisibility(element) { if(element.classList.contains("visible")) { element.classList.remove("visible"); element.parentNode.classList.remove("visible"); - focusedElement.classList.remove("focused"); - focusedElement = null; + if(focusedElement) + { + focusedElement.classList.remove("focused"); + focusedElement = null; + } if(focusedIdentifier) { focusedIdentifier.classList.remove("focused"); @@ -536,6 +607,27 @@ function toggleSuperTheatreMode() player.updateSize(); } +function AscribeTemporaryResponsibility(Element, Milliseconds) +{ + if(!Element.classList.contains("responsible")) + { + Element.classList.add("responsible"); + } + setTimeout(function() { Element.classList.remove("responsible"); }, Milliseconds); +} + +function SelectText(inputElement) +{ + inputElement.select(); +} + +function CopyToClipboard(inputElement) +{ + SelectText(inputElement); + document.execCommand("copy"); + AscribeTemporaryResponsibility(linkMenu.parentNode, 8000); +} + function handleKey(key) { var gotKey = true; switch (key) { @@ -557,6 +649,13 @@ function handleKey(key) { toggleMenuVisibility(filterMenu) } } break; + case "y": { + if(linkMenu) + { + toggleMenuVisibility(linkMenu) + } + break; + } case "c": { if(creditsMenu) { @@ -917,7 +1016,7 @@ function handleKey(key) { } break; case "z": { - toggleFilterMode(); + toggleFilterOrLinkMode(); } break; case "v": { @@ -960,6 +1059,20 @@ function handleKey(key) { location = nextEpisode.href; } } break; + case 'Y': { + if(cineraLink) + { + if(linkAnnotation == false && player.playing) + { + player.pause(); + } + if(linkMenu && !linkMenu.classList.contains("visible")) + { + toggleMenuVisibility(linkMenu); + } + SelectText(cineraLink); + } + } default: { gotKey = false; } break; @@ -998,22 +1111,6 @@ function applyFilter() { } } -function toggleFilterMode() { - if(filterMode == "inclusive") - { - filterModeElement.classList.remove("inclusive"); - filterModeElement.classList.add("exclusive"); - filterMode = "exclusive"; - } - else - { - filterModeElement.classList.remove("exclusive"); - filterModeElement.classList.add("inclusive"); - filterMode = "inclusive"; - } - applyFilter(); -} - function filterItemToggle(filterItem) { var selectedCategory = filterItem.classList[1]; filterState[selectedCategory].off = !filterState[selectedCategory].off; @@ -1356,6 +1453,10 @@ function handleMouseOverMenu(menu, eventType) { toggleMenuVisibility(filterMenu); } + else if(menu.classList.contains("link")) + { + toggleMenuVisibility(linkMenu); + } else if(menu.classList.contains("credits")) { toggleMenuVisibility(creditsMenu);