[Widget] List Recordings and play selected Recording in an Popup

Hi, I’m trying to create a widget that lists recordings taken with my camera with the option to play them in a popup.

uid: CAM_Recordings
tags: []
props:
  parameters:
    - description: Title of The Recording List
      label: Title
      name: title
      required: false
      type: TEXT
    - default: https://xxxx.de/ipcamera/a0470d9ac6/{recording}.mp4
      name: URL
      required: true
      type: TEXT
    - context: item
      description: Komma seperated List
      label: Komma Seperated List of Recordings
      name: recordings
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Apr 3, 2023, 5:11:42 AM
component: f7-card
config:
  title: =props.title
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: oh-repeater
            config:
              for: size
              fragment: true
              sourceType: range
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: list
                    fragment: true
                    in: =[items[props.recordings].state.split(",")[loop.size].split(",")[0]]
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: selectedRecording
                          actionVariableValue: =[items[props.recordings].state.split(",")[loop.size].split(",")[0]]
                          outline: true
                          round: false
                          style:
                            --f7-button-border-color: var(--f7-card-outline-border-color)
                          text: =loop.list
                          popupOpen: .selectetRecording_po
    - component: f7-popup
      config:
        closeByBackdropClick: true
        closeOnEscape: true
        swipeToClose: true
        class:
          - selectetRecording_po
      slots:
        default:
          - component: oh-video-card
            config:
              title: =vars.selectedRecording
              url: =props.URL.replace('{recording}', vars.selectedRecording)
              class:
                - padding

The widget asks for a comma separated list, e.g. video1.mp4,video2.mp4,video3.mp4…

So far, this list is also split up by the oh-repeater and set as a variable after a selection (vars.selectedRecording)

After the recording has been selected, it also starts in an popoup, after I close the popup and want to start the other recording, the first selection is still played, only after clicking on “redraw” and subsequent new selection is the other recording is also played.

Does anyone know what I’m doing wrong ?

Splittet List :

After Klicking the first Video :

After Klicking the second Video :

In the Last Screenshot, the Title of the Video Changed Correctly, but the recording it self ist the “first one”
Only after clicking on “redraw” and subsequent new selection is the other recording is also played.

Without seeing an example of the actual state of your recordings item, it is hard to say exactly what this is doing. However, your second repeater doesn’t seem to be actually repeating anything, because the in property does not appear to be an array. (In fact, it uses the exact same expression that you are using to set the selectedRecord variable.)

You can make the popup itself refresh whenever the variable changes by adding

key: =Math.random() + (vars.selectedRecord || "")

to the popup’s config.

Hi,
Thanks for your help,
I have now included the change
but unfortunately the widget editor crashed after clicking on one of the videos, what’s going on there now?

My item state currently looks like this:

Current Code :

uid: CAM_Recordings
tags: []
props:
  parameters:
    - description: Title of The Recording List
      label: Title
      name: title
      required: false
      type: TEXT
    - default: https://xxx.de/ipcamera/a0470d9ac6/{recording}.mp4
      name: URL
      required: true
      type: TEXT
    - context: item
      description: Komma seperated List
      label: Komma Seperated List of Recordings
      name: recordings
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Apr 3, 2023, 8:21:49 AM
component: f7-card
config:
  key: =Math.random() + (vars.selectedRecording || "")
  title: =props.title
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: array
              for: list
              fragment: true
              in: =items[props.recordings].state.split(",")
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: selectedRecording
                    actionVariableValue: =loop.list
                    outline: true
                    round: false
                    style:
                      --f7-button-border-color: var(--f7-card-outline-border-color)
                    text: =loop.list
                    popoverOpen: .selectetRecording_po
    - component: f7-popup
      config:
        closeByBackdropClick: true
        closeOnEscape: true
        swipeToClose: true
        class:
          - selectetRecording_po
      slots:
        default:
          - component: oh-video-card
            config:
              title: =vars.selectedRecording
              url: =props.URL.replace('{recording}', vars.selectedRecording)
              class:
                - padding

That new code looks much cleaner. You probably don’t even need the key property with that code, it should work without it, I suspect. But, if it’s still giving you trouble, try moving the key property to the video card config instead to just force a refresh of the video card (there may have been some strange race condition between the variable and the popup when the key value was in the popup or base component).

Hi again,
still no luck.
without the key property, and also inside the video Card config: section tested.

same behavior:

After the recording has been selected, it also starts in an popoup, after I close the popup and want to start the other recording, the first selection is still played, only after clicking on “redraw” and subsequent new selection is the other recording is also played.

What version of OH are you using?

I´m using Openhab 3.4.2,

I Modified this Widget Again, without a popup-feature, in this Variant the reload thing with “key” is working.

I don´t know whats wrong in my “first” Version.

Working one :

uid: CAM_Recordings_et
tags: []
props:
  parameters:
    - description: Title of The Recording List
      label: Title
      name: title
      required: false
      type: TEXT
    - default: https://xxx.de/ipcamera/a0470d9ac6/{recording}.mp4
      name: URL
      required: true
      type: TEXT
    - context: item
      description: Komma seperated List
      label: Komma Seperated List of Recordings
      name: recordings
      required: true
      type: TEXT
    - context: item
      description: Item to delete selected Recording
      label: Item to delete selected Recording
      name: trash_item
      required: false
      type: TEXT
    - default: /openhab/userdata/ipcamera/a0470d9ac6/
      description: Full Path with Camera UID
      label: Path with UID to Identify selected deletion
      name: ID
      required: true
      type: TEXT
    - description: Height of the Video (empty = default)
      label: Height
      name: height
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Apr 4, 2023, 3:52:04 AM
component: f7-card
config:
  key: =Math.random() + (vars.selectedRecording || "")
  outline: true
  style:
    --f7-card-margin-horizontal: 10px
    --f7-card-margin-vertical: 3px
    --f7-card-padding-horizontal: 10px
    --f7-card-padding-vertical: 100px
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.3)
    margin-bottom: 10px
    margin-top: 10px
    noShadow: false
  title: =props.title
slots:
  default:
    - component: oh-button
      config:
        action: toggle
        actionItem: =props.trash_item
        actionCommand: =(props.ID + vars.selectedRecording + ".mp4")
        iconColor: red
        iconF7: trash
        iconSize: 20
        style:
          margin: -2px
        tooltip: Aufnahme löschen
    - component: oh-video-card
      config:
        height: =props.height
        title: =("Kamera Hoftor Aufnahme vom " + vars.selectedRecording)
        url: =props.URL.replace('{recording}', vars.selectedRecording || items[props.recordings].state.split(",")[0])
        class:
          - padding
    - component: f7-card-content
      config:
        class:
          - padding-bottom-half
        outline: false
        round: false
        style:
          --f7-button-border-radius: 4px
          --f7-button-font-size: 14px
          --f7-button-font-weight: 300
          --f7-button-outline-border-width: 1px
          --f7-button-padding-horizontal: 0px
          --f7-button-padding-vertical: 0px
          --f7-button-text-color: "=themeOptions.dark === 'light' ? 'black' : 'white'"
          --f7-button-text-transform: none
          margin-left: 10px
          margin-right: 10px
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: array
              for: list
              fragment: true
              in: =items[props.recordings].state.split(",")
            slots:
              default:
                - component: oh-button
                  config:
                    fill: "=(vars.selectedRecording == loop.list) ? true : false"
                    action: variable
                    actionVariable: selectedRecording
                    actionVariableValue: =loop.list
                    outline: true
                    round: false
                    style:
                      --f7-button-border-color: var(--f7-card-outline-border-color)
                    text: =loop.list

I’m not sure at the moment either. I tried a version of your widget code and there are some strange errors in the browser console. I’m going to look into a little further, because I think there may be something buggy going on.

1 Like