Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asciinema-player with React #251

Closed
Ceditvodu opened this issue Sep 5, 2017 · 31 comments
Closed

asciinema-player with React #251

Ceditvodu opened this issue Sep 5, 2017 · 31 comments

Comments

@Ceditvodu
Copy link

Hello.

Asciinema player has very strange behavior in my small React project. On static page with same parametrs it works perfetct both online and offline. On React it doesn't work properly. It shows on page, but when I click on play button it start endless loading. Also there is no any errors in console.

Anybody know how to fix it?

Thanks.

@ku1ik
Copy link
Contributor

ku1ik commented Sep 14, 2017

When you use it in your React-driven page, do you embed the player outside of your React tree, or you add <asciinema-player> in your JSX?

@Ceditvodu
Copy link
Author

Directly in jsx! Is it wrong?

@ku1ik
Copy link
Contributor

ku1ik commented Sep 14, 2017

I don't think this will work our of the box. <asciinema-player> element is wrapping reagent (and thus React) component, which comes with its own bundled version of React. So there may be some conflicts there.

Maybe we could expose the component directly, without the wrapper, so it can be used within existing React component tree. Not sure how to do that yet though.

@Ceditvodu
Copy link
Author

Hmmm, interesting thought. I`ll try it! Whait for response :)

@coco98
Copy link

coco98 commented Nov 8, 2017

@sickill So is there no way of using the asciinema player inside a react component? Should I try the iframe route:

<div className={styles.playerContainer}>
  <iframe src="https://asciinema.org/a/113463/iframe">
</iframe>
</div>

This doesn't work for me though. Working my way through this, but I was wondering what the recommended workaround at the moment is?

EDIT:

Doesn't work because:

Refused to display 'https://asciinema.org/a/113463/iframe' in a frame because it set 'X-Frame-Options' to 'sameorigin'.```

@ku1ik
Copy link
Contributor

ku1ik commented Nov 9, 2017

Looks like you just found a bug with iframe embedding ;) I need to modify or remove this X-Frame-Options header.

@ku1ik
Copy link
Contributor

ku1ik commented Nov 9, 2017

Ah, and now I see you already suggested solution in the other issue, thx!

@coco98
Copy link

coco98 commented Nov 16, 2017

I can confirm that the iframe embed works with react.

Minor issues with fullscreen at: asciinema/asciinema-server#286 (comment)

@trevordmiller
Copy link

I’m hoping to add hosted asciicasts to my React site. Has anyone had any further luck or tips for using the self hosted player in React?

@ku1ik
Copy link
Contributor

ku1ik commented Mar 31, 2018

The player component is reagent component, and it seems it can be converted into native React component as described here: https://github.com/reagent-project/reagent/blob/master/docs/InteropWithReact.md#creating-react-components-from-reagent-components

The released asciinema-player.js bundle includes React and other deps, it's basically a standalone script to be added to a page.

It seems to me that in order to support consuming it as React component it would be better if asciinema-player was released as npm package with React defined as proper npm dependency, without bundled React code in the player itself, and with a proper way to import AsciinemaPlayer from 'asciinema-player';.

Latest versions of ClojureScript compiler made lots of improvements for integrating with node/npm so I think it's something we could try implementing already.

@trevordmiller
Copy link

A React npm package would be fantastic!

@AlanFoster
Copy link

AlanFoster commented Apr 12, 2018

A standalone version would be great; But for now I have included the CSS and JS file as static assets, and I've written a simple wrapper for now:

class Asciinema extends React.Component {
  render() {
    return (
      <asciinema-player
        src={this.props.src}
        preload
        poster="npt:0:3"
        idle-time-limit="2"
      />
    );
  }
}

...

<Asciinema src='/example.cast'/>

The full screen functionality doesn't resize the text as I would have expected, but I believe this isn't supported out of the box currently.



Update: I noticed some weird quirks the directly using the above custom asciinema-player element that's been registered registered by asciinema. I tracked this down to an issue with the bootstrapping of asciinema via onCreated rather than onAttached.

I am now directly using the createPlayer method instead:

class Asciinema extends React.Component {
  static defaultProps = {
    theme: 'monokai',
    idleTimeLimit: 2,
    poster: 'npt:0:3'
  };

  bindRef = (ref) => {
    this.ref = ref;
  };

  componentDidMount() {
    asciinema.player.js.CreatePlayer(
      this.ref,
      this.props.src,
      this.props
    );
  }

  componentWillUnmount() {
    if (!this.ref) return;

    asciinema.player.js.UnmountPlayer(this.ref);
    this.ref = null;
  }

  render() {
    return (
      <div ref={this.bindRef}/>
    );
  }
}

Example usage:

<Asciinema src='/example.cast'/>

<Asciinema src='/example.cast' theme='etc' />

@trevordmiller
Copy link

Have there been any updates on an npm package for a React player? Looking forward to this to use in my React websites and slide decks.

@trevordmiller
Copy link

@AlanFoster I've tried to use your suggestions without success. Would you mind publishing your wrapping pieces as to npm for others to use directly in React applications without having to download and host the static .js and .css files?

@AlanFoster
Copy link

@trevordmiller The API for refs changed in the latest versions of React, what version are you currently using? As you might have to tweak the example code a little if you're using the latest and greatest react

@trevordmiller
Copy link

@AlanFoster Callback refs like you are using work in latest react as well as previous versions and I've also tried createRef so I don't think that is the problem. I'm trying to use the player inside of presentation slides (mdx-deck, which abstracts React and other config). I was mainly wondering if you'd be willing to publish your React Asciinema player to npm to use directly without having to host built .js and .css files manually - but if not, I'll wait for an official one from @sickill :)

@trevordmiller
Copy link

trevordmiller commented Sep 2, 2018

I've also considered using a tool like xterm to embed a terminal directly in my slides, with asciinema installed, and just use asciinema play .... But a React component would be much cleaner :)

@ultrox
Copy link

ultrox commented Feb 4, 2019

@sickill is there any news on releasing proper npm package? I'm interested in creating minimal asciinema editor in react, and so far I'm getting hit hard by need for learning tooling system of clojure & java, which is demotivating. Namely I tried to install leningen and end up hitting java dependency issues.

@dreness
Copy link

dreness commented Feb 16, 2019

@ultrox One thing you can try is to play along with the travis build log.

The winning move for me was to install java10.

xomg% java -version
java version "10.0.2" 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)

@Zeljkomk
Copy link

Zeljkomk commented Jul 12, 2019

@AlanFoster this functions are coming from asciinema-player.js file.But the problem is that it says to me Unresolved function or method CreatePlayer and UnmountPlayer.How can i solve this ?

  • asciinema.player.js.CreatePlayer(
    this.ref,
    this.props.src,
    this.props
    );

  • asciinema.player.js.UnmountPlayer(this.ref);

@ngocdaothanh
Copy link

@Zeljkomk You can add asciinema-player.js to your HTML page, then call window.asciinema.player.js.CreatePlayer(...).

@ngocdaothanh
Copy link

@AlanFoster's solution works very well!
Tip: If you want to autoplay, set autoPlay: true (not autoplay).

@frippe75
Copy link

@AlanFoster , not sure why I'm getting 'asciinema' is not defined

Tried importing it multiple (incorrect) ways..

import "./asciinema-player"; (having it locally in the component path)
//import 'asciinema-player' (when installed as node module)

Also tried putting a <script> tag in index.html placing asciinema-player,js in public....

dherman referenced this issue in neon-bindings/website Sep 10, 2020
- Based on https://www.figma.com/file/AHM9ZSowavRtfl8E21ZHQc/Home-Page?node-id=33%3A3
- Dark green-blue background for features list and footer
- All cyan feature headings
- Matched the asciinema component's color scheme to the site style
- Blue Netlify badge to match new site color scheme

Functional improvements:

- Self-hosted asciinema component based on suggestions at:
  * https://github.com/asciinema/asciinema-player#self-hosting-quick-start
  * https://github.com/asciinema/asciinema-player/issues/72#issuecomment-380950743
- Menus have a subtle pink on hover
@davidlamt
Copy link

I was able to get this integration working by following @AlanFoster's approach. Just thought I'd share a Hooks example in case others find it useful!

I am using it in a Gatsby project so the inclusion of the asciinema-player.css/js bundle is a bit different but the wrapper and usage should still be applicable.

@nuriAngraini
Copy link

👌

@ku1ik
Copy link
Contributor

ku1ik commented Oct 31, 2021

The next version of the player (3.0, see next branch) is going to be a proper npm package, finally 😅.

It's also a rewrite from ClojureScript to modern JS. For rendering it doesn't use React.js anymore, instead it uses small and fast Solid.js.

There's been several different issues raised in this thread and I hope the new version will address most, if not all, of them 🤞

It's around the corner, there's just a few small missing bits I plan to address in next few weeks. I plan to publish a series of alpha/beta releases to npmjs.org and would love a feedback from you 🙌

@ku1ik
Copy link
Contributor

ku1ik commented Dec 11, 2021

The new version of the player has been published to npmjs.org (currently at 3.0.0-rc.1). Feel free to give it a spin. Check out the updated self-hosting quick-start guide: https://github.com/asciinema/asciinema-player#quick-start

@ku1ik ku1ik closed this as completed Dec 20, 2021
@dunnkers
Copy link

dunnkers commented Jan 29, 2022

Anyone coming here who is still confused on how to use Asciinema with React, see the following example:

npm install --save-dev asciinema-player@3.0.0-rc.1
import React, { useEffect, useRef } from 'react';
import * as AsciinemaPlayerLibrary from 'asciinema-player';

type AsciinemaPlayerProps = {
    src: string;
    // START asciinemaOptions
    cols: string;
    rows: string;
    autoPlay: boolean
    preload: boolean;
    loop: boolean | number;
    startAt: number | string;
    speed: number;
    idleTimeLimit: number;
    theme: string;
    poster: string;
    fit: string;
    fontSize: string;
    // END asciinemaOptions
};

const AsciinemaPlayer: React.FC<AsciinemaPlayerProps> = ({
    src,
    ...asciinemaOptions
}) => {
    const ref = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const currentRef = ref.current;
        AsciinemaPlayerLibrary.create(src, currentRef, asciinemaOptions);
    }, [src]);

    return <div ref={ref} />;
};

export default AsciinemaPlayer;

Use like so:

import AsciinemaPlayer from './components/AsciinemaPlayer';
import 'asciinema-player/dist/bundle/asciinema-player.css';
<AsciinemaPlayer src="/fseval/cast/examples_quick_start.cast" rows={30} idleTimeLimit={3} preload={true} />

🎉

@gangster
Copy link

Anyone coming here who is still confused on how to use Asciinema with React, see the following example:

npm install --save-dev asciinema-player@3.0.0-rc.1
import React, { useEffect, useRef } from 'react';
import * as AsciinemaPlayerLibrary from 'asciinema-player';

type AsciinemaPlayerProps = {
    src: string;
    // START asciinemaOptions
    cols: string;
    rows: string;
    autoPlay: boolean
    preload: boolean;
    loop: boolean | number;
    startAt: number | string;
    speed: number;
    idleTimeLimit: number;
    theme: string;
    poster: string;
    fit: string;
    fontSize: string;
    // END asciinemaOptions
};

const AsciinemaPlayer: React.FC<AsciinemaPlayerProps> = ({
    src,
    ...asciinemaOptions
}) => {
    const ref = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const currentRef = ref.current;
        AsciinemaPlayerLibrary.create(src, currentRef, asciinemaOptions);
    }, [src]);

    return <div ref={ref} />;
};

export default AsciinemaPlayer;

Use like so:

import AsciinemaPlayer from './components/AsciinemaPlayer';
import 'asciinema-player/dist/bundle/asciinema-player.css';
<AsciinemaPlayer src="/fseval/cast/examples_quick_start.cast" rows={30} idleTimeLimit={3} preload={true} />

🎉

Works for me!!! Well done and thank you.

@benjaminpreiss
Copy link

So for anyone who runs into a double rendering problem with react 18, here is my solution, including typescript types:

AsciinemaPlayer.tsx:

import React, { useEffect, useRef, useState } from 'react';
import 'asciinema-player/dist/bundle/asciinema-player.css';

type AsciinemaPlayerProps = {
    src: string;
    // START asciinemaOptions
    cols?: string;
    rows?: string;
    autoPlay?: boolean
    preload?: boolean;
    loop?: boolean | number;
    startAt?: number | string;
    speed?: number;
    idleTimeLimit?: number;
    theme?: string;
    poster?: string;
    fit?: string;
    fontSize?: string;
    // END asciinemaOptions
};

function AsciinemaPlayer ({src, ...asciinemaOptions}: AsciinemaPlayerProps) {
    const ref = useRef<HTMLDivElement>(null);
    const [player, setPlayer] = useState<typeof import("asciinema-player")>()
    useEffect(() => {
        import("asciinema-player").then(p => {setPlayer(p)})
    }, [])
    useEffect(() => {
        const currentRef = ref.current
        const instance = player?.create(src, currentRef, asciinemaOptions);
        return () => {instance?.dispose()}
    }, [src, player, asciinemaOptions]);

    return <div ref={ref} />;
}

export default AsciinemaPlayer

asciinema-player.d.ts:

declare module "asciinema-player" {
    export function create(
        src: string,
        element: HTMLElement | null,
        // START asciinemaOptions
        opts: {
            cols?: string,
            rows?: string,
            autoPlay?: boolean,
            preload?: boolean,
            loop?: boolean | number,
            startAt?: number | string,
            speed?: number,
            idleTimeLimit?: number,
            theme?: string,
            poster?: string,
            fit?: string,
            fontSize?: string
        }
    )
}

@ymolists
Copy link

ymolists commented Jun 9, 2024

Does anyone has an example that works with nextjs , react 18 and typescript please ?

@ku1ik ku1ik transferred this issue from asciinema/asciinema-player Jun 10, 2024
@asciinema asciinema locked and limited conversation to collaborators Jun 10, 2024
@ku1ik ku1ik converted this issue into discussion #252 Jun 10, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

17 participants