Skip to content
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

[MIK-314] Update "export to renpy" #160

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions apps/interactor/src/components/history/ExportToRenpy.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@
height: 100%;
}
}
.disabled-export-button {
color: $color-gray;
border-color: $color-gray;
background-color: #5e5e5e67;
cursor: not-allowed;

& img {
filter: grayscale(100%);
}

&:hover {
background-color: #5e5e5e67;
}
}
17 changes: 12 additions & 5 deletions apps/interactor/src/components/history/ExportToRenpy.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Button, CheckBox, Loader, Modal, Tooltip } from '@mikugg/ui-kit';
import { useState } from 'react';
import { toast } from 'react-toastify';
import { useAppContext } from '../../App.context';
import { downloadRenPyProject, exportToRenPy } from '../../libs/exportToRenpy';
import { RootState } from '../../state/store';
import './ExportToRenpy.scss';
import { useAppContext } from '../../App.context';

interface RenPyExportButtonProps {
state: RootState;
Expand All @@ -14,7 +14,8 @@ export const RenPyExportButton = ({ state }: RenPyExportButtonProps) => {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [linearStory, setLinearStory] = useState<boolean>(false);
const { assetLinkLoader } = useAppContext();
const premiumMember = state.settings.user.isPremium;
const { assetLinkLoader, isMobileApp, isProduction } = useAppContext();
const handleButtonClick = async () => {
setIsLoading(true);
try {
Expand All @@ -27,15 +28,21 @@ export const RenPyExportButton = ({ state }: RenPyExportButtonProps) => {
setIsModalOpen(false);
};

if(isMobileApp && !isProduction) return null;

return (
<>
<Tooltip id="renpy-export-tooltip" place="bottom" />
<button
className="RenPyExportButton"
className={`RenPyExportButton ${!premiumMember ? 'disabled-export-button' : ''}`}
onClick={() => setIsModalOpen(true)}
data-tooltip-id="renpy-export-tooltip"
data-tooltip-content="Generate a Ren'Py project from the current narration."
disabled={isLoading}
data-tooltip-content={
!premiumMember
? `Export to Ren'Py is only for premium members.`
: `Generate a Ren'Py project from the current narration.`
}
disabled={isLoading || !premiumMember}
>
<img src="/images/renpy.png" alt="Ren'Py" height={16} />
Export as Ren'Py
Expand Down
5 changes: 2 additions & 3 deletions apps/interactor/src/components/history/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ const HistoryActions = () => {
const state = useAppSelector((state) => state);
const hasInteractions = useAppSelector((state) => Object.keys(state.narration.interactions).length > 0);

const { isMobileApp } = useAppContext();

const handleSave = () => {
const clonedState = JSON.parse(JSON.stringify(state));
clonedState.settings.modals.history = false;
Expand Down Expand Up @@ -102,7 +100,8 @@ const HistoryActions = () => {
return (
<div className="History__actions">
<Tooltip id="history-actions-tooltip" place="bottom" />
{!isMobileApp && hasInteractions ? <RenPyExportButton state={state} /> : null}
{hasInteractions ? <RenPyExportButton state={state} /> : null}

{!hasInteractions ? (
<label
className="icon-button"
Expand Down
71 changes: 61 additions & 10 deletions apps/interactor/src/libs/exportToRenpy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AssetDisplayPrefix } from '@mikugg/bot-utils';
import JSZip from 'jszip';
import { selectAllParentDialogues } from '../state/selectors';
import { RootState } from '../state/store';
import { NovelCharacterOutfit } from '../state/versioning';
import { fillTextTemplate } from './prompts/strategies';
import { AssetDisplayPrefix } from '@mikugg/bot-utils';

const assert = console.assert;

Expand Down Expand Up @@ -358,16 +358,67 @@ export const downloadRenPyProject = async (
assetLinkLoader: (asset: string, type: AssetDisplayPrefix) => string,
) => {
try {
const allBackgroundAssets = state.novel.backgrounds.map((background) => background.source.jpg);
const allCharactersImages = state.novel.characters
.map((character) => {
return character.card.data.extensions.mikugg_v2.outfits.map((outfit) => {
return outfit.emotions.map((emotion) => {
return emotion.sources.png;
});
let allBackgroundAssets: string[] = [];
let allCharactersImages: string[] = [];
const removeDuplicates = (strings: string[]): string[] => {
return Array.from(new Set(strings));
};
// const allBackgroundAssets = state.novel.backgrounds.map((background) => background.source.jpg);
// const allCharactersImages = state.novel.characters
// .map((character) => {
// return character.card.data.extensions.mikugg_v2.outfits.map((outfit) => {
// return outfit.emotions.map((emotion) => {
// return emotion.sources.png;
// });
// });
// })
// .flat(2);

for (const interaction of Object.values(state.narration.interactions)) {
if (interaction) {
const sceneId = interaction.sceneId;
const scene = state.novel.scenes.find((scene) => scene.id === sceneId);
const responses = interaction.responsesId.map((responseId) => {
return state.narration.responses[responseId];
});
})
.flat(2);
const emotions = responses
.map((response) => {
return response
? response?.characters.map((character) => {
return character.emotion;
})
: [];
})
.flat();
if (scene) {
const characterOutfits = scene.characters.map((character) => {
return character.outfit;
});
const outfits = characterOutfits
.map((outfit) => {
return state.novel.characters.find((character) => character.id === outfit)?.card.data.extensions.mikugg_v2
.outfits;
})
.flat();
for (const outfit of outfits) {
const emotionsInScene = outfit?.emotions.filter((emotion) => emotions.includes(emotion.id));
if (emotionsInScene) {
allCharactersImages = allCharactersImages.concat(emotionsInScene.map((emotion) => emotion.sources.png));
}
}
const sceneBackground = state.novel.backgrounds.find((background) => background.id === scene.backgroundId);
if (sceneBackground) {
if (!allBackgroundAssets.includes(sceneBackground.source.jpg)) {
allBackgroundAssets.push(sceneBackground.source.jpg);
}
}
}
}
}
allCharactersImages = allCharactersImages.filter((item) => item !== '');

allBackgroundAssets = removeDuplicates(allBackgroundAssets);
allCharactersImages = removeDuplicates(allCharactersImages);

// eslint-disable-next-line
// @ts-ignore
Expand Down
Loading