Skip to content

Commit 09d43f2

Browse files
authored
Add a way to delete fonts from disk (#2752)
* Add a way to delete fonts from disk * Improve \ fix some errors * Review fixes * Review fixes (2)
1 parent 4fe73e5 commit 09d43f2

File tree

3 files changed

+77
-35
lines changed

3 files changed

+77
-35
lines changed

lib/components/DynamicFonts/FontDownloader.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ export default class FontDownloader {
3535
this.fs = RNFS;
3636
}
3737

38+
private log(message?: any, ...optionalParams: any[]) {
39+
const {debug} = this.props;
40+
if (debug) {
41+
console.log(message, optionalParams);
42+
}
43+
}
44+
3845
private getPrivateFolder() {
3946
const {dynamicFontsFolder} = this.props;
4047
return (
@@ -103,20 +110,24 @@ export default class FontDownloader {
103110
const downloadLocation = this.getPrivateFilePath(fileName);
104111

105112
try {
113+
this.log(fontName, 'Starting to download');
106114
const result = await this.fs.downloadFile(this.getDownloadFontOptions(fontUri, downloadLocation, timeout))
107115
.promise;
108116
if (result.statusCode === 200) {
117+
this.log(fontName, 'Finished downloading');
109118
return downloadLocation;
110119
} else {
120+
this.log(fontName, 'Error downloading statusCode:', result.statusCode);
111121
return Promise.reject({
112122
source: 'uilib:FontDownloader:downloadFont',
113123
message: `${downloadErrorMessage} fontName: ${fontName} statusCode: ${result.statusCode}`
114124
});
115125
}
116126
} catch (error) {
127+
this.log(fontName, 'Error downloading error:', error);
117128
return Promise.reject({
118129
source: 'uilib:FontDownloader:downloadFont',
119-
message: `${downloadErrorMessage} fontName: ${fontName} error: ${error}`
130+
message: `${downloadErrorMessage} fontName: ${fontName} error: ${JSON.stringify(error)}`
120131
});
121132
}
122133
}
@@ -136,9 +147,28 @@ export default class FontDownloader {
136147
const fileName = this.getFileName(fontName, fontExtension);
137148
const privateFilePath = this.getPrivateFilePath(fileName);
138149
if (await this.fs.exists(privateFilePath)) {
139-
base64FontString = await this.fs.readFile(privateFilePath, 'base64').catch(() => {});
150+
this.log(fontName, 'Starting to read from disk');
151+
base64FontString = await this.fs.readFile(privateFilePath, 'base64').catch(err => {
152+
this.log(fontName, 'Failed reading from disk:', err);
153+
});
154+
this.log(fontName, 'Finished reading from disk');
155+
} else {
156+
this.log(fontName, 'File does not exist (read)');
140157
}
141158

142159
return base64FontString;
143160
}
161+
162+
public async deleteFontFromDisk(fontFullName: string): Promise<void> {
163+
const privateFilePath = this.getPrivateFilePath(fontFullName);
164+
if (await this.fs.exists(privateFilePath)) {
165+
this.log(fontFullName, 'Starting to delete');
166+
await this.fs.unlink(privateFilePath).catch(err => {
167+
this.log(fontFullName, 'Failed deleting:', err);
168+
});
169+
this.log(fontFullName, 'Finished deleting');
170+
} else {
171+
this.log(fontFullName, 'File does not exist (delete)');
172+
}
173+
}
144174
}

lib/components/DynamicFonts/FontLoader.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,22 @@ export default class FontLoader {
4040
this.props = props;
4141
}
4242

43+
private log(message?: any, ...optionalParams: any[]) {
44+
const {debug} = this.props;
45+
if (debug) {
46+
console.log(message, optionalParams);
47+
}
48+
}
49+
4350
public loadFont = ({
4451
fontName,
4552
base64FontString,
4653
fontExtension = 'ttf',
4754
forceLoad = false
4855
}: LoadFontInput): Promise<string> => {
49-
const {debug} = this.props;
5056
/* Check if this font was already loaded */
5157
if (!forceLoad && this.loadedFonts.has(fontName)) {
52-
if (debug) {
53-
console.log(fontName, 'Already loaded');
54-
}
58+
this.log(fontName, 'Already loaded');
5559
return Promise.resolve(this.loadedFonts.get(fontName) as string);
5660
}
5761

@@ -63,9 +67,7 @@ export default class FontLoader {
6367
throw new Error('base64FontString is a required argument');
6468
}
6569

66-
if (debug) {
67-
console.log(fontName, 'Starting to load');
68-
}
70+
this.log(fontName, 'Starting to load');
6971
/* Load font via native binary code */
7072
return new Promise((resolve, reject) => {
7173
DynamicFont.loadFont({

lib/components/DynamicFonts/index.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,29 @@ export default class DynamicFonts {
4545
private readonly fontDownloader: InstanceType<typeof FontDownloader>;
4646

4747
constructor(props: DynamicFontsProps) {
48-
const {debug} = props;
48+
const {debug = __DEV__} = props;
4949
this.props = {fontLoadErrorMessage: DEFAULT_FONT_LOAD_ERROR_MESSAGE, ...props};
5050
this.permissionsAcquirer = new PermissionsAcquirer(this.props.permissionsAcquirerProps ?? {});
5151
this.fontLoader = new FontLoader({debug});
5252
const fontDownloadingProps = this.props.fontDownloadingProps ?? {};
5353
this.fontDownloader = new FontDownloader({...fontDownloadingProps, debug});
5454
}
5555

56+
private log(message?: any, ...optionalParams: any[]) {
57+
const {debug} = this.props;
58+
if (debug) {
59+
console.log(message, optionalParams);
60+
}
61+
}
62+
5663
private async loadFont(input: LoadFontInput) {
5764
const {fontLoadErrorMessage} = this.props;
5865
try {
5966
return await this.fontLoader.loadFont(input);
6067
} catch (err) {
6168
return Promise.reject({
6269
source: 'uilib:FontDownloader:loadFont',
63-
message: `${fontLoadErrorMessage} fontName: ${input.fontName}`
70+
message: `${fontLoadErrorMessage} fontName: ${input.fontName} error: ${JSON.stringify(err)}`
6471
});
6572
}
6673
}
@@ -74,32 +81,19 @@ export default class DynamicFonts {
7481
* @param timeout milliseconds for the download to complete in (defaults to 5000)
7582
*/
7683
public async getFont({fontUri, fontName, fontExtension, timeout = 5000}: GetFontInput): Promise<string> {
77-
const {debug} = this.props;
7884
const {fontLoadErrorMessage} = this.props;
7985
await this.permissionsAcquirer.getPermissions();
8086
if (await this.fontDownloader.isFontDownloaded(fontName, fontExtension)) {
81-
if (debug) {
82-
console.log(fontName, 'Already downloaded');
83-
}
87+
this.log(fontName, 'Already downloaded');
8488
} else {
85-
if (debug) {
86-
console.log(fontName, 'Starting to download');
87-
}
8889
await this.fontDownloader.downloadFont(fontUri, fontName, fontExtension, timeout);
89-
if (debug) {
90-
console.log(fontName, 'Finished downloading');
91-
}
9290
}
9391

9492
const base64FontString = await this.fontDownloader.readFontFromDisk(fontName, fontExtension);
9593
if (base64FontString) {
96-
if (debug) {
97-
console.log(fontName, 'Loading');
98-
}
94+
this.log(fontName, 'Loading');
9995
const _fontName = await this.loadFont({fontName, base64FontString, fontExtension});
100-
if (debug) {
101-
console.log(_fontName, 'Finished loading');
102-
}
96+
this.log(_fontName, 'Finished loading');
10397
return Promise.resolve(_fontName);
10498
} else {
10599
return Promise.reject({
@@ -118,13 +112,13 @@ export default class DynamicFonts {
118112
}
119113
}
120114

121-
private buildFontName(rootUri: string,
115+
private buildFontData(rootUri: string,
122116
fontName: string,
123117
fontExtension: FontExtension,
124-
fontNamePrefix?: string): GetFontInput {
118+
fontNamePrefix?: string): GetFontInput & {fullFontName: string} {
125119
const _fontName = `${fontNamePrefix ?? ''}${fontName}`;
126120
const fullFontName = `${_fontName}.${fontExtension}`;
127-
return {fontUri: `${rootUri}${fullFontName}`, fontName: _fontName, fontExtension};
121+
return {fontUri: `${rootUri}${fullFontName}`, fontName: _fontName, fontExtension, fullFontName};
128122
}
129123

130124
// eslint-disable-next-line max-params
@@ -133,9 +127,8 @@ export default class DynamicFonts {
133127
fontExtension: FontExtension,
134128
fontNamePrefix?: string,
135129
retries = 1): Promise<string[]> {
136-
const {debug} = this.props;
137130
const fonts: GetFontInput[] = fontNames.map(fontName =>
138-
this.buildFontName(rootUri, fontName, fontExtension, fontNamePrefix));
131+
this.buildFontData(rootUri, fontName, fontExtension, fontNamePrefix));
139132
let fontsLoaded: string[] = [];
140133
let tryCounter = 0;
141134
while (fontsLoaded.length < fontNames.length && tryCounter < retries) {
@@ -144,12 +137,29 @@ export default class DynamicFonts {
144137
// TODO: we should return successful loaded fonts and not fail all of them
145138
fontsLoaded = await this.getFonts(fonts);
146139
} catch (error) {
147-
if (debug) {
148-
console.log(`getFontFamily failed (try #${tryCounter}) error: ${error}`);
149-
}
140+
this.log(`getFontFamily failed (try #${tryCounter}) error:`, error);
150141
}
151142
}
152143

153144
return Promise.resolve(fontsLoaded);
154145
}
146+
147+
private async deleteFontFromDisk(fontName: string, fontExtension: FontExtension, fontNamePrefix?: string) {
148+
const fontInput = this.buildFontData('', fontName, fontExtension, fontNamePrefix);
149+
await this.fontDownloader.deleteFontFromDisk(fontInput.fullFontName);
150+
}
151+
152+
public async deleteFont(fontName: string, fontExtension: FontExtension): Promise<void> {
153+
await this.permissionsAcquirer.getPermissions();
154+
await this.deleteFontFromDisk(fontName, fontExtension);
155+
}
156+
157+
public async deleteFontFamily(fontNames: string[],
158+
fontExtension: FontExtension,
159+
fontNamePrefix?: string): Promise<void> {
160+
await this.permissionsAcquirer.getPermissions();
161+
fontNames.forEach(async fontName => {
162+
await this.deleteFontFromDisk(fontName, fontExtension, fontNamePrefix);
163+
});
164+
}
155165
}

0 commit comments

Comments
 (0)