cinera: Share link (to current annotation)
This commit is contained in:
		
							parent
							
								
									426cbfccba
								
							
						
					
					
						commit
						ce367b00aa
					
				|  | @ -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, | ||||
|                         "            <div class=\"menu credits\">\n" | ||||
|                         "                <div class=\"mouse_catcher\"></div>\n" | ||||
|                         "                <span>Credits</span>\n" | ||||
|                         "                <div class=\"credits_container\">\n"); | ||||
| 
 | ||||
|  | @ -3433,7 +3432,6 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen | |||
|                         CopyStringToBuffer(&ReferenceMenu, | ||||
|                                 "            <div class=\"menu references\">\n" | ||||
|                                 "                <span>References ▼</span>\n" | ||||
|                                 "                <div class=\"mouse_catcher\"></div>\n" | ||||
|                                 "                <div class=\"refs references_container\">\n"); | ||||
| 
 | ||||
|                         if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, CurrentRef, Anno) == RC_INVALID_REFERENCE) | ||||
|  | @ -3589,7 +3587,6 @@ AppendedIdentifier: | |||
|                     CopyStringToBuffer(&QuoteMenu, | ||||
|                             "            <div class=\"menu quotes\">\n" | ||||
|                             "                <span>Quotes ▼</span>\n" | ||||
|                             "                <div class=\"mouse_catcher\"></div>\n" | ||||
|                             "                <div class=\"refs quotes_container\">\n"); | ||||
| 
 | ||||
|                     HasQuoteMenu = TRUE; | ||||
|  | @ -3969,7 +3966,14 @@ AppendedIdentifier: | |||
|                 "                <div class=\"views_container\">\n" | ||||
|                 "                    <div class=\"view\" data-id=\"super\" title=\"SUPERtheatre mode\">🏟</div>\n" | ||||
|                 "                </div>\n" | ||||
|                 "            </div>\n"); | ||||
|                 "            </div>\n" | ||||
| 				"            <div class=\"menu link\">\n" | ||||
| 				"                <span>🔗</span>\n" | ||||
| 				"                <div class=\"link_container\">\n" | ||||
| 				"                    <div id=\"cineraLinkMode\">Link to current annotation</div>\n" | ||||
| 				"                    <textarea title=\"Click to copy to clipboard\" id=\"cineraLink\" readonly spellcheck=\"false\"></textarea>\n" | ||||
| 				"                </div>\n" | ||||
| 				"            </div>\n"); | ||||
| 
 | ||||
|         if(HasCreditsMenu) | ||||
|         { | ||||
|  | @ -3992,7 +3996,7 @@ AppendedIdentifier: | |||
|         if(HasFilterMenu) | ||||
|         { | ||||
|             CopyStringToBuffer(&CollationBuffers->Menus, | ||||
|                     "                    <span class=\"help_key\">z</span> <span class=\"help_text\">Toggle filter mode</span> <span class=\"help_key\">V</span> <span class=\"help_text\">Revert filter to original state</span>\n"); | ||||
|                     "                    <span class=\"help_key\">V</span> <span class=\"help_text\">Revert filter to original state</span> <span class=\"help_key\">Y</span> <span class=\"help_text\">Select link (requires manual Ctrl-c)</span>\n"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | @ -4037,6 +4041,9 @@ AppendedIdentifier: | |||
|                     "                    <span class=\"help_key unavailable\">f</span> <span class=\"help_text unavailable\">Filter</span>\n"); | ||||
|         } | ||||
| 
 | ||||
| 		CopyStringToBuffer(&CollationBuffers->Menus, | ||||
| 				"                    <span class=\"help_key\">y</span> <span class=\"help_text\">Link</span>\n"); | ||||
| 
 | ||||
|         if(HasCreditsMenu) | ||||
|         { | ||||
|             CopyStringToBuffer(&CollationBuffers->Menus, | ||||
|  | @ -4206,7 +4213,10 @@ AppendedIdentifier: | |||
|                     "                    <h2>Filter Menu</h2>\n" | ||||
|                     "                    <span class=\"help_key\">x</span>, <span class=\"help_key word\">Space</span> <span class=\"help_text\">Toggle category and focus next</span><br>\n" | ||||
|                     "                    <span class=\"help_key\">X</span>, <span class=\"help_key word modifier\">Shift</span><span class=\"help_key word\">Space</span> <span class=\"help_text\">Toggle category and focus previous</span><br>\n" | ||||
|                     "                    <span class=\"help_key\">v</span> <span class=\"help_text\">Invert topics / media as per focus</span>\n"); | ||||
|                     "                    <span class=\"help_key\">v</span> <span class=\"help_text\">Invert topics / media as per focus</span>\n" | ||||
|                     "\n" | ||||
|                     "                    <h2>Filter and Link Menus</h2>\n" | ||||
| 					"                    <span class=\"help_key\">z</span> <span class=\"help_text\">Toggle filter / linking mode</span>\n"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | @ -4214,7 +4224,10 @@ AppendedIdentifier: | |||
|                     "                    <h2><span class=\"unavailable\">Filter Menu</span></h2>\n" | ||||
|                     "                    <span class=\"help_key unavailable\">x</span>, <span class=\"help_key word unavailable\">Space</span> <span class=\"help_text unavailable\">Toggle category and focus next</span><br>\n" | ||||
|                     "                    <span class=\"help_key unavailable\">X</span>, <span class=\"help_key word modifier unavailable\">Shift</span><span class=\"help_key word unavailable\">Space</span> <span class=\"help_text unavailable\">Toggle category and focus previous</span><br>\n" | ||||
|                     "                    <span class=\"help_key unavailable\">v</span> <span class=\"help_text unavailable\">Invert topics / media as per focus</span>\n"); | ||||
|                     "                    <span class=\"help_key unavailable\">v</span> <span class=\"help_text unavailable\">Invert topics / media as per focus</span>\n" | ||||
|                     "\n" | ||||
|                     "                    <h2><span class=\"unavailable\">Filter</span> and Link Menus</h2>\n" | ||||
| 					"                    <span class=\"help_key\">z</span> <span class=\"help_text\">Toggle <span class=\"unavailable\">filter /</span> linking mode</span>\n"); | ||||
|         } | ||||
| 
 | ||||
|         CopyStringToBuffer(&CollationBuffers->Menus, "\n"); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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(); | ||||
|     } | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue