FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: Don't crash on missing resources in tab-view and action-bar (#6388) · NativeScript/NativeScript@56a1b12 · GitHub

Commit 56a1b12

Browse files
Alexander Vakrilov
authored
fix: Don't crash on missing resources in tab-view and action-bar (#6388)
1 parent 5b77017 commit 56a1b12

6 files changed

Lines changed: 68 additions & 25 deletions

File tree

‎tns-core-modules/ui/action-bar/action-bar-common.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ import { profile } from "../../profiling";
99

1010
export * from "../core/view";
1111

12-
import { View, ViewBase, Property, unsetValue, booleanConverter, horizontalAlignmentProperty, verticalAlignmentProperty, CSSType } from "../core/view";
12+
import {
13+
View, ViewBase, Property,
14+
unsetValue, booleanConverter,
15+
horizontalAlignmentProperty,
16+
verticalAlignmentProperty, CSSType,
17+
traceWrite, traceCategories, traceMessageType
18+
} from "../core/view";
1319

1420
export module knownCollections {
1521
export var actionItems = "actionItems";
@@ -334,6 +340,12 @@ function onVisibilityChanged(item: ActionItemBase, oldValue: string, newValue: s
334340
item._onVisibilityChanged(newValue);
335341
}
336342

343+
export function traceMissingIcon(icon: string) {
344+
traceWrite("Could not load action bar icon: " + icon,
345+
traceCategories.Error,
346+
traceMessageType.error);
347+
}
348+
337349
export const textProperty = new Property<ActionItemBase, string>({ name: "text", defaultValue: "", valueChanged: onItemChanged });
338350
textProperty.register(ActionItemBase);
339351

‎tns-core-modules/ui/action-bar/action-bar.android.ts‎

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { AndroidActionBarSettings as AndroidActionBarSettingsDefinition, AndroidActionItemSettings } from ".";
2-
import { ActionItemBase, ActionBarBase, isVisible, View, layout, colorProperty, flatProperty, Color } from "./action-bar-common";
2+
import {
3+
ActionItemBase, ActionBarBase, isVisible,
4+
View, layout, colorProperty, flatProperty,
5+
Color, traceMissingIcon
6+
} from "./action-bar-common";
37
import { RESOURCE_PREFIX } from "../../utils/utils";
48
import { fromFileOrResource } from "../../image-source";
59
import * as application from "../../application";
@@ -18,7 +22,7 @@ function generateItemId(): number {
1822
}
1923

2024
interface MenuItemClickListener {
21-
new (owner: ActionBar): android.support.v7.widget.Toolbar.OnMenuItemClickListener;
25+
new(owner: ActionBar): android.support.v7.widget.Toolbar.OnMenuItemClickListener;
2226
}
2327

2428
let appResources: android.content.res.Resources;
@@ -219,7 +223,9 @@ export class ActionBar extends ActionBarBase {
219223
}
220224
else if (navButton.icon) {
221225
let drawableOrId = getDrawableOrResourceId(navButton.icon, appResources);
222-
this.nativeViewProtected.setNavigationIcon(drawableOrId);
226+
if (drawableOrId) {
227+
this.nativeViewProtected.setNavigationIcon(drawableOrId);
228+
}
223229
}
224230

225231
// Set navigation content descripion, used by screen readers for the vision-impaired users
@@ -304,9 +310,6 @@ export class ActionBar extends ActionBarBase {
304310
if (drawableOrId) {
305311
menuItem.setIcon(drawableOrId);
306312
}
307-
else {
308-
throw new Error("Error loading icon from " + item.icon);
309-
}
310313
}
311314

312315
let showAsAction = getShowAsAction(item);
@@ -422,10 +425,11 @@ function getDrawableOrResourceId(icon: string, resources: android.content.res.Re
422425
return undefined;
423426
}
424427

428+
let result = undefined;
425429
if (icon.indexOf(RESOURCE_PREFIX) === 0) {
426430
let resourceId: number = resources.getIdentifier(icon.substr(RESOURCE_PREFIX.length), "drawable", application.android.packageName);
427431
if (resourceId > 0) {
428-
return resourceId;
432+
result = resourceId;
429433
}
430434
}
431435
else {
@@ -436,10 +440,14 @@ function getDrawableOrResourceId(icon: string, resources: android.content.res.Re
436440
drawable = new android.graphics.drawable.BitmapDrawable(is.android);
437441
}
438442

439-
return drawable;
443+
result = drawable;
444+
}
445+
446+
if (!result) {
447+
traceMissingIcon(icon);
440448
}
441449

442-
return undefined;
450+
return result;
443451
}
444452

445453
function getShowAsAction(menuItem: ActionItem): number {

‎tns-core-modules/ui/action-bar/action-bar.ios.ts‎

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
import { IOSActionItemSettings, ActionItem as ActionItemDefinition } from ".";
2-
import { ActionItemBase, ActionBarBase, isVisible, View, colorProperty, backgroundColorProperty, backgroundInternalProperty, flatProperty, layout, Color } from "./action-bar-common";
3-
import { ImageSource, fromFileOrResource } from "../../image-source";
2+
import {
3+
ActionItemBase, ActionBarBase, isVisible, View,
4+
colorProperty, backgroundColorProperty,
5+
backgroundInternalProperty, flatProperty,
6+
layout, Color, traceMissingIcon } from "./action-bar-common";
7+
import { fromFileOrResource } from "../../image-source";
48
import { ios as iosUtils } from "../../utils/utils";
9+
import { write as traceWrite, categories, messageType } from "../../trace";
510

611
export * from "./action-bar-common";
712

813
const majorVersion = iosUtils.MajorVersion;
914
const UNSPECIFIED = layout.makeMeasureSpec(0, layout.UNSPECIFIED);
1015

16+
function loadActionIconFromFileOrResource(icon: string): UIImage {
17+
const img = fromFileOrResource(icon);
18+
if (img && img.ios) {
19+
return img.ios;
20+
} else {
21+
traceMissingIcon(icon);
22+
return null;
23+
}
24+
}
25+
1126
class TapBarItemHandlerImpl extends NSObject {
1227
private _owner: WeakRef<ActionItemDefinition>;
1328

@@ -151,16 +166,16 @@ export class ActionBar extends ActionBarBase {
151166
}
152167

153168
// Set back button image
154-
let img: ImageSource;
169+
let img: UIImage;
155170
if (this.navigationButton && isVisible(this.navigationButton) && this.navigationButton.icon) {
156-
img = fromFileOrResource(this.navigationButton.icon);
171+
img = loadActionIconFromFileOrResource(this.navigationButton.icon);
157172
}
158173

159174
// TODO: This could cause issue when canceling BackEdge gesture - we will change the backIndicator to
160175
// show the one from the old page but the new page will still be visible (because we canceled EdgeBackSwipe gesutre)
161176
// Consider moving this to new method and call it from - navigationControllerDidShowViewControllerAnimated.
162-
if (img && img.ios) {
163-
let image = img.ios.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
177+
if (img) {
178+
let image = img.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
164179
navigationBar.backIndicatorImage = image;
165180
navigationBar.backIndicatorTransitionMaskImage = image;
166181
} else {
@@ -226,12 +241,8 @@ export class ActionBar extends ActionBarBase {
226241

227242
barButtonItem = UIBarButtonItem.alloc().initWithBarButtonSystemItemTargetAction(id, tapHandler, "tap");
228243
} else if (item.icon) {
229-
const img = fromFileOrResource(item.icon);
230-
if (img && img.ios) {
231-
barButtonItem = UIBarButtonItem.alloc().initWithImageStyleTargetAction(img.ios, UIBarButtonItemStyle.Plain, tapHandler, "tap");
232-
} else {
233-
throw new Error("Error loading icon from " + item.icon);
234-
}
244+
const img = loadActionIconFromFileOrResource(item.icon);
245+
barButtonItem = UIBarButtonItem.alloc().initWithImageStyleTargetAction(img, UIBarButtonItemStyle.Plain, tapHandler, "tap");
235246
} else {
236247
barButtonItem = UIBarButtonItem.alloc().initWithTitleStyleTargetAction(item.text + "", UIBarButtonItemStyle.Plain, tapHandler, "tap");
237248
}

‎tns-core-modules/ui/tab-view/tab-view-common.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { TabView as TabViewDefinition, TabViewItem as TabViewItemDefinition, SelectedIndexChangedEventData } from ".";
22
import {
33
View, ViewBase, Style, Property, CssProperty, CoercibleProperty,
4-
Color, isIOS, AddArrayFromBuilder, AddChildFromBuilder, EventData, CSSType
4+
Color, isIOS, AddArrayFromBuilder, AddChildFromBuilder, EventData, CSSType,
5+
traceWrite, traceCategories, traceMessageType
56
} from "../core/view";
67

78
export * from "../core/view";
@@ -203,6 +204,10 @@ export interface TabViewBase {
203204
on(event: "selectedIndexChanged", callback: (args: SelectedIndexChangedEventData) => void, thisArg?: any);
204205
}
205206

207+
export function traceMissingIcon(icon: string) {
208+
traceWrite("Could not load tab bar icon: " + icon, traceCategories.Error, traceMessageType.error);
209+
}
210+
206211
export const selectedIndexProperty = new CoercibleProperty<TabViewBase, number>({
207212
name: "selectedIndex", defaultValue: -1, affectsLayout: isIOS,
208213
valueChanged: (target, oldValue, newValue) => {

‎tns-core-modules/ui/tab-view/tab-view.android.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
tabTextColorProperty, tabBackgroundColorProperty, tabTextFontSizeProperty, selectedTabTextColorProperty,
77
androidSelectedTabHighlightColorProperty, androidOffscreenTabLimitProperty,
88
fontSizeProperty, fontInternalProperty, layout, traceCategory, traceEnabled,
9-
traceWrite, Color
9+
traceWrite, Color, traceMissingIcon
1010
} from "./tab-view-common"
1111
import { textTransformProperty, TextTransform, getTransformedText } from "../text-base";
1212
import { fromFileOrResource } from "../../image-source";
@@ -233,11 +233,16 @@ function createTabItemSpec(item: TabViewItem): org.nativescript.widgets.TabItemS
233233
if (item.iconSource) {
234234
if (item.iconSource.indexOf(RESOURCE_PREFIX) === 0) {
235235
result.iconId = ad.resources.getDrawableId(item.iconSource.substr(RESOURCE_PREFIX.length));
236+
if (result.iconId === 0) {
237+
traceMissingIcon(item.iconSource);
238+
}
236239
} else {
237240
const is = fromFileOrResource(item.iconSource);
238241
if (is) {
239242
// TODO: Make this native call that accepts string so that we don't load Bitmap in JS.
240243
result.iconDrawable = new android.graphics.drawable.BitmapDrawable(is.android);
244+
} else {
245+
traceMissingIcon(item.iconSource);
241246
}
242247
}
243248
}

‎tns-core-modules/ui/tab-view/tab-view.ios.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ios as iosView, ViewBase } from "../core/view";
55
import {
66
TabViewBase, TabViewItemBase, itemsProperty, selectedIndexProperty,
77
tabTextColorProperty, tabTextFontSizeProperty, tabBackgroundColorProperty, selectedTabTextColorProperty, iosIconRenderingModeProperty,
8-
View, fontInternalProperty, layout, traceEnabled, traceWrite, traceCategories, Color
8+
View, fontInternalProperty, layout, traceEnabled, traceWrite, traceCategories, Color, traceMissingIcon
99
} from "./tab-view-common"
1010
import { textTransformProperty, TextTransform, getTransformedText } from "../text-base";
1111
import { fromFileOrResource } from "../../image-source";
@@ -451,6 +451,8 @@ export class TabView extends TabViewBase {
451451
const originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode());
452452
this._iconsCache[iconSource] = originalRenderedImage;
453453
image = originalRenderedImage;
454+
} else {
455+
traceMissingIcon(iconSource);
454456
}
455457
}
456458

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL