Skip to content

Commit

Permalink
Merge pull request #1513 from tomivm/feature/improve-phrase
Browse files Browse the repository at this point in the history
Feature/improve phrase
  • Loading branch information
martinbedouret authored Sep 28, 2023
2 parents f8c9bbb + 6202ca2 commit 8d4e9a8
Show file tree
Hide file tree
Showing 19 changed files with 262 additions and 36 deletions.
27 changes: 27 additions & 0 deletions src/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { isAndroid } from '../cordova-util';

const BASE_URL = API_URL;
const LOCAL_COMMUNICATOR_ID = 'cboard_default';
export let improvePhraseAbortController;

const getUserData = () => {
const store = getStore();
Expand Down Expand Up @@ -626,6 +627,32 @@ class API {
return data;
}
}

async improvePhrase({ phrase, language }) {
const authToken = getAuthToken();
if (!(authToken && authToken.length)) {
throw new Error('Need to be authenticated to perform this request');
}

try {
const headers = {
Authorization: `Bearer ${authToken}`
};
improvePhraseAbortController = new AbortController();
const { data } = await this.axiosInstance.post(
`/gpt/edit`,
{ phrase, language },
{
headers,
signal: improvePhraseAbortController.signal
}
);
return data;
} catch (error) {
if (error.message !== 'canceled') console.error(error);
return { phrase: '' };
}
}
}

const API_INSTANCE = new API({});
Expand Down
3 changes: 2 additions & 1 deletion src/components/App/App.reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ const initialState = {
quickUnlockActive: false,
removeOutputActive: false,
vocalizeFolders: false,
liveMode: false
liveMode: false,
improvePhraseActive: false
},
symbolsSettings: {
arasaacActive: false
Expand Down
40 changes: 21 additions & 19 deletions src/components/App/__tests__/App.reducer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
FINISH_FIRST_VISIT,
UPDATE_CONNECTIVITY,
UPDATE_DISPLAY_SETTINGS,
UPDATE_NAVIGATION_SETTINGS,
UPDATE_NAVIGATION_SETTINGS
} from '../App.constants';
import appReducer from '../App.reducer';

Expand All @@ -24,9 +24,9 @@ describe('reducer', () => {
communicatorTour: {
isCommBoardsEnabled: true,
isPublicBoardsEnabled: true,
isAllMyBoardsEnabled: true,
isAllMyBoardsEnabled: true
},
isAnalyticsTourEnabled: true,
isAnalyticsTourEnabled: true
},
displaySettings: {
uiSize: DISPLAY_SIZE_STANDARD,
Expand All @@ -35,7 +35,7 @@ describe('reducer', () => {
hideOutputActive: false,
increaseOutputButtons: false,
labelPosition: 'Below',
darkThemeActive: false,
darkThemeActive: false
},
navigationSettings: {
active: false,
Expand All @@ -47,11 +47,12 @@ describe('reducer', () => {
quickUnlockActive: false,
removeOutputActive: false,
vocalizeFolders: false,
improvePhraseActive: false
},
symbolsSettings: {
arasaacActive: false,
arasaacActive: false
},
userData: {},
userData: {}
};
uData = { name: 'martin bedouret', email: '[email protected]' };
mockApp = {
Expand All @@ -62,7 +63,7 @@ describe('reducer', () => {
labelPosition: 'Below',
fontFamily: DEFAULT_FONT_FAMILY,
fontSize: 'Standard',
darkThemeActive: false,
darkThemeActive: false
},
isConnected: true,
isFirstVisit: false,
Expand All @@ -76,8 +77,9 @@ describe('reducer', () => {
quickUnlockActive: false,
removeOutputActive: false,
vocalizeFolders: false,
improvePhraseActive: false
},
userData: uData,
userData: uData
};
});
it('should return the initial state', () => {
Expand All @@ -86,57 +88,57 @@ describe('reducer', () => {
it('should handle login ', () => {
const login = {
type: LOGIN_SUCCESS,
payload: uData,
payload: uData
};
expect(appReducer(initialState, login)).toEqual({
...initialState,
userData: uData,
isFirstVisit: false,
isFirstVisit: false
});
});
it('should handle logout', () => {
const logout = {
type: LOGOUT,
type: LOGOUT
};
expect(appReducer(initialState, logout)).toEqual(initialState);
});
it('should handle updateDisplaySettings', () => {
const updateDisplaySettings = {
type: UPDATE_DISPLAY_SETTINGS,
payload: mockApp.displaySettings,
payload: mockApp.displaySettings
};
expect(appReducer(initialState, updateDisplaySettings)).toEqual({
...initialState,
displaySettings: mockApp.displaySettings,
displaySettings: mockApp.displaySettings
});
});
it('should handle updateNavigationSettings', () => {
const updateNavigationSettings = {
type: UPDATE_NAVIGATION_SETTINGS,
payload: mockApp.navigationSettings,
payload: mockApp.navigationSettings
};
expect(appReducer(initialState, updateNavigationSettings)).toEqual({
...initialState,
navigationSettings: mockApp.navigationSettings,
navigationSettings: mockApp.navigationSettings
});
});
it('should handle finishFirstVisit ', () => {
const finishFirstVisit = {
type: FINISH_FIRST_VISIT,
type: FINISH_FIRST_VISIT
};
expect(appReducer(initialState, finishFirstVisit)).toEqual({
...initialState,
isFirstVisit: false,
isFirstVisit: false
});
});
it('should handle updateConnectivity', () => {
const updateConnectivity = {
type: UPDATE_CONNECTIVITY,
payload: false,
payload: false
};
expect(appReducer(initialState, updateConnectivity)).toEqual({
...initialState,
isConnected: false,
isConnected: false
});
});
});
41 changes: 38 additions & 3 deletions src/components/Board/Board.actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
CLICK_SYMBOL,
CLICK_OUTPUT,
CHANGE_OUTPUT,
CHANGE_IMPROVED_PHRASE,
CHANGE_LIVE_MODE,
REPLACE_BOARD,
HISTORY_REMOVE_BOARD,
Expand Down Expand Up @@ -55,6 +56,7 @@ import {
import { isAndroid, writeCvaFile } from '../../cordova-util';
import { DEFAULT_BOARDS } from '../../helpers';
import history from './../../history';
import { improvePhraseAbortController } from '../../api/api';

const BOARDS_PAGE_LIMIT = 100;

Expand Down Expand Up @@ -324,9 +326,42 @@ export function clickOutput(outputPhrase) {
}

export function changeOutput(output) {
return {
type: CHANGE_OUTPUT,
output
return async (dispatch, getState) => {
const {
app: {
navigationSettings: { improvePhraseActive }
}
} = getState();
if (improvePhraseActive) dispatch(improvePhrase(output));
dispatch({
type: CHANGE_OUTPUT,
output
});
};
}

export function improvePhrase(output) {
const fetchImprovePhrase = async language => {
const MIN_TILES_TO_IMPROVE = 1;
if (output.length <= MIN_TILES_TO_IMPROVE) return '';
const labels = output.map(symbol => symbol.label);
const phrase = labels.join(' '); //this.handlePhraseToShare();
const improvedPhrase = await API.improvePhrase({ phrase, language });
return improvedPhrase.phrase;
};
return async (dispatch, getState) => {
try {
const language = getState().language.lang;
if (improvePhraseAbortController?.abort)
improvePhraseAbortController.abort();
const improvedPhrase = await fetchImprovePhrase(language);
dispatch({
type: CHANGE_IMPROVED_PHRASE,
improvedPhrase
});
} catch (err) {
console.error('error', err);
}
};
}

Expand Down
12 changes: 10 additions & 2 deletions src/components/Board/Board.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import './Board.css';
import BoardTour from './BoardTour/BoardTour';
import ScrollButtons from '../ScrollButtons';
import { NAVIGATION_BUTTONS_STYLE_SIDES } from '../Settings/Navigation/Navigation.constants';
import ImprovePhraseOutput from './ImprovePhraseOutput';

export class Board extends Component {
static propTypes = {
Expand Down Expand Up @@ -315,7 +316,9 @@ export class Board extends Component {
setIsScroll,
isScroll,
totalRows,
changeDefaultBoard
changeDefaultBoard,
improvedPhrase,
speak
} = this.props;

const tiles = this.renderTiles(board.tiles);
Expand Down Expand Up @@ -524,7 +527,12 @@ export class Board extends Component {
/>
)}
</div>

{navigationSettings.improvePhraseActive && (
<ImprovePhraseOutput
improvedPhrase={improvedPhrase}
speak={speak}
/>
)}
<Dialog
open={this.state.openTitleDialog}
aria-labelledby="board-dialog-title"
Expand Down
1 change: 1 addition & 0 deletions src/components/Board/Board.constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const FOCUS_TILE = 'cboard/Board/FOCUS_TILE';
export const CLICK_SYMBOL = 'cboard/Board/CLICK_SYMBOL';
export const CLICK_OUTPUT = 'cboard/Board/CLICK_OUTPUT';
export const CHANGE_OUTPUT = 'cboard/Board/CHANGE_OUTPUT';
export const CHANGE_IMPROVED_PHRASE = 'cboard/Board/CHANGE_IMPROVED_PHRASE';
export const CHANGE_LIVE_MODE = 'cboard/Board/CHANGE_LIVE_MODE';
export const HISTORY_REMOVE_BOARD = 'cboard/Board/HISTORY_REMOVE_BOARD';
export const UNMARK_BOARD = 'cboard/Board/UNMARK_BOARD';
Expand Down
9 changes: 7 additions & 2 deletions src/components/Board/Board.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,9 @@ export class BoardContainer extends Component {
navHistory,
board,
focusTile,
isPremiumRequiredModalOpen
isPremiumRequiredModalOpen,
improvedPhrase,
speak
} = this.props;

if (!this.state.translatedBoard) {
Expand Down Expand Up @@ -1614,6 +1616,8 @@ export class BoardContainer extends Component {
totalRows={this.state.totalRows}
ref={this.boardRef}
changeDefaultBoard={this.props.changeDefaultBoard}
improvedPhrase={improvedPhrase}
speak={speak}
/>
<Dialog
open={!!this.state.copyPublicBoard && !isPremiumRequiredModalOpen}
Expand Down Expand Up @@ -1726,7 +1730,8 @@ const mapStateToProps = ({
offlineVoiceAlert,
isRootBoardTourEnabled: liveHelp.isRootBoardTourEnabled,
isUnlockedTourEnabled: liveHelp.isUnlockedTourEnabled,
isPremiumRequiredModalOpen: premiumRequiredModalState?.open
isPremiumRequiredModalOpen: premiumRequiredModalState?.open,
improvedPhrase: board.improvedPhrase
};
};

Expand Down
9 changes: 8 additions & 1 deletion src/components/Board/Board.reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EDIT_TILES,
FOCUS_TILE,
CHANGE_OUTPUT,
CHANGE_IMPROVED_PHRASE,
REPLACE_BOARD,
HISTORY_REMOVE_BOARD,
UNMARK_BOARD,
Expand Down Expand Up @@ -48,7 +49,8 @@ const initialState = {
isFetching: false,
images: [],
isFixed: false,
isLiveMode: false
isLiveMode: false,
improvedPhrase: ''
};

function reconcileBoards(localBoard, remoteBoard) {
Expand Down Expand Up @@ -411,6 +413,11 @@ function boardReducer(state = initialState, action) {
return {
...state
};
case CHANGE_IMPROVED_PHRASE:
return {
...state,
improvedPhrase: action.improvedPhrase
};
default:
return state;
}
Expand Down
41 changes: 41 additions & 0 deletions src/components/Board/ImprovePhraseOutput/ImprovePhraseOutput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import PropTypes from 'prop-types';

import styles from './ImprovePhraseOutput.module.css';

import { Typography } from '@material-ui/core';
import { PlayArrow } from '@material-ui/icons';

const propTypes = {
improvedPhrase: PropTypes.string,
speak: PropTypes.func
};

function ImprovePhraseOutput({ improvedPhrase, speak }) {
const handlePlay = async () => {
if (!improvedPhrase || improvedPhrase.length === 0) return;
speak(improvedPhrase);
};
const enabledControllsClassname = improvedPhrase
? `${styles.text_and_controls} ${styles.enabled}`
: styles.text_and_controls;

return (
<div
tabIndex="0"
className={enabledControllsClassname}
onClick={handlePlay}
>
<Typography className={styles.text} variant="h5">
{improvedPhrase}
</Typography>
{improvedPhrase && (
<PlayArrow className={styles.playArrow} fontSize="large" />
)}
</div>
);
}

ImprovePhraseOutput.propTypes = propTypes;

export default ImprovePhraseOutput;
Loading

0 comments on commit 8d4e9a8

Please sign in to comment.