Closed alexander-karpov closed 6 years ago
Да, согласен, пока этого нет, я программно меняю сцену так:
ctx.session.setData('currentScene', null);
@alexander-karpov А как ты думаешь, как было бы удобнее менять сцену? 1 - как ты предложил, но тогда если у тебя сцены в разных файлах, то тебе надо одну в другую импортировать, чтобы заходить. 2 - а можно по названию при инициализации
alice.command('Алиса, пойдём в бар!', ctx => {
if (ctx.profile.age < 18) {
ctx.reply('Давайте лучше в кино.');
} else {
ctx.reply('Пойдёмте.');
ctx.changeScene('in-the-bar');
ctx.switchScene('in-the-bar'); // maybe better naming
}
});
Еще хорошо бы сразу подумать о том, что в будущем могут появиться множественные активные сцены (когда сцена вызвана из сцены).
Мне кажется, что переключение сцены надо делать через события.
Я же правильно понимаю, что переключение сцен хорошо ложится на паттерн State Machine? Я сейчас прочитал это - https://ru.hexlet.io/courses/js-abp/lessons/state_machine_pattern/theory_unit, после чего подумал про события.
В моем представлении сцены похожи на экраны мобильного приложения. Например, заказ пиццы имел бы экраны:
То же самое я бы сделал в навыке, 3 сцены (главный экран - когда без сцены).
Сцена внутри сцены тут может быть такая: модальное окно с подтверждением отправки заказа в приложении и ctx.confirm()
в навыке. То есть вложенные сцены в моем представлении похожи на модальные попапы на сайте, они дают выбрать из одного или нескольких вариантов и пока это не будет сделано, не дают сделать ничего другого.
При таком раскладе (если больше 2 сцен не будет) может это и не вложенная сцена совсем, а просто отдельным полем завести ctx.session.data.currentModalScene
.
Я могу представить, когда нужна вложенность больше:
Вопрос в том, насколько глубоко возможно погружать пользователя в голосовом интерфейсе.
А вам какие сценарии приходят в голову, где нужны вложенные сцены?
@popstas Наверняка в сложных навыках понадобится вложенность и возможность переходить на предыдущий экран. Мое предложение - начать пока просто с возможности произвольно переключать сцены (хотя возможно потом это будет сложнее расширить).
@fletcherist Мне кажется лучше все же передавать ссылку на сцену - надежнее (рефакторить проще, труднее случайно сломать). Переключение можно сделать например вызовами
const inBar = new Scene();
alice.command('Алиса, пойдём в бар', ctx => {
ctx.enterScene(inBar); // change, switch
return 'Пойдёмте.';
});
inBar.command('Алиса, пойдём домой', ctx => {
ctx.enterScene(alice); // или ctx.leaveScene()
return 'Возвращаюсь.';
});
Кстати, как насчет отделить alice
как сервер и alice
как сцену?
Взял на себя
@popstas стейт-машины — это прикольно, но мне кажется, пускай разработчики сами их пишут. Мы дадим им апи перехода из сцены в сцену. А дальше пускай они сами разруливают, куда и из какого состояния можно переходить
Сделано в PR https://github.com/fletcherist/yandex-dialogs-sdk/pull/65
Теперь можно писать так:
const inBar = new Scene('in-bar');
alice.command('Алиса, пойдём в бар', ctx => {
ctx.enterScene(inBar); // change, switch
return 'Пойдёмте.';
});
inBar.command('Алиса, пойдём домой', ctx => {
ctx.leaveScene()
return 'Возвращаюсь.';
});
С таким же успехом можно прыгать из одной сцены в другую.
ctx.leaveScene()
всегда возвращает на главный диалог
Было бы удобно иметь возможность перейти в сцену из другой команды: