You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue provides only another SSCCE to the #103 issue. In my opinion the explanation in the other issue applies to this SSCCE too. Like #103 this SSCCE could be added to the list in #105 as well.
Version
OS: Windows 10 1909 (Build 18363.900)
Elm: 0.19.1
Thrown exceptions
The thrown exceptions differ between Chrome and Firefox. Added so it is easier to find for other people. But the exception text may vary between the expected types.
Chrome 83.0.4103.116 (64-Bit)
Uncaught TypeError: Cannot read property 'a' of undefined
moduleMainexposing (main)
importBrowserimportHtmlexposing (Html, br, button, div, source, text, video)
importHtml.Attributesexposing (autoplay, id, loop, property, src, style, type_)
importHtml.Eventsexposing (on, onClick)
importJson.DecodeasJDimportJson.EncodeasJEtype alias Model={ currentTime :Float, duration :Float, videoVisible :Bool, selection :Maybe(GroupId,ItemId)}initialModel:ModelinitialModel ={ currentTime =0, duration =0, videoVisible =False, selection =Nothing}type MediaMsg=MediaMsgTimeupdate{ currentTime :Float, duration :Float}type VideoPageMsg=VideoPageMsgLeave|VideoPageMsgMediaMsgMediaMsgtype GroupId=GroupIdStringgroupIdEncoder:GroupId->JE.ValuegroupIdEncoder (GroupId value)=JE.string value
type ItemId=ItemIdStringitemIdEncoder:ItemId->JE.ValueitemIdEncoder (ItemId value)=JE.string value
type ListPageMsg=ListPageMsgSelectGroupIdItemIdtype Msg=VideoPageVideoPageMsg|ListPageListPageMsgupdate:Msg->Model->Modelupdate msg model =case msg ofVideoPage videoPageMsg ->case videoPageMsg ofVideoPageMsgMediaMsg(MediaMsgTimeupdate{ currentTime, duration })->{ model | currentTime = currentTime, duration = duration }VideoPageMsgLeave->{ model | videoVisible =False}ListPage listPageMsg ->case listPageMsg ofListPageMsgSelect groupId itemId ->let
_ =Debug.log "Attempt to store selection with" listPageMsg
_ =-- In my case i am storing the selection in the local storage,-- so i can just use F5 to reload the page, without reselecting.Debug.log "Selection json which can be sent to local storage"<|JE.encode 0<|JE.object
[("groupId", groupIdEncoder groupId ),("itemId", itemIdEncoder itemId )]in{ model | selection =Just( groupId, itemId ), videoVisible =True}timeupdateDecoder:JD.Decoder { currentTime : Float, duration : Float }
timeupdateDecoder =JD.map2 (\currentTime duration ->{ currentTime = currentTime, duration = duration })(JD.at ["target","currentTime"]JD.float)(JD.at ["target","duration"]JD.float)viewList:HtmlListPageMsgviewList =
div [][ button [ onClick <|ListPageMsgSelect(GroupId"fpie73")(ItemId"72ba27hs")][ text "Open video"]]viewVideo:HtmlVideoPageMsgviewVideo =
div [][ button [ onClick <|VideoPageMsgLeave][ text "Leave video"], br [][], br [][], video
[ autoplay True, property "muted"(JE.string "muted"), loop True, on "timeupdate"(timeupdateDecoder |>JD.map MediaMsgTimeupdate)][ source
[ id "mp4", src "http://www.w3schools.com/html/movie.mp4", type_ "video/mp4"][]]|>Html.map VideoPageMsgMediaMsg]view:Model->HtmlMsgview model =
div
[ style "transform""scale(2, 2)", style "transform-origin""left top"][if model.videoVisible then
viewVideo |>Html.map VideoPageelse
viewList |>Html.map ListPage, div [][ br [][], text <|String.fromFloat model.currentTime ++"/"++String.fromFloat model.duration
]]main:Program()ModelMsgmain =Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
Workaround
In #103 are also workarounds described. Additional Html.map identity on the pages with same "map depth" works, but is not safe, because in future there could be another page with the same "map depth".
In my case i have wrapped the event in a custom element, which disconnects the event listener as soon as the element is removed from the DOM. The custom element controls the playstate too, so i do not need a port for pause/resume. Place this video-control custom element inside the video element. The custom element is defined as followed:
// This is based on the idea from baffalop on Slack// https://elmlang.slack.com/archives/C0CJ3SBBM/p1593872335052000// Place this custom element inside the video element.customElements.define('video-control',classVideoControlextendsHTMLElement{staticgetobservedAttributes(){return['playstate'];}constructor(){super();this.boundVideoTimeupdated=this.videoTimeupdated.bind(this);}attributeChangedCallback(name,oldValue,newValue){constparentElement=this.parentElement;if(name==="playstate"){VideoControl.updatePlayState(parentElement,newValue);}}/** * @param {HTMLVideoElement} videoElement * @param {boolean} value * @return {string} */staticupdatePlayState(videoElement,value){if(!videoElement)return;if(value==="play"){videoElement.play();}elseif(value=="pause"){videoElement.pause();}}/** * @param {HTMLVideoElement} videoElement */videoTimeupdated(){constvideoElement=this.videoElement;if(!videoElement||videoElement.tagName!=="VIDEO")return;this.dispatchEvent(newCustomEvent("timeupdate",{detail: {currentTime: videoElement.currentTime,duration: videoElement.duration}}));}/** * @param {HTMLVideoElement} videoElement */connectVideoElement(videoElement){this.disconnectVideoElement();if(!videoElement||videoElement.tagName!=="VIDEO")return;this.videoElement=videoElement;// Wir müssen timeupdate hier kapseln, da das timeupdate vom Video-Element// einen Laufzeitfehler erzeugt, sollte die Seite verlassen werden, bevor// das Video angehalten wurde.VideoControl.updatePlayState(videoElement,this.getAttribute("playstate"));videoElement.addEventListener('timeupdate',this.boundVideoTimeupdated,false);}/** * @param {HTMLVideoElement} videoElement */disconnectVideoElement(){constvideoElement=this.videoElement;if(!videoElement||videoElement.tagName!=="VIDEO")return;videoElement.removeEventListener('timeupdate',this.boundVideoTimeupdated,false);this.videoElement=null;}connectedCallback(){this.connectVideoElement(this.parentElement);}disconnectedCallback(){this.disconnectVideoElement();}});
The text was updated successfully, but these errors were encountered:
Problem
This issue provides only another SSCCE to the #103 issue. In my opinion the explanation in the other issue applies to this SSCCE too. Like #103 this SSCCE could be added to the list in #105 as well.
Version
OS: Windows 10 1909 (Build 18363.900)
Elm: 0.19.1
Thrown exceptions
The thrown exceptions differ between Chrome and Firefox. Added so it is easier to find for other people. But the exception text may vary between the expected types.
Chrome 83.0.4103.116 (64-Bit)
Uncaught TypeError: Cannot read property 'a' of undefined
Firefox 78.0.2 (64-Bit)
TypeError: _v0 is undefined
SSCCEE
https://ellie-app.com/9pbMRZHxRkVa1
Workaround
In #103 are also workarounds described. Additional
Html.map identity
on the pages with same "map depth" works, but is not safe, because in future there could be another page with the same "map depth".In my case i have wrapped the event in a custom element, which disconnects the event listener as soon as the element is removed from the DOM. The custom element controls the playstate too, so i do not need a port for pause/resume. Place this
video-control
custom element inside thevideo
element. The custom element is defined as followed:The text was updated successfully, but these errors were encountered: