<commit_before>import isolate from "@cycle/isolate";
import { VNode, div } from "@cycle/dom";
import xs, { Stream, MemoryStream } from "xstream";

import { IconType, Direction, Animation } from "../../enums";
import { Dimmer } from "../../modules/dimmer";
import { Icon } from "../../elements/icon";
import { Transition } from "../../modules/transition";
import { DOMContent, isDOMContent, ComponentSources, ComponentSinks } from "../../types";
import { getScope} from "../../utils";

export namespace Modal {
  export interface Props {
    inverted: boolean;
  }
  export interface ContentObj {
    main: DOMContent;
    header: DOMContent;
    actions: DOMContent;
  }
  export interface ModalSources extends ComponentSources<Props, DOMContent, ContentObj> {
    args?: {
      on$?: Stream<boolean>;
      target$?: Stream<VNode>;
    };
  }
  export interface ModalSinks extends ComponentSinks {
    active$: Stream<boolean>;
  }


  export function run(sources: ModalSources, scope: string = getScope()) : ModalSinks {
    function main(sources: ModalSources) {
      const props$ = sources.props$ ? sources.props$ : xs.of({}) as Stream<Partial<Props>>;
      const content$ = sources.content$ ? sources.content$.map(c => isDOMContent(c) ? { main: c } : c) : xs.of({ main: [] });
      const target$ = sources.args && sources.args.target$ ? sources.args.target$ : xs.of("page");
      const show$= sources.args && sources.args.on$ ? sources.args.on$ : xs.of(true);

      const closeIcon = Icon.run({ DOM: sources.DOM, props$: xs.of({ link: true }), content$: xs.of(IconType.Close) }, scope);
      const close$ = closeIcon.events("click").mapTo(false);

      /*** Render modal ***/
      let dimmerclick$proxy = xs.create() as Stream<boolean>;
      const on$ = xs.merge(show$, dimmerclick$proxy, close$).remember() as MemoryStream<boolean>;
      const modal$ = xs.combine(content$, closeIcon.DOM).map(
        ([content, icon]) =>
          div({ props: { className: "ui scrolling active modal" } }, [].concat(
            icon,
            content.header ? div({ props: { className: "header" } }, content.header) : [],
            div({ props: { className: "content" } }, content.main),
            content.actions ? div({ props: { className: "actions" } }, content.actions) : []
          ))
      ).remember();

      /*** Animation ***/
      const transition$ = on$
        .fold((prevAnim, active) => prevAnim.direction === Direction.None
          ? ({ animation: Animation.None, direction: active ? Direction.In : Direction.Out })
          : {
            animation: Animation.Fade, direction: active ? Direction.In : Direction.Out
          }
        , ({ animation: Animation.None, direction: Direction.None }));
      const animatedContent = Transition.run({ DOM: sources.DOM, target$: modal$, transition$ }, scope);

      /*** Activate dimmer ***/
      let dimmerContent$ = animatedContent.DOM.map(x => [x]);
      const dimmer = Dimmer.run({
        DOM: sources.DOM,
        props$: props$.map(x => ({ inverted: x.inverted })),
        content$: dimmerContent$,
        args: { target$, on$ }
      }, scope);
      const dimmerclick$ = dimmer.events("mousedown")
        .filter(evt => evt.srcElement === (evt as MouseEvent).currentTarget)
        .mapTo(false);
      dimmerclick$proxy.imitate(dimmerclick$);

      const fadeOutEnd$ = on$.map(active => !active ? dimmer.events("animationend") : xs.never()).flatten().mapTo(false);
      // const active$ = xs.merge(sources.on$, fadeOutEnd$).remember();
      return {
        active$: xs.merge(show$, fadeOutEnd$),
        DOM: dimmer.DOM,
        events: (type) => sources.DOM.select(".modal").events(type)
      };
    }
    const isolatedMain = isolate(main, scope);
    return isolatedMain(sources);
  }
}
<commit_msg>fix(Modal): Moved content transition to its own scope<commit_after>import isolate from "@cycle/isolate";
import { VNode, div } from "@cycle/dom";
import xs, { Stream, MemoryStream } from "xstream";

import { IconType, Direction, Animation } from "../../enums";
import { Dimmer } from "../../modules/dimmer";
import { Icon } from "../../elements/icon";
import { Transition } from "../../modules/transition";
import { DOMContent, isDOMContent, ComponentSources, ComponentSinks } from "../../types";
import { getScope} from "../../utils";

export namespace Modal {
  export interface Props {
    inverted: boolean;
  }
  export interface ContentObj {
    main: DOMContent;
    header: DOMContent;
    actions: DOMContent;
  }
  export interface ModalSources extends ComponentSources<Props, DOMContent, ContentObj> {
    args?: {
      on$?: Stream<boolean>;
      target$?: Stream<VNode>;
    };
  }
  export interface ModalSinks extends ComponentSinks {
    active$: Stream<boolean>;
  }


  export function run(sources: ModalSources, scope: string = getScope()) : ModalSinks {
    function main(sources: ModalSources) {
      const props$ = sources.props$ ? sources.props$ : xs.of({}) as Stream<Partial<Props>>;
      const content$ = sources.content$ ? sources.content$.map(c => isDOMContent(c) ? { main: c } : c) : xs.of({ main: [] });
      const target$ = sources.args && sources.args.target$ ? sources.args.target$ : xs.of("page");
      const show$= sources.args && sources.args.on$ ? sources.args.on$ : xs.of(true);

      const closeIcon = Icon.run({ DOM: sources.DOM, props$: xs.of({ link: true }), content$: xs.of(IconType.Close) }, scope);
      const close$ = closeIcon.events("click").mapTo(false);

      /*** Render modal ***/
      let dimmerclick$proxy = xs.create() as Stream<boolean>;
      const on$ = xs.merge(show$, dimmerclick$proxy, close$).remember() as MemoryStream<boolean>;
      const modal$ = xs.combine(content$, closeIcon.DOM).map(
        ([content, icon]) =>
          div({ props: { className: "ui scrolling active modal" } }, [].concat(
            icon,
            content.header ? div({ props: { className: "header" } }, content.header) : [],
            div({ props: { className: "content" } }, content.main),
            content.actions ? div({ props: { className: "actions" } }, content.actions) : []
          ))
      ).remember();

      /*** Animation ***/
      const transition$ = on$
        .fold((prevAnim, active) => prevAnim.direction === Direction.None
          ? ({ animation: Animation.None, direction: active ? Direction.In : Direction.Out })
          : {
            animation: Animation.Scale, direction: active ? Direction.In : Direction.Out
          }
        , ({ animation: Animation.None, direction: Direction.None }));
      const animatedContent = Transition.run({ DOM: sources.DOM, target$: modal$, transition$ }, scope + "_transition");

      /*** Activate dimmer ***/
      let dimmerContent$ = animatedContent.DOM.map(x => [x]);
      const dimmer = Dimmer.run({
        DOM: sources.DOM,
        props$: props$.map(x => ({ inverted: x.inverted })),
        content$: dimmerContent$,
        args: { target$, on$ }
      }, scope);
      const dimmerclick$ = dimmer.events("mousedown")
        .filter(evt => evt.srcElement === (evt as MouseEvent).currentTarget)
        .mapTo(false);
      dimmerclick$proxy.imitate(dimmerclick$);

      const fadeOutEnd$ = on$.map(active => !active ? dimmer.events("animationend") : xs.never()).flatten().mapTo(false);
      // const active$ = xs.merge(sources.on$, fadeOutEnd$).remember();
      return {
        active$: xs.merge(show$, fadeOutEnd$),
        DOM: dimmer.DOM,
        events: (type) => sources.DOM.select(".modal").events(type)
      };
    }
    const isolatedMain = isolate(main, scope);
    return isolatedMain(sources);
  }
}

{'fraction_non_alphanumeric': 0.16634025329677504, 'fraction_numerical': 0.0, 'mean_word_length': 2.9730290456431536, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6582563', 'n_tokens_mistral': 2260, 'n_tokens_neox': 2209, 'n_words': 550}