Commit 087c10fc authored by Michael Henretty's avatar Michael Henretty
Browse files

disallow implicit any on the web client

parent bd6f38f2
declare global {
interface AudioContext {
createMediaStreamDestination: any;
}
interface Navigator {
webkitGetUserMedia: any;
mozGetUserMedia: any;
}
}
export {};
declare global {
interface AudioContext {
createMediaStreamDestination: any;
}
interface Navigator {
webkitGetUserMedia: any;
mozGetUserMedia: any;
}
}
export {};
......@@ -64,11 +64,11 @@ export default class API {
return req.responseText;
}
private requestResourceText(resource): Promise<string> {
private requestResourceText(resource: string): Promise<string> {
return this.fetchText(this.getPath(resource));
}
private requestResource(resource): Promise<string> {
private requestResource(resource: string): Promise<string> {
return this.fetch(this.getPath(resource));
}
......@@ -81,7 +81,7 @@ export default class API {
return sentencesText.split('\n');
}
getTextFromUrl(url): Promise<string> {
getTextFromUrl(url: string): Promise<string> {
return this.fetchText(url);
}
......
......@@ -165,7 +165,7 @@ export default class App {
document.body.classList.add('loaded');
}, LOAD_TIMEOUT);
await this.loadImages(progress => {
await this.loadImages((progress: number) => {
if (this.progressMeter) {
// TODO: find something performant here. (ie not this)
// let whatsLeft = 1 - progress;
......@@ -173,11 +173,10 @@ export default class App {
// `transform: scale(${whatsLeft});`;
}
});
this.loaded = true;
setTimeout(() => {
document.body.classList.add('loaded');
}, LOAD_DELAY);
}
document.body.classList.add('loaded'); }, LOAD_DELAY); }
/**
* Entry point for the application.
......
......@@ -13,9 +13,9 @@ interface State {
* Allows us to see console log on the ios app.
*/
export default class DebugBox extends Component<Props, State> {
hideTimeout: number;
hideTimeout: any;
constructor(props) {
constructor(props?: Props) {
super(props);
this.state = {
messages: []
......@@ -33,6 +33,7 @@ export default class DebugBox extends Component<Props, State> {
if (this.hideTimeout) {
clearTimeout(this.hideTimeout);
}
this.hideTimeout = setTimeout(() => {
this.setState({
messages: []
......@@ -48,13 +49,13 @@ export default class DebugBox extends Component<Props, State> {
componentDidMount() {
let log = window.console.log.bind(window.console);
window.console.log = (...args) => {
window.console.log = (...args: any[]) => {
log(...args);
this.addMessage(args.join(', '));
}
let err = window.console.error.bind(window.console);
window.console.error = (...args) => {
window.console.error = (...args: any[]) => {
err(...args);
this.addMessage(args.join(', '));
}
......
import { h, Component } from 'preact';
const ICONS = {
interface FontIcons {
[key: string]: string;
bullhorn: string;
hamburger: string;
redo: string;
play: string;
pause: string;
undo: string;
check: string;
x: string;
github: string;
firefox: string;
chrome: string;
help: string;
discourse: string;
}
const ICONS: FontIcons = {
bullhorn: '',
hamburger: '',
redo: '',
......@@ -28,7 +45,7 @@ interface Props {
*/
export default class Icon extends Component<Props, void> {
getIcon(name: string): string {
return ICONS[name] || '';
return ICONS[name];
}
render() {
......
......@@ -39,7 +39,7 @@ export default class ListenBox extends Component<Props, State> {
this.voteNo = this.voteNo.bind(this);
}
state = {
state: State = {
loaded: false,
playing: false,
played: false,
......
import { h, Component } from 'preact';
export default (props) => {
export default (props: any) => {
return <a class="main-logo" href="/"
onClick={(evt) => {
evt.preventDefault();
......
......@@ -17,7 +17,20 @@ import NotFound from './pages/not-found';
import API from '../api';
import User from '../user';
const URLS = {
interface PageUrls {
[key: string]: string;
ROOT: string;
HOME: string;
RECORD: string;
LISTEN: string;
PROFILE: string;
FAQ: string;
PRIVACY: string;
TERMS: string;
NOTFOUND: string;
};
const URLS: PageUrls = {
ROOT: '/',
HOME: '/home',
RECORD: '/record',
......@@ -68,7 +81,7 @@ export default class Pages extends Component<PagesProps, PagesState> {
private bg: HTMLElement;
private iOSBackground: any[];
state = {
state: PagesState = {
isMenuVisible: false,
pageTransitioning: false,
scrolled: false,
......@@ -81,7 +94,7 @@ export default class Pages extends Component<PagesProps, PagesState> {
recorderVolume: 100
};
constructor(props) {
constructor(props?: PagesProps) {
super(props);
// On native iOS, we found some issues animating the css background
......@@ -116,7 +129,7 @@ export default class Pages extends Component<PagesProps, PagesState> {
window.location.href = getItunesURL();
}
private closeOpenInApp(evt) {
private closeOpenInApp(evt: Event) {
evt.stopPropagation();
evt.preventDefault();
document.getElementById('install-app').classList.add('hide');
......@@ -144,8 +157,8 @@ export default class Pages extends Component<PagesProps, PagesState> {
});
}
private isValidPage(url): boolean {
return Object.keys(URLS).some(key => {
private isValidPage(url: string): boolean {
return Object.keys(URLS).some((key: string) => {
return URLS[key] === url;
});
}
......
......@@ -11,7 +11,7 @@ interface Props {
}
export default class Home extends Component<Props, void> {
constructor(props) {
constructor(props: Props) {
super(props);
this.onVote = this.onVote.bind(this);
}
......
......@@ -11,7 +11,7 @@ interface ListenPageProps {
}
export default class Listen extends Component<ListenPageProps, void> {
constructor(props) {
constructor(props: ListenPageProps) {
super(props);
this.onVote = this.onVote.bind(this);
}
......
......@@ -14,7 +14,7 @@ interface State {
}
export default class Profile extends Component<Props, State> {
constructor(props) {
constructor(props: Props) {
super(props);
let user = this.props.user.getState();
......@@ -43,8 +43,8 @@ export default class Profile extends Component<Props, State> {
this.render();
}
private configSendEmails(e) {
let el = e.currentTarget;
private configSendEmails(e: Event) {
let el = e.currentTarget as HTMLInputElement;
this.props.user.setSendEmails(el.checked);
}
......@@ -99,7 +99,7 @@ export default class Profile extends Component<Props, State> {
let ageModified = this.state.age !== user.age;
let genderModified = this.state.gender !== user.gender;
let accentOptions = [];
let accentOptions: any[] = [];
Object.keys(ACCENTS).forEach(accent => {
accentOptions.push(
<option value={accent} selected={this.state.accent === accent}>
......@@ -107,7 +107,7 @@ export default class Profile extends Component<Props, State> {
</option>);
});
let ageOptions = [];
let ageOptions: any[] = [];
Object.keys(AGES).forEach(age => {
ageOptions.push(
<option value={age} selected={this.state.age === age}>
......@@ -115,7 +115,7 @@ export default class Profile extends Component<Props, State> {
</option>);
});
let genderOptions = [];
let genderOptions: any[] = [];
Object.keys(GENDER).forEach(gender => {
genderOptions.push(
<option value={gender} selected={this.state.gender === gender}>
......
......@@ -58,7 +58,7 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
sentenceCache: string[];
maxVolume: number;
state = {
state: RecordState = {
sentences: [],
recording: false,
recordingStartTime: 0,
......@@ -69,7 +69,7 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
isReRecord: false
};
constructor(props) {
constructor(props: RecordProps) {
super(props);
this.tracker = new Tracker();
......
......@@ -5,8 +5,8 @@ import confirm from '../../confirm';
const LEVELS_THROTTLE = 50;
declare var webkit;
declare var vcopensettings;
declare var webkit: any;
declare var vcopensettings: any;
export default class AudioIOS {
postMessage: Function;
......@@ -70,7 +70,7 @@ export default class AudioIOS {
// Native will call this function with decibels from -120 to 0.
this.lastUpdate = Date.now();
window['levels'] = (decibels) => {
window['levels'] = (decibels: string) => {
if (!this.volumeCallback) {
return;
}
......
......@@ -4,6 +4,10 @@ import confirm from '../../confirm';
const AUDIO_TYPE = 'audio/ogg; codecs=opus';
interface BlobEvent extends Event {
data: Blob;
}
export interface AudioInfo {
url: string;
blob: Blob;
......@@ -172,11 +176,11 @@ export default class AudioWeb {
return new Promise<void>((res: Function, rej: Function) => {
this.chunks = [];
this.recorder.ondataavailable = (e) => {
this.recorder.ondataavailable = (e: BlobEvent) => {
this.chunks.push(e.data);
};
this.recorder.onstart = (e) => {
this.recorder.onstart = (e: Event) => {
this.clear();
res();
}
......@@ -198,7 +202,7 @@ export default class AudioWeb {
return new Promise((res: Function, rej: Function) => {
this.stopVisualize();
this.recorder.onstop = (e) => {
this.recorder.onstop = (e: Event) => {
let blob = new Blob(this.chunks, { 'type': AUDIO_TYPE });
this.last = {
url: URL.createObjectURL(blob),
......
......@@ -3,7 +3,7 @@ import { h, Component } from 'preact';
const CHARACTER_DELAY = 80;
const PARAGRAPH_DELAY = 3500;
interface Props {
interface Props extends preact.ComponentProps<RobotTalker> {
}
interface State {
......@@ -14,10 +14,10 @@ interface State {
* Handle robot transitions.
*/
export default class RobotTalker extends Component<Props, State> {
timeoutHandle: number;
timeoutHandle: any;
remainingParagraphs: string[];
constructor(props) {
constructor(props: Props) {
super(props);
this.nextParagraph = this.nextParagraph.bind(this);
this.updateCharacter = this.updateCharacter.bind(this);
......@@ -64,13 +64,13 @@ export default class RobotTalker extends Component<Props, State> {
}, PARAGRAPH_DELAY * 0.85);
}
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props) {
if (nextProps.children !== this.props.children) {
this.remainingParagraphs = [];
for (let i = 0; i < nextProps.children.length; i++) {
let textParent = nextProps.children[i];
let textParent: JSX.Element = nextProps.children[i];
if (textParent) {
this.remainingParagraphs.push(textParent.children[0]);
this.remainingParagraphs.push(textParent.children[0].toString());
}
}
......
......@@ -9,7 +9,7 @@ const MODE_THUMBS_UP = '/img/robot-thumbs-up.png';
const SPEECH_GREETINGS = 'Click here to help me learn!';
interface Props {
interface Props extends preact.ComponentProps<Robot> {
position?: string;
onClick(page: string): void;
}
......@@ -28,7 +28,7 @@ export default class Robot extends Component<Props, State> {
speech: ''
}
constructor(props) {
constructor(props: Props) {
super(props);
this.handleSpeechClick = this.handleSpeechClick.bind(this);
......
......@@ -22,7 +22,7 @@ interface State {
*/
export default class Validator extends Component<Props, State> {
constructor(props) {
constructor(props: Props) {
super(props);
this.onVote = this.onVote.bind(this);
this.loadClip = this.loadClip.bind(this);
......
import { isProduction } from './utility';
declare var ga;
declare var ga: any;
const CATEGORY_RECORD = 'Recording';
const CATEGORY_LISTEN = 'Listening';
......
......@@ -3,7 +3,28 @@ import Tracker from './tracker';
const USER_KEY = 'userdata';
export const ACCENTS = {
interface UserAccents {
[key: string]: string;
'': string;
'us': string;
'australia': string;
'england': string;
'canada': string;
'philippines': string;
'hongkong': string;
'indian': string;
'ireland': string;
'malaysia': string;
'newzealand': string;
'scotland': string;
'singapore': string;
'southatlandtic': string;
'african': string;
'wales': string;
'bermuda': string;
};
export const ACCENTS: UserAccents = {
'': '--',
'us': 'United States English',
'australia': 'Australian English',
......@@ -23,7 +44,21 @@ export const ACCENTS = {
'bermuda': 'West Indies and Bermuda (Bahamas, Bermuda, Jamaica, Trinidad)',
};
export const AGES = {
interface UserAges {
[key: string]: string;
'': string;
'teens': string;
'twenties': string;
'thirties': string;
'fourties': string;
'fifties': string;
'sixties': string;
'seventies': string;
'eighties': string;
'nineties': string;
};
export const AGES: UserAges = {
'': '--',
'teens': '< 19',
'twenties': '19 - 29',
......@@ -36,7 +71,15 @@ export const AGES = {
'nineties': '> 89',
};
export const GENDER = {
interface UserGender {
[key: string]: string;
'': '--',
'male': 'Male',
'female': 'Female',
'other': 'Other'
};
export const GENDER: UserGender = {
'': '--',
'male': 'Male',
'female': 'Female',
......
......@@ -15,8 +15,8 @@ export function generateGUID(): string {
/**
* Capitalize first letter for nice display.
*/
export function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
export function capitalizeFirstLetter(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment