feat: 🎸 Fix image load and typescript errors (#570)

* Update Cocoapods version
* Use new api GetRequestHeaders to get headers
* Remove warnings of missing colors and brushes
* Fix typing errors
* Change affected main branch to main
* Remove unused feature toggle
* Add dummy login checker to remove using any
This commit is contained in:
Andreas Eriksson 2021-12-02 15:34:15 +01:00 committed by GitHub
parent aea848f66a
commit 933a8840a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 84 additions and 54 deletions

View File

@ -1,4 +1,4 @@
import { CalendarItem } from '@skolplattformen/api-skolplattformen'
import { CalendarItem } from '@skolplattformen/api'
import { useCalendar } from '@skolplattformen/hooks'
import {
Divider,

View File

@ -1,4 +1,4 @@
import { Child } from '@skolplattformen/api-skolplattformen'
import { Child } from '@skolplattformen/api'
import React, { createContext, useContext } from 'react'
interface ChildProviderProps {

View File

@ -1,7 +1,7 @@
/* eslint-disable react-native-a11y/has-accessibility-hint */
import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { Child } from '@skolplattformen/api-skolplattformen'
import { Child } from '@skolplattformen/api'
import {
useCalendar,
useClassmates,

View File

@ -1,5 +1,5 @@
import { useNavigation } from '@react-navigation/core'
import { Child } from '@skolplattformen/api-skolplattformen'
import { Child } from '@skolplattformen/api'
import { useApi, useChildList } from '@skolplattformen/hooks'
import {
Button,

View File

@ -1,4 +1,4 @@
import { Classmate } from '@skolplattformen/api-skolplattformen'
import { Classmate } from '@skolplattformen/api'
import { useClassmates } from '@skolplattformen/hooks'
import {
Divider,

View File

@ -1,5 +1,5 @@
/* eslint-disable react-native-a11y/has-accessibility-hint */
import { Classmate } from '@skolplattformen/api-skolplattformen'
import { Classmate } from '@skolplattformen/api'
import {
Button,
MenuGroup,

View File

@ -1,4 +1,4 @@
import { Child } from '@skolplattformen/api-skolplattformen'
import { Child } from '@skolplattformen/api'
import { useTimetable } from '@skolplattformen/hooks'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import moment, { Moment } from 'moment'

View File

@ -31,7 +31,7 @@ export const Image = ({
resizeMode = 'contain',
}: ImageProps) => {
const { api } = useApi()
const [headers, setHeaders] = useState()
const [headers, setHeaders] = useState<{ [index: string]: string }>()
const { width: windowWidth } = useWindowDimensions()
const [dimensions, setDimensions] = useState({ width: 0, height: 0 })
@ -40,7 +40,7 @@ export const Image = ({
const prefetchImageInformation = useCallback(
async (url: string) => {
if (!url) return
const { headers: newHeaders } = await api.getSession(url)
const newHeaders = await api.getSessionHeaders(url)
console.log('[IMAGE] Getting image dimensions with headers', {
debugImageName,

View File

@ -1,4 +1,4 @@
import { MenuItem } from '@skolplattformen/api-skolplattformen'
import { MenuItem } from '@skolplattformen/api'
import { useMenu } from '@skolplattformen/hooks'
import {
Divider,

View File

@ -1,4 +1,4 @@
import { MenuItem } from '@skolplattformen/api-skolplattformen'
import { MenuItem } from '@skolplattformen/api'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import React from 'react'
import { View } from 'react-native'

View File

@ -20,12 +20,12 @@ export const ModalWebView = ({
const [modalVisible, setModalVisible] = React.useState(true)
const { api } = useApi()
const [title, setTitle] = React.useState('...')
const [headers, setHeaders] = useState()
const [headers, setHeaders] = useState<{ [index: string]: string }>()
useEffect(() => {
const getHeaders = async (urlToGetSessionFor: string) => {
if (sharedCookiesEnabled) return
const { headers: newHeaders } = await api.getSession(urlToGetSessionFor)
const newHeaders = await api.getSessionHeaders(urlToGetSessionFor)
setHeaders(newHeaders)
}

View File

@ -2,7 +2,7 @@ import { NavigationContainer } from '@react-navigation/native'
import {
Child as ChildType,
NewsItem as NewsItemType,
} from '@skolplattformen/api-skolplattformen'
} from '@skolplattformen/api'
import { useApi } from '@skolplattformen/hooks'
import { useTheme } from '@ui-kitten/components'
import { Library } from 'libraries.json'

View File

@ -1,6 +1,6 @@
import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { NewsItem } from '@skolplattformen/api-skolplattformen'
import { NewsItem } from '@skolplattformen/api'
import { StyleService, useStyleSheet } from '@ui-kitten/components'
import moment from 'moment'
import React, { ReactNode } from 'react'

View File

@ -1,4 +1,4 @@
import { Notification as NotificationType } from '@skolplattformen/api-skolplattformen'
import { Notification as NotificationType } from '@skolplattformen/api'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import moment from 'moment'
import React from 'react'

View File

@ -1,4 +1,4 @@
import { CalendarItem } from '@skolplattformen/api-skolplattformen'
import { CalendarItem } from '@skolplattformen/api'
import { Button, MenuItem, OverflowMenu, Text } from '@ui-kitten/components'
import React from 'react'
import RNCalendarEvents from 'react-native-calendar-events'

View File

@ -1,8 +1,4 @@
import {
Child,
MenuItem,
TimetableEntry,
} from '@skolplattformen/api-skolplattformen'
import { Child, MenuItem, TimetableEntry } from '@skolplattformen/api'
import { useMenu, useTimetable } from '@skolplattformen/hooks'
import {
List,

View File

@ -2,8 +2,9 @@ import { Features, FeatureType } from '@skolplattformen/api'
import React from 'react'
export const FeatureFlagsContext = React.createContext<Features>({
LOGIN_BANK_ID_SAME_DEVICE: false,
LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: true,
FOOD_MENU: false,
CLASS_LIST: true,
})
interface Props {

View File

@ -16,7 +16,7 @@ export const SchoolPlatformProvider: React.FC = ({ children }) => {
'currentSchoolPlatform'
)
const changeSchoolPlatform = (platform: string) => {
const changeSchoolPlatform = (platform) => {
setCurrentSchoolPlatform(platform)
}

View File

@ -10,13 +10,13 @@ export const schoolPlatforms = [
{
id: 'stockholm-skolplattformen',
displayName: 'Stockholm stad (Skolplattformen)',
api: initSkolplattformen(fetch, CookieManager),
api: initSkolplattformen(fetch as any, CookieManager),
features: featuresSkolPlattformen,
},
{
id: 'goteborg-hjarntorget',
displayName: 'Göteborg stad (Hjärntorget)',
api: initHjarntorget(fetch, CookieManager),
api: initHjarntorget(fetch as any, CookieManager),
features: featuresHjarntorget,
},
]

View File

@ -1,5 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { User } from '@skolplattformen/api-skolplattformen'
import { User } from '@skolplattformen/api'
import { act, renderHook } from '@testing-library/react-hooks'
import usePersonalStorage from '../usePersonalStorage'

View File

@ -669,4 +669,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 85f5a2dfa1de342b427eecb6e9652410ad153247
COCOAPODS: 1.10.1
COCOAPODS: 1.11.2

View File

@ -1,5 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { User } from '@skolplattformen/api-skolplattformen'
import { User } from '@skolplattformen/api'
import AppStorage from '../appStorage'
beforeEach(() => {

View File

@ -1,5 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { User } from '@skolplattformen/api-skolplattformen'
import { User } from '@skolplattformen/api'
export default class AppStorage {
static settingsStorageKeyPrefix = 'appsetting_'

View File

@ -1,4 +1,4 @@
import { Guardian } from '@skolplattformen/api-skolplattformen'
import { Guardian } from '@skolplattformen/api'
export const studentName = (name?: string) => name?.replace(/\s?\(\w+\)$/, '')

View File

@ -1,4 +1,4 @@
import { NewsItem } from '@skolplattformen/api-skolplattformen'
import { NewsItem } from '@skolplattformen/api'
import { useNews } from '@skolplattformen/hooks'
import { MatchData, Searcher } from 'fast-fuzzy'
import React, { ReactNode, useMemo } from 'react'

View File

@ -5,6 +5,7 @@ import { EvaIconsPack } from '@ui-kitten/eva-icons'
import React, { ReactElement } from 'react'
import { LanguageProvider } from '../context/language/languageContext'
import { translations } from './translation'
import { lightTheme } from '../design/themes'
export const render = (
ui: ReactElement<any, string>,
@ -14,7 +15,7 @@ export const render = (
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={eva.light}>
<ApplicationProvider {...eva} theme={lightTheme}>
<LanguageProvider
cache={false}
data={translations}

View File

@ -5,6 +5,7 @@ import {
Classmate,
CookieManager,
EtjanstChild,
Fetch,
Fetcher,
FetcherOptions,
LoginStatusChecker,
@ -24,7 +25,7 @@ import { decode } from 'he'
import { DateTime, FixedOffsetZone } from 'luxon'
import * as html from 'node-html-parser'
import { fakeFetcher } from './fake/fakeFetcher'
import { checkStatus } from './loginStatus'
import { checkStatus, DummyStatusChecker } from './loginStatus'
import { extractMvghostRequestBody, parseCalendarItem } from './parse/parsers'
import {
beginBankIdUrl,
@ -84,7 +85,7 @@ export class ApiHjarntorget extends EventEmitter implements Api {
}
constructor(
fetch: typeof global.fetch,
fetch: Fetch,
cookieManager: CookieManager,
options?: FetcherOptions
) {
@ -138,6 +139,13 @@ export class ApiHjarntorget extends EventEmitter implements Api {
return this.personalNumber
}
public async getSessionHeaders(url: string): Promise<{ [index: string]: string }> {
const cookie = await this.cookieManager.getCookieString(url)
return {
cookie,
}
}
async setSessionCookie(sessionCookie: string): Promise<void> {
await this.fetch('login-cookie', hjarntorgetUrl, {
headers: {
@ -490,13 +498,13 @@ export class ApiHjarntorget extends EventEmitter implements Api {
if((beginLoginRedirectResponse as any).url.endsWith("startPage.do")) {
// already logged in!
const emitter = new EventEmitter()
const emitter = new DummyStatusChecker()
setTimeout(() => {
this.isLoggedIn = true
emitter.emit('OK')
this.emit('login')
}, 50)
return emitter;
return emitter as LoginStatusChecker;
}
console.log('prepping??? shibboleth')

File diff suppressed because one or more lines are too long

View File

@ -28,10 +28,9 @@ const fetchMappings: { [name:string]: () => Response} = {
'event-role-members-24-821': eventRoleMembers24,
'calendars': calendars,
'calendar-14241345': calendar_14241345,
}
export const fakeFetcher: Fetcher = (name: string, url: string, init?: any): Promise<Response> => {
const responder = fetchMappings[name] ?? (() => {throw new Error("Request not faked for name: " + name)})
return Promise.resolve(responder());
}
}

View File

@ -10,7 +10,7 @@ import {
pollStatusUrl,
} from './routes'
export class HjarntorgetChecker extends EventEmitter {
export class HjarntorgetChecker extends EventEmitter implements LoginStatusChecker {
private fetcher: Fetcher
private basePollingUrl: string
@ -120,3 +120,10 @@ export const checkStatus = (
fetch: Fetcher,
basePollingUrl: string
): LoginStatusChecker => new HjarntorgetChecker(fetch, basePollingUrl)
export class DummyStatusChecker extends EventEmitter implements LoginStatusChecker {
token = ""
async cancel(): Promise<void> {
// do nothing
}
}

View File

@ -16,7 +16,7 @@ the concrete implementation of fetch and cookie handler must be injected.
#### react-native
```javascript
import init from '@skolplattformen/api-skolplattformen'
import init from '@skolplattformen/api'
import CookieManager from '@react-native-cookies/cookies'
const api = init(fetch, () => CookieManager.clearAll())
@ -25,7 +25,7 @@ const api = init(fetch, () => CookieManager.clearAll())
#### node
```javascript
import init from '@skolplattformen/api-skolplattformen'
import init from '@skolplattformen/api'
import nodeFetch from 'node-fetch'
import fetchCookie from 'fetch-cookie/node-fetch'
import { CookieJar } from 'tough-cookie'

View File

@ -28,7 +28,7 @@ import { decode } from 'he'
import { DateTime } from 'luxon'
import * as html from 'node-html-parser'
import * as fake from './fakeData'
import { checkStatus } from './loginStatusChecker'
import { checkStatus, DummyStatusChecker } from './loginStatusChecker'
import * as parse from './parse/index'
import * as routes from './routes'
@ -94,6 +94,16 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
}
}
public async getSessionHeaders(url: string): Promise<{ [index: string]: string }> {
const init = this.getRequestInit()
const cookie = await this.cookieManager.getCookieString(url)
return {
...init.headers,
cookie,
}
}
public async getSession(
url: string,
options?: RequestInit
@ -203,8 +213,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
this.emit('login')
}, 50)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const emitter: any = new EventEmitter()
const emitter = new DummyStatusChecker()
emitter.token = 'fake'
return emitter
}

View File

@ -2,7 +2,7 @@ import { EventEmitter } from 'events';
import { loginStatus } from './routes';
import { AuthTicket, Fetcher, LoginStatusChecker } from '@skolplattformen/api';
export class Checker extends EventEmitter {
export class Checker extends EventEmitter implements LoginStatusChecker {
public token: string;
private fetcher: Fetcher;
@ -41,3 +41,10 @@ export const checkStatus = (
fetch: Fetcher,
ticket: AuthTicket
): LoginStatusChecker => new Checker(fetch, ticket)
export class DummyStatusChecker extends EventEmitter implements LoginStatusChecker {
token = ""
async cancel(): Promise<void> {
// do nothing
}
}

View File

@ -21,6 +21,7 @@ export interface Api extends EventEmitter {
getPersonalNumber(): string | undefined
login(personalNumber?: string): Promise<LoginStatusChecker>
setSessionCookie(sessionCookie: string): Promise<void>
getSessionHeaders(url: string): Promise<{ [index: string]: string }>
getUser(): Promise<User>
getChildren(): Promise<EtjanstChild[]>
getCalendar(child: EtjanstChild): Promise<CalendarItem[]>

View File

@ -18,7 +18,7 @@ In order to use api hooks, you must wrap your app in an ApiProvider
```javascript
import React from 'react'
import { ApiProvider } from '@skolplattformen/hooks'
import init from '@skolplattformen/api-skolplattformen'
import init from '@skolplattformen/api-skolplattformet'
import { CookieManager } from '@react-native-cookies/cookies'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { RootComponent } from './components/root'

View File

@ -107,7 +107,7 @@ const hook = <T>(
if (newState.error) {
const description = `Error getting ${entityName} from API`
reporter.error(newState.error, description)
reporter.error && reporter.error(newState.error, description)
}
}
}