'Vaadin 14 convert Polymer component to Lit with TypeScript
I use Intellij IDEA and Vaadin 14. How can i convert simple Polymer component to Lit with TypeScript? I want to learn how to create Lit with TypeScript in order to upgrade project to latest Vaadin LTS, that is use it as i understand. I tried to create ts-file based on included JS-file, but have no luck. It highlite many errors for the code. Maybe someone can give some links where i can read more pointly about this?
AudioPlayer.java:
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.EventHandler;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.server.StreamReceiver;
import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.server.StreamResourceRegistry;
import com.vaadin.flow.server.StreamVariable;
import org.apache.commons.io.input.AutoCloseInputStream;
import java.io.InputStream;
import java.util.function.Supplier;
@Tag("audio-player-element")
@JsModule("./src/audio-player/audio-player-element.js")
public class AudioPlayer extends PolymerTemplate<AudioPlayerModel> {
private Supplier<InputStream> inputStreamSupplier;
public AudioPlayer(Supplier<InputStream> inputStreamSupplier) {
this.inputStreamSupplier = inputStreamSupplier;
}
@EventHandler
private void requestAudioStream() {
if (getModel().getAudioSrc() == null) {
AutoCloseInputStream autoCloseInputStream = new AutoCloseInputStream(inputStreamSupplier.get());
StreamResource streamResource = new StreamResource(
"audio_proxy_" + System.currentTimeMillis() + ".webm",
() -> autoCloseInputStream);
streamResource.setCacheTime(600000);
streamResource.setContentType("application/octet-stream");
getElement().setAttribute("streamResourceHandler", streamResource);
String src = StreamResourceRegistry.getURI(streamResource).getPath();
getModel().setAudioSrc(src);
}
getElement().executeJs("this.audioPlay();");
}
}
AudioPlayerModel.java:
import com.vaadin.flow.templatemodel.TemplateModel;
public class AudioPlayerModel implements TemplateModel {
private String audioSrc;
public String getAudioSrc() {
return audioSrc;
}
public void setAudioSrc(String audioSrc) {
this.audioSrc = audioSrc;
}
}
audio-player-element.js:
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
import '@vaadin/vaadin-icons/vaadin-icons.js';
import '@polymer/iron-icon/iron-icon.js';
class AudioPlayerElement extends PolymerElement {
constructor() {
super();
}
static get template() {
return html`
<div class="audio-container" on-click="requestAudioStream">
<iron-icon class="play-pause-icon"
icon="[[playButtonIcon]]"
></iron-icon>
<audio id="audioPlayer" src$=[[audioSrc]] on-ended="onAudioEnded"/>
</div>
${this.templateCSS}
`;
}
static get is() {
return 'audio-player-element';
}
static get properties() {
return {
playButtonIcon: {
type: String,
value: "vaadin:play",
notify: true
},
audioSrc: {
type: String,
value: null,
notify: true/*,
reflectToAttribute: true*/
}
}
}
/* Backend alias */
requestAudioStream() {}
audioPlay() {
this.playButtonIcon = "vaadin:stop";
this.$.audioPlayer.play();
}
onAudioEnded() {
this.$.audioPlayer.currentTime = 0;
this.playButtonIcon = "vaadin:play";
}
static get templateCSS() {
return html`
<style>
:host div.audio-container {
width: 50px;
border-radius: 7px;
padding: 3px;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
box-shadow: inset 0 0 2px 1px #0087fd;
margin: 3px;
height: 15px;
}
:host div iron-icon.play-pause-icon {
width: 18px;
height: 18px;
display: contents;
}
</style>`;
}
}
customElements.define(AudioPlayerElement.is, AudioPlayerElement);
Solution 1:[1]
Resolved.
Java:
// AudioPlayer2.java
import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.server.StreamResourceRegistry;
import org.apache.commons.io.input.AutoCloseInputStream;
import java.io.InputStream;
import java.util.function.Supplier;
@Tag("audio-player-element2")
@JsModule("./src/audio-player/audio-player-element2.ts")
public class AudioPlayer2 extends Component {
private final transient Supplier<InputStream> inputStreamSupplier;
public AudioPlayer2(Supplier<InputStream> inputStreamSupplier) {
this.inputStreamSupplier = inputStreamSupplier;
}
@ClientCallable
public String requestAudioStream() {
AutoCloseInputStream autoCloseInputStream = new AutoCloseInputStream(inputStreamSupplier.get());
StreamResource streamResource = new StreamResource(
"audio_proxy_" + System.currentTimeMillis() + ".webm",
() -> autoCloseInputStream);
streamResource.setCacheTime(600000);
streamResource.setContentType("application/octet-stream");
getElement().setAttribute("streamResourceHandler", streamResource);
return StreamResourceRegistry.getURI(streamResource).getPath();
}
}
TypeScript (audio-player-element2.ts):
import {css, customElement, html, LitElement, property} from 'lit-element';
import '@vaadin/vaadin-icons/vaadin-icons.js';
import '@polymer/iron-icon/iron-icon.js';
interface AudioPlayer2 {
requestAudioStream(): string;
}
@customElement('audio-player-element2')
export class AudioPlayerElement2 extends LitElement {
declare $server: AudioPlayer2;
@property()
public audioPlayerInstance: HTMLAudioElement;
@property({attribute: true})
public playButtonIcon: string = "vaadin:play";
@property()
public audioLoaded: boolean = false;
constructor() {
super();
this.audioPlayerInstance = new Audio();
this.audioPlayerInstance.addEventListener("ended", () => this.onAudioEnded())
}
firstUpdated() {
this.renderRoot.querySelector('.audio-container')?.appendChild(this.audioPlayerInstance);
}
render() {
return html`
<div class="audio-container" @click="${this.playAudio}}">
<iron-icon class="play-pause-icon" icon="${this.playButtonIcon}"></iron-icon>
</div>
`;
}
playAudio() {
if (this.audioLoaded) {
this.audioPlayerInstance.play();
this.playButtonIcon = "vaadin:stop";
} else {
// not sure how is right
//let asyncSrcRequest = async () => await this.$server.requestAudioStream();
let asyncSrcRequest = async () => this.$server.requestAudioStream();
asyncSrcRequest().then((src) => {
this.audioLoaded = true;
this.audioPlayerInstance.src = src;
this.audioPlayerInstance.play();
this.playButtonIcon = "vaadin:stop";
})
}
}
onAudioEnded() {
this.audioPlayerInstance.currentTime = 0;
this.playButtonIcon = "vaadin:play";
}
static get styles() {
return css`
:host div.audio-container {
width: 50px;
border-radius: 7px;
padding: 3px;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
box-shadow: inset 0 0 2px 1px #0087fd;
margin: 3px;
height: 15px;
}
:host div iron-icon.play-pause-icon {
width: 18px;
height: 18px;
display: contents;
}
`;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | lanmaster |
