Skip to content

Commit

Permalink
Fetch keyboard statistics and show them.
Browse files Browse the repository at this point in the history
  • Loading branch information
yoichiro committed Dec 19, 2023
1 parent c0ecdf2 commit 804cef2
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-draggable": "^4.4.3",
"react-google-charts": "^4.0.1",
"react-helmet-async": "^1.0.9",
"react-image-gallery": "^1.2.7",
"react-redux": "^7.2.2",
Expand Down
8 changes: 8 additions & 0 deletions src/actions/keyboards.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
IBuildableFirmwareFileType,
IKeyboardDefinitionAuthorType,
IKeyboardDefinitionDocument,
IKeyboardStatistics,
IStore,
} from '../services/storage/Storage';
import { ThunkAction, ThunkDispatch } from 'redux-thunk';
Expand Down Expand Up @@ -196,6 +197,7 @@ export const KEYBOARDS_EDIT_DEFINITION_UPDATE_ORGANIZATION_ID = `${KEYBOARDS_EDI
export const KEYBOARDS_EDIT_DEFINITION_UPDATE_AUTHOR_TYPE = `${KEYBOARDS_EDIT_DEFINITION_ACTIONS}/UpdateAuthorType`;
export const KEYBOARDS_EDIT_DEFINITION_UPDATE_BUILDABLE_FIRMWARE_FILE = `${KEYBOARDS_EDIT_DEFINITION_ACTIONS}/UpdateBuildableFirmwareFile`;
export const KEYBOARDS_EDIT_DEFINITION_UPDATE_BUILDABLE_FIRMWARE_CODE_PARAMETERS = `${KEYBOARDS_EDIT_DEFINITION_ACTIONS}/UpdateBuildableFirmwareCodeParameters`;
export const KEYBOARDS_EDIT_DEFINITION_UPDATE_KEYBOARD_STATISTICS = `${KEYBOARDS_EDIT_DEFINITION_ACTIONS}/UpdateKeyboardStatistics`;

export const KeyboardsEditDefinitionActions = {
clear: () => {
Expand Down Expand Up @@ -447,6 +449,12 @@ export const KeyboardsEditDefinitionActions = {
value: parameters,
};
},
updateKeyboardStatistics: (statistics: IKeyboardStatistics | undefined) => {
return {
type: KEYBOARDS_EDIT_DEFINITION_UPDATE_KEYBOARD_STATISTICS,
value: statistics,
};
},
};

type ActionTypes = ReturnType<
Expand Down
17 changes: 17 additions & 0 deletions src/actions/storage.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,23 @@ export const storageActionsThunk = {
);
return;
}
const fetchKeyboardStatisticsResult =
await storage.instance!.fetchKeyboardStatistics(definitionId);
if (isError(fetchKeyboardStatisticsResult)) {
console.error(fetchKeyboardStatisticsResult.cause);
dispatch(
NotificationActions.addError(
fetchKeyboardStatisticsResult.error,
fetchKeyboardStatisticsResult.cause
)
);
return;
}
dispatch(
KeyboardsEditDefinitionActions.updateKeyboardStatistics(
fetchKeyboardStatisticsResult.value
)
);
dispatch(
StorageActions.updateBuildableFirmware(
fetchBuildableFirmwareResult.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { connect } from 'react-redux';
import Statistics from './Statistics';

const mapStateToProps = (state: RootState) => {
return {};
return {
statistics: state.keyboards.editdefinition.keyboardStatistics,
};
};
export type StatisticsStateType = ReturnType<typeof mapStateToProps>;

// eslint-disable-next-line no-unused-vars
const mapDispatchToProps = (_dispatch: any) => {
return {};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
.edit-definition-statistics {
&-container {
display: flex;
flex-direction: row;
flex-direction: column;
width: 100%;
}
}
73 changes: 70 additions & 3 deletions src/components/keyboards/editdefinition/statistics/Statistics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,85 @@ import {
StatisticsStateType,
} from './Statistics.container';
import './Statistics.scss';
import { Card } from '@mui/material';
import { Card, CardContent, Typography } from '@mui/material';
import { Chart } from 'react-google-charts';

type OwnProps = {};
type StatisticsProps = OwnProps &
Partial<StatisticsActionsType> &
Partial<StatisticsStateType>;

export default function Statistics(props: StatisticsProps) {
const data = props.statistics;

return (
<div className="edit-definition-statistics-container">
<Card variant="outlined"></Card>
<Card variant="outlined"></Card>
<Card variant="outlined" sx={{ mb: 2 }}>
<CardContent>
<Typography variant="h6">
Counts of opening a keyboard per day
</Typography>
{data !== undefined && (
<Chart
chartType="LineChart"
data={[
['Date', 'Weight'],
...data.statistics.counts_of_opening_keyboard.labels.map(
(label, index) => [
label,
data.statistics.counts_of_opening_keyboard.values[index],
]
),
]}
width="100%"
height="300px"
options={{
legend: 'none',
}}
/>
)}
<Typography
variant="caption"
sx={{ display: 'block', textAlign: 'right', mt: 2 }}
>
* This statistics will be shown after logs are collected by enough
users because of avoiding a privacy issue.
</Typography>
</CardContent>
</Card>
<Card variant="outlined">
<CardContent>
<Typography variant="h6">
Counts of flashing a keymap to MCU
</Typography>
{data !== undefined && (
<Chart
chartType="LineChart"
data={[
['Date', 'Weight'],
...data.statistics.counts_of_flashing_keymap.labels.map(
(label, index) => [
label,
data.statistics.counts_of_flashing_keymap.values[index],
]
),
]}
width="100%"
height="300px"
options={{
legend: 'none',
}}
/>
)}
<Typography
variant="caption"
sx={{ display: 'block', textAlign: 'right', mt: 2 }}
>
* This statistics will be shown after logs are collected by enough
users because of avoiding a privacy issue.
</Typography>
</CardContent>
</Card>
</div>
);
}
27 changes: 27 additions & 0 deletions src/services/provider/Firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
BUILDABLE_FIRMWARE_QMK_FIRMWARE_VERSION,
IBuildableFirmwareQmkFirmwareVersion,
IOperationLogType,
IKeyboardStatistics,
} from '../storage/Storage';
import { IAuth, IAuthenticationResult } from '../auth/Auth';
import { IFirmwareCodePlace, IKeyboardFeatures } from '../../store/state';
Expand Down Expand Up @@ -2026,4 +2027,30 @@ export class FirebaseProvider implements IStorage, IAuth {
// Ignore error.
}
}

async fetchKeyboardStatistics(
keyboardDefinitionId: string
): Promise<IResult<IKeyboardStatistics>> {
try {
const createKeyboardStatistics = this.functions.httpsCallable(
'createKeyboardStatistics'
);
const createKeyboardStatisticsResult = await createKeyboardStatistics({
keyboardDefinitionId,
});
const data = createKeyboardStatisticsResult.data;
if (data.success) {
return successResultOf(data);
} else {
console.error(data.errorMessage);
return errorResultOf(data.errorMessage);
}
} catch (error) {
console.error(error);
return errorResultOf(
`Fetching keyboard statistics failed: ${error}`,
error
);
}
}
}
16 changes: 16 additions & 0 deletions src/services/storage/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,19 @@ export type IFirmwareBuildingTask = {

export type IOperationLogType = 'configure/flash' | 'configure/open';

export type IKeyboardStatistics = {
statistics: {
counts_of_opening_keyboard: {
labels: string[];
values: number[];
};
counts_of_flashing_keymap: {
labels: string[];
values: number[];
};
};
};

/* eslint-disable no-unused-vars */
export interface IStorage {
fetchKeyboardDefinitionDocumentByDeviceInfo(
Expand Down Expand Up @@ -539,5 +552,8 @@ export interface IStorage {
keyboardDefinitionId: string,
operation: IOperationLogType
): Promise<void>;
fetchKeyboardStatistics(
keyboardDefinitionId: string
): Promise<IResult<IKeyboardStatistics>>;
}
/* eslint-enable no-unused-vars */
4 changes: 4 additions & 0 deletions src/store/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ import {
KEYBOARDS_EDIT_DEFINITION_UPDATE_JSON_FILENAME,
KEYBOARDS_EDIT_DEFINITION_UPDATE_JSON_STRING,
KEYBOARDS_EDIT_DEFINITION_UPDATE_KEYBOARD_DEFINITION,
KEYBOARDS_EDIT_DEFINITION_UPDATE_KEYBOARD_STATISTICS,
KEYBOARDS_EDIT_DEFINITION_UPDATE_MAIN_IMAGE_UPLOADED_RATE,
KEYBOARDS_EDIT_DEFINITION_UPDATE_MAIN_IMAGE_UPLOADING,
KEYBOARDS_EDIT_DEFINITION_UPDATE_ORGANIZATION_EVIDENCE,
Expand Down Expand Up @@ -455,6 +456,9 @@ const keyboardsEditKeyboardReducer = (
draft.keyboards.editdefinition.buildableFirmwareCodeParameters =
action.value;
break;
case KEYBOARDS_EDIT_DEFINITION_UPDATE_KEYBOARD_STATISTICS:
draft.keyboards.editdefinition.keyboardStatistics = action.value;
break;
}
};

Expand Down
3 changes: 3 additions & 0 deletions src/store/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
IFirmwareBuildingTask,
IKeyboardDefinitionAuthorType,
IKeyboardDefinitionDocument,
IKeyboardStatistics,
IOrganization,
IOrganizationMember,
IStorage,
Expand Down Expand Up @@ -411,6 +412,7 @@ export type RootState = {
buildableFirmwareFile: IBuildableFirmwareFile | null;
buildableFirmwareFileType: IBuildableFirmwareFileType | null;
buildableFirmwareCodeParameters: IBuildableFirmwareCodeParameter[];
keyboardStatistics: IKeyboardStatistics | undefined;
};
};
catalog: {
Expand Down Expand Up @@ -671,6 +673,7 @@ export const INIT_STATE: RootState = {
buildableFirmwareFile: null,
buildableFirmwareFileType: null,
buildableFirmwareCodeParameters: [],
keyboardStatistics: undefined,
},
},
catalog: {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12926,6 +12926,11 @@ react-fast-compare@^3.0.1, react-fast-compare@^3.2.0:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==

react-google-charts@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/react-google-charts/-/react-google-charts-4.0.1.tgz#b7713856a48009b77318f8951ddf2c3ba39f991b"
integrity sha512-V/hcMcNuBgD5w49BYTUDye+bUKaPmsU5vy/9W/Nj2xEeGn+6/AuH9IvBkbDcNBsY00cV9OeexdmgfI5RFHgsXQ==

react-helmet-async@*, react-helmet-async@^1.0.7, react-helmet-async@^1.0.9:
version "1.2.3"
resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.2.3.tgz#57326a69304ea3293036eafb49475e9ba454cb37"
Expand Down

0 comments on commit 804cef2

Please sign in to comment.