feat: Implement colored blur backgrounds

This commit is contained in:
Lei Nelissen
2022-05-04 22:46:19 +02:00
parent 76f2db19e5
commit f48d248144
11 changed files with 331 additions and 127 deletions

View File

@@ -305,6 +305,35 @@ PODS:
- RCTTypeSafety - RCTTypeSafety
- React - React
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- react-native-skia (0.1.123):
- React
- React-callinvoker
- React-Core
- react-native-skia/Api (= 0.1.123)
- react-native-skia/Jsi (= 0.1.123)
- react-native-skia/RNSkia (= 0.1.123)
- react-native-skia/SkiaHeaders (= 0.1.123)
- react-native-skia/Utils (= 0.1.123)
- react-native-skia/Api (0.1.123):
- React
- React-callinvoker
- React-Core
- react-native-skia/Jsi (0.1.123):
- React
- React-callinvoker
- React-Core
- react-native-skia/RNSkia (0.1.123):
- React
- React-callinvoker
- React-Core
- react-native-skia/SkiaHeaders (0.1.123):
- React
- React-callinvoker
- React-Core
- react-native-skia/Utils (0.1.123):
- React
- React-callinvoker
- React-Core
- react-native-slider (4.2.2): - react-native-slider (4.2.2):
- React-Core - React-Core
- react-native-track-player (2.1.3): - react-native-track-player (2.1.3):
@@ -464,6 +493,7 @@ DEPENDENCIES:
- react-native-flipper (from `../node_modules/react-native-flipper`) - react-native-flipper (from `../node_modules/react-native-flipper`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- "react-native-skia (from `../node_modules/@shopify/react-native-skia`)"
- "react-native-slider (from `../node_modules/@react-native-community/slider`)" - "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-track-player (from `../node_modules/react-native-track-player`) - react-native-track-player (from `../node_modules/react-native-track-player`)
- react-native-webview (from `../node_modules/react-native-webview`) - react-native-webview (from `../node_modules/react-native-webview`)
@@ -561,6 +591,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/netinfo" :path: "../node_modules/@react-native-community/netinfo"
react-native-safe-area-context: react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context" :path: "../node_modules/react-native-safe-area-context"
react-native-skia:
:path: "../node_modules/@shopify/react-native-skia"
react-native-slider: react-native-slider:
:path: "../node_modules/@react-native-community/slider" :path: "../node_modules/@react-native-community/slider"
react-native-track-player: react-native-track-player:
@@ -652,6 +684,7 @@ SPEC CHECKSUMS:
react-native-flipper: b9e2e817604af8da0d5a9ba20a8516e780e30f3c react-native-flipper: b9e2e817604af8da0d5a9ba20a8516e780e30f3c
react-native-netinfo: 3671b091c4843fda5e153612866ef4024b8f5d62 react-native-netinfo: 3671b091c4843fda5e153612866ef4024b8f5d62
react-native-safe-area-context: ebf8c413eb8b5f7c392a036a315eb7b46b96845f react-native-safe-area-context: ebf8c413eb8b5f7c392a036a315eb7b46b96845f
react-native-skia: 8a3e1b513020e2c9b0b4e49404f396d2a88f9ac7
react-native-slider: 2f25c919f1dc309b90e2cc8346b8042ecec2102f react-native-slider: 2f25c919f1dc309b90e2cc8346b8042ecec2102f
react-native-track-player: c4147afddd29de936caa06561f78a32d6502eb12 react-native-track-player: c4147afddd29de936caa06561f78a32d6502eb12
react-native-webview: 8ec7ddf9eb4ddcd92b32cee7907efec19a9ec7cb react-native-webview: 8ec7ddf9eb4ddcd92b32cee7907efec19a9ec7cb

212
package-lock.json generated
View File

@@ -21,6 +21,7 @@
"@react-navigation/stack": "^6.2.1", "@react-navigation/stack": "^6.2.1",
"@reduxjs/toolkit": "^1.8.1", "@reduxjs/toolkit": "^1.8.1",
"@sentry/react-native": "^3.4.2", "@sentry/react-native": "^3.4.2",
"@shopify/react-native-skia": "^0.1.123",
"@types/lodash": "^4.14.182", "@types/lodash": "^4.14.182",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
"events": "^3.3.0", "events": "^3.3.0",
@@ -1066,11 +1067,11 @@
} }
}, },
"node_modules/@babel/plugin-syntax-typescript": { "node_modules/@babel/plugin-syntax-typescript": {
"version": "7.14.5", "version": "7.17.10",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz",
"integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "integrity": "sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ==",
"dependencies": { "dependencies": {
"@babel/helper-plugin-utils": "^7.14.5" "@babel/helper-plugin-utils": "^7.16.7"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@@ -1404,11 +1405,11 @@
} }
}, },
"node_modules/@babel/plugin-transform-object-assign": { "node_modules/@babel/plugin-transform-object-assign": {
"version": "7.14.5", "version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.7.tgz",
"integrity": "sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==", "integrity": "sha512-R8mawvm3x0COTJtveuoqZIjNypn2FjfvXZr4pSQ8VhEFBuQGBz4XhHasZtHXjgXU4XptZ4HtGof3NoYc93ZH9Q==",
"dependencies": { "dependencies": {
"@babel/helper-plugin-utils": "^7.14.5" "@babel/helper-plugin-utils": "^7.16.7"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@@ -1649,13 +1650,13 @@
} }
}, },
"node_modules/@babel/plugin-transform-typescript": { "node_modules/@babel/plugin-transform-typescript": {
"version": "7.15.8", "version": "7.16.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz",
"integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==",
"dependencies": { "dependencies": {
"@babel/helper-create-class-features-plugin": "^7.15.4", "@babel/helper-create-class-features-plugin": "^7.16.7",
"@babel/helper-plugin-utils": "^7.14.5", "@babel/helper-plugin-utils": "^7.16.7",
"@babel/plugin-syntax-typescript": "^7.14.5" "@babel/plugin-syntax-typescript": "^7.16.7"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@@ -1882,13 +1883,13 @@
} }
}, },
"node_modules/@babel/preset-typescript": { "node_modules/@babel/preset-typescript": {
"version": "7.15.0", "version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz",
"integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==",
"dependencies": { "dependencies": {
"@babel/helper-plugin-utils": "^7.14.5", "@babel/helper-plugin-utils": "^7.16.7",
"@babel/helper-validator-option": "^7.14.5", "@babel/helper-validator-option": "^7.16.7",
"@babel/plugin-transform-typescript": "^7.15.0" "@babel/plugin-transform-typescript": "^7.16.7"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@@ -4423,6 +4424,20 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@shopify/react-native-skia": {
"version": "0.1.123",
"resolved": "https://registry.npmjs.org/@shopify/react-native-skia/-/react-native-skia-0.1.123.tgz",
"integrity": "sha512-Yn9nHYRuTz84eCbHbpTi8VbP33tQc1D6rDQNEj7fgV6aPusaN79XjnnxtPsZsO+nLlbkpI3q1x+2Ds3Qu1I8ZA==",
"hasInstallScript": true,
"dependencies": {
"react-reconciler": "^0.26.2"
},
"peerDependencies": {
"react": ">=16.8.1",
"react-native": ">=0.63.0-rc.0 <1.0.x",
"react-native-reanimated": ">=2.0.0"
}
},
"node_modules/@sideway/address": { "node_modules/@sideway/address": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
@@ -4893,6 +4908,12 @@
"integrity": "sha512-F+AuFCjllE1A0W/YUxJB13q2t7cWITMqXOTXQ/InfXxxT8nXrrqL7s/8Pv6XThGjFPemukElwk6QlMOKCEg7eQ==", "integrity": "sha512-F+AuFCjllE1A0W/YUxJB13q2t7cWITMqXOTXQ/InfXxxT8nXrrqL7s/8Pv6XThGjFPemukElwk6QlMOKCEg7eQ==",
"dev": true "dev": true
}, },
"node_modules/@types/invariant": {
"version": "2.2.35",
"resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz",
"integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==",
"peer": true
},
"node_modules/@types/istanbul-lib-coverage": { "node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -12432,6 +12453,12 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
}, },
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
"peer": true
},
"node_modules/lodash.merge": { "node_modules/lodash.merge": {
"version": "4.6.2", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -14396,6 +14423,26 @@
} }
} }
}, },
"node_modules/react-native-reanimated": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.8.0.tgz",
"integrity": "sha512-kJvf/UWLBMaGCs9X66MKq5zdFMgwx8D0nHnolbHR7s8ZnbLdb7TlQ/yuzIXqn/9wABfnwtNRI3CyaP1aHWMmZg==",
"peer": true,
"dependencies": {
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@types/invariant": "^2.2.35",
"invariant": "^2.2.4",
"lodash.isequal": "^4.5.0",
"setimmediate": "^1.0.5",
"string-hash-64": "^1.0.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0",
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-safe-area-context": { "node_modules/react-native-safe-area-context": {
"version": "4.2.5", "version": "4.2.5",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.2.5.tgz", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.2.5.tgz",
@@ -15184,6 +15231,22 @@
"async-limiter": "~1.0.0" "async-limiter": "~1.0.0"
} }
}, },
"node_modules/react-reconciler": {
"version": "0.26.2",
"resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz",
"integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==",
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"scheduler": "^0.20.2"
},
"engines": {
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^17.0.2"
}
},
"node_modules/react-redux": { "node_modules/react-redux": {
"version": "7.2.6", "version": "7.2.6",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
@@ -15813,6 +15876,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"peer": true
},
"node_modules/setprototypeof": { "node_modules/setprototypeof": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@@ -16313,6 +16382,12 @@
"safe-buffer": "~5.1.0" "safe-buffer": "~5.1.0"
} }
}, },
"node_modules/string-hash-64": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz",
"integrity": "sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==",
"peer": true
},
"node_modules/string-length": { "node_modules/string-length": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -17996,11 +18071,11 @@
} }
}, },
"@babel/plugin-syntax-typescript": { "@babel/plugin-syntax-typescript": {
"version": "7.14.5", "version": "7.17.10",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz",
"integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "integrity": "sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ==",
"requires": { "requires": {
"@babel/helper-plugin-utils": "^7.14.5" "@babel/helper-plugin-utils": "^7.16.7"
} }
}, },
"@babel/plugin-transform-arrow-functions": { "@babel/plugin-transform-arrow-functions": {
@@ -18202,11 +18277,11 @@
} }
}, },
"@babel/plugin-transform-object-assign": { "@babel/plugin-transform-object-assign": {
"version": "7.14.5", "version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.7.tgz",
"integrity": "sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==", "integrity": "sha512-R8mawvm3x0COTJtveuoqZIjNypn2FjfvXZr4pSQ8VhEFBuQGBz4XhHasZtHXjgXU4XptZ4HtGof3NoYc93ZH9Q==",
"requires": { "requires": {
"@babel/helper-plugin-utils": "^7.14.5" "@babel/helper-plugin-utils": "^7.16.7"
} }
}, },
"@babel/plugin-transform-object-super": { "@babel/plugin-transform-object-super": {
@@ -18350,13 +18425,13 @@
} }
}, },
"@babel/plugin-transform-typescript": { "@babel/plugin-transform-typescript": {
"version": "7.15.8", "version": "7.16.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz",
"integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==",
"requires": { "requires": {
"@babel/helper-create-class-features-plugin": "^7.15.4", "@babel/helper-create-class-features-plugin": "^7.16.7",
"@babel/helper-plugin-utils": "^7.14.5", "@babel/helper-plugin-utils": "^7.16.7",
"@babel/plugin-syntax-typescript": "^7.14.5" "@babel/plugin-syntax-typescript": "^7.16.7"
} }
}, },
"@babel/plugin-transform-unicode-escapes": { "@babel/plugin-transform-unicode-escapes": {
@@ -18537,13 +18612,13 @@
} }
}, },
"@babel/preset-typescript": { "@babel/preset-typescript": {
"version": "7.15.0", "version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz",
"integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==",
"requires": { "requires": {
"@babel/helper-plugin-utils": "^7.14.5", "@babel/helper-plugin-utils": "^7.16.7",
"@babel/helper-validator-option": "^7.14.5", "@babel/helper-validator-option": "^7.16.7",
"@babel/plugin-transform-typescript": "^7.15.0" "@babel/plugin-transform-typescript": "^7.16.7"
} }
}, },
"@babel/register": { "@babel/register": {
@@ -20500,6 +20575,14 @@
} }
} }
}, },
"@shopify/react-native-skia": {
"version": "0.1.123",
"resolved": "https://registry.npmjs.org/@shopify/react-native-skia/-/react-native-skia-0.1.123.tgz",
"integrity": "sha512-Yn9nHYRuTz84eCbHbpTi8VbP33tQc1D6rDQNEj7fgV6aPusaN79XjnnxtPsZsO+nLlbkpI3q1x+2Ds3Qu1I8ZA==",
"requires": {
"react-reconciler": "^0.26.2"
}
},
"@sideway/address": { "@sideway/address": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
@@ -20809,6 +20892,12 @@
"integrity": "sha512-F+AuFCjllE1A0W/YUxJB13q2t7cWITMqXOTXQ/InfXxxT8nXrrqL7s/8Pv6XThGjFPemukElwk6QlMOKCEg7eQ==", "integrity": "sha512-F+AuFCjllE1A0W/YUxJB13q2t7cWITMqXOTXQ/InfXxxT8nXrrqL7s/8Pv6XThGjFPemukElwk6QlMOKCEg7eQ==",
"dev": true "dev": true
}, },
"@types/invariant": {
"version": "2.2.35",
"resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz",
"integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==",
"peer": true
},
"@types/istanbul-lib-coverage": { "@types/istanbul-lib-coverage": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -26592,6 +26681,12 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
}, },
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
"peer": true
},
"lodash.merge": { "lodash.merge": {
"version": "4.6.2", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -28718,6 +28813,21 @@
"integrity": "sha512-BuPaQWvxLZG1NrCDGqgAnecDrNQu3LED9/Pyl4H2LwTMHcEngXpE5PfVntW2GiLumdr6nUOkWmMnh8PynZqrsw==", "integrity": "sha512-BuPaQWvxLZG1NrCDGqgAnecDrNQu3LED9/Pyl4H2LwTMHcEngXpE5PfVntW2GiLumdr6nUOkWmMnh8PynZqrsw==",
"requires": {} "requires": {}
}, },
"react-native-reanimated": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.8.0.tgz",
"integrity": "sha512-kJvf/UWLBMaGCs9X66MKq5zdFMgwx8D0nHnolbHR7s8ZnbLdb7TlQ/yuzIXqn/9wABfnwtNRI3CyaP1aHWMmZg==",
"peer": true,
"requires": {
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@types/invariant": "^2.2.35",
"invariant": "^2.2.4",
"lodash.isequal": "^4.5.0",
"setimmediate": "^1.0.5",
"string-hash-64": "^1.0.3"
}
},
"react-native-safe-area-context": { "react-native-safe-area-context": {
"version": "4.2.5", "version": "4.2.5",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.2.5.tgz", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.2.5.tgz",
@@ -28782,6 +28892,16 @@
} }
} }
}, },
"react-reconciler": {
"version": "0.26.2",
"resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz",
"integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"scheduler": "^0.20.2"
}
},
"react-redux": { "react-redux": {
"version": "7.2.6", "version": "7.2.6",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
@@ -29278,6 +29398,12 @@
} }
} }
}, },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"peer": true
},
"setprototypeof": { "setprototypeof": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@@ -29687,6 +29813,12 @@
"safe-buffer": "~5.1.0" "safe-buffer": "~5.1.0"
} }
}, },
"string-hash-64": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz",
"integrity": "sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==",
"peer": true
},
"string-length": { "string-length": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",

View File

@@ -25,6 +25,7 @@
"@react-navigation/stack": "^6.2.1", "@react-navigation/stack": "^6.2.1",
"@reduxjs/toolkit": "^1.8.1", "@reduxjs/toolkit": "^1.8.1",
"@sentry/react-native": "^3.4.2", "@sentry/react-native": "^3.4.2",
"@shopify/react-native-skia": "^0.1.123",
"@types/lodash": "^4.14.182", "@types/lodash": "^4.14.182",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
"events": "^3.3.0", "events": "^3.3.0",

View File

@@ -2,7 +2,9 @@ import { BlurView, BlurViewProperties } from '@react-native-community/blur';
import { THEME_COLOR } from 'CONSTANTS'; import { THEME_COLOR } from 'CONSTANTS';
import React, { PropsWithChildren } from 'react'; import React, { PropsWithChildren } from 'react';
import { useContext } from 'react'; import { useContext } from 'react';
import { ColorSchemeName, StyleSheet, useColorScheme } from 'react-native'; import { ColorSchemeName, Platform, StyleSheet, useColorScheme } from 'react-native';
const majorPlatformVersion = typeof Platform.Version === 'string' ? parseInt(Platform.Version, 10) : Platform.Version;
/** /**
* Function for generating both the dark and light stylesheets, so that they * Function for generating both the dark and light stylesheets, so that they
@@ -92,6 +94,11 @@ export function ColoredBlurView(props: PropsWithChildren<BlurViewProperties>) {
const scheme = useColorScheme(); const scheme = useColorScheme();
return ( return (
<BlurView {...props} blurType={scheme === 'dark' ? 'extraDark' : 'xlight'} /> <BlurView
{...props}
blurType={Platform.OS === 'ios' && majorPlatformVersion >= 13
? 'material'
: scheme === 'dark' ? 'extraDark' : 'xlight'
} />
); );
} }

View File

@@ -0,0 +1,85 @@
import React, { useMemo } from 'react';
import { Dimensions, ViewProps } from 'react-native';
import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia';
import useDefaultStyles from './Colors';
import styled from 'styled-components/native';
const Screen = Dimensions.get('screen');
const Container = styled.View<{ size: number }>`
width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
position: relative;
`;
const BlurContainer = styled(Canvas)<{ size: number, offset: number }>`
position: absolute;
left: -${(props) => props.offset}px;
top: -${(props) => props.offset}px;
width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
z-index: 2;
`;
interface Props {
blurRadius?: number;
opacity?: number;
margin?: number;
radius?: number;
style?: ViewProps['style'];
src: string;
}
/**
* This will take a cover image, and apply shadows and a really nice background
* blur to the image in question. Additionally, we'll add some margin and radius
* to the corners.
*/
function CoverImage({
blurRadius = 256,
opacity = 0.85,
margin = 112,
radius = 12,
style,
src,
}: Props) {
const defaultStyles = useDefaultStyles();
const image = useImage(src || '');
const { canvasSize, imageSize } = useMemo(() => {
const imageSize = Screen.width - margin;
const canvasSize = imageSize + blurRadius * 2;
return { imageSize, canvasSize };
}, [blurRadius, margin]);
return (
<Container size={imageSize} style={style}>
<BlurContainer size={canvasSize} offset={blurRadius}>
<RoundedRect x={blurRadius} y={blurRadius} width={imageSize} height={imageSize} color={defaultStyles.imageBackground.backgroundColor} r={12}>
<Shadow dx={0} dy={1} blur={2} color="#0000000d" />
<Shadow dx={0} dy={2} blur={4} color="#0000000d" />
<Shadow dx={0} dy={4} blur={8} color="#0000000d" />
<Shadow dx={0} dy={8} blur={16} color="#0000000d" />
<Shadow dx={0} dy={16} blur={32} color="#0000000d" />
</RoundedRect>
{image ? (
<>
<SkiaImage image={image} width={imageSize} height={imageSize} opacity={opacity}>
<Offset x={blurRadius} y={blurRadius} />
<Blur blur={blurRadius / 2} />
</SkiaImage>
<Mask mask={<RoundedRect width={imageSize} height={imageSize} x={blurRadius} y={blurRadius} r={radius} />}>
{image ? (
<SkiaImage image={image} width={imageSize} height={imageSize}>
<Offset x={blurRadius} y={blurRadius} />
</SkiaImage>
) : null}
</Mask>
</>
) : null}
</BlurContainer>
</Container>
);
}
export default CoverImage;

View File

@@ -1,26 +0,0 @@
import {GestureHandlerRefContext} from '@react-navigation/stack';
import React, {PropsWithChildren, useCallback, useState} from 'react';
import {ScrollViewProps} from 'react-native';
import {ScrollView} from 'react-native-gesture-handler';
export const DismissableScrollView = (
props: PropsWithChildren<ScrollViewProps>,
) => {
const [scrolledTop, setScrolledTop] = useState(true);
const onScroll = useCallback(({nativeEvent}) => {
console.log(nativeEvent.contentOffset);
setScrolledTop(nativeEvent.contentOffset.y <= 0);
}, []);
return (
<GestureHandlerRefContext.Consumer>
{(ref) => (
<ScrollView
waitFor={scrolledTop ? ref : undefined}
onScroll={onScroll}
scrollEventThrottle={16}
{...props}
/>
)}
</GestureHandlerRefContext.Consumer>
);
};

View File

@@ -20,7 +20,8 @@ function MusicStack() {
<> <>
<Stack.Navigator initialRouteName="RecentAlbums" screenOptions={{ <Stack.Navigator initialRouteName="RecentAlbums" screenOptions={{
headerTintColor: THEME_COLOR, headerTintColor: THEME_COLOR,
headerTitleStyle: defaultStyles.stackHeader headerTitleStyle: defaultStyles.stackHeader,
cardStyle: defaultStyles.view,
}}> }}>
<Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: t('recent-albums') }} /> <Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: t('recent-albums') }} />
<Stack.Screen name="Albums" component={Albums} options={{ headerTitle: t('albums') }} /> <Stack.Screen name="Albums" component={Albums} options={{ headerTitle: t('albums') }} />

View File

@@ -11,7 +11,7 @@ import { THEME_COLOR } from 'CONSTANTS';
import { Shadow } from 'react-native-shadow-2'; import { Shadow } from 'react-native-shadow-2';
import usePrevious from 'utility/usePrevious'; import usePrevious from 'utility/usePrevious';
import Text from 'components/Text'; import Text from 'components/Text';
import { ColoredBlurView } from 'components/Colors'; import useDefaultStyles, { ColoredBlurView } from 'components/Colors';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
const NOW_PLAYING_POPOVER_MARGIN = 6; const NOW_PLAYING_POPOVER_MARGIN = 6;
@@ -78,19 +78,20 @@ const ProgressTrack = styled(Animated.View)<ProgressTrackProps>`
function SelectActionButton() { function SelectActionButton() {
const state = usePlaybackState(); const state = usePlaybackState();
const defaultStyles = useDefaultStyles();
switch(state) { switch(state) {
case State.Playing: case State.Playing:
return ( return (
<Pressable onPress={TrackPlayer.pause}> <Pressable onPress={TrackPlayer.pause}>
<PauseIcon fill="black" height={18} width={18} /> <PauseIcon fill={defaultStyles.text.color} height={18} width={18} />
</Pressable> </Pressable>
); );
case State.Stopped: case State.Stopped:
case State.Paused: case State.Paused:
return ( return (
<Pressable onPress={TrackPlayer.play}> <Pressable onPress={TrackPlayer.play}>
<PlayIcon fill="black" height={18} width={18} /> <PlayIcon fill={defaultStyles.text.color} height={18} width={18} />
</Pressable> </Pressable>
); );
// @ts-expect-error For some reason buffering isn't stated right in the types // @ts-expect-error For some reason buffering isn't stated right in the types

View File

@@ -1,9 +1,8 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { ScrollView, Dimensions, RefreshControl, StyleSheet, View, Image } from 'react-native'; import { ScrollView, RefreshControl, StyleSheet, View } from 'react-native';
import { useGetImage } from 'utility/JellyfinApi'; import { useGetImage } from 'utility/JellyfinApi';
import styled, { css } from 'styled-components/native'; import styled, { css } from 'styled-components/native';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import FastImage from 'react-native-fast-image';
import { useTypedSelector } from 'store'; import { useTypedSelector } from 'store';
import { THEME_COLOR } from 'CONSTANTS'; import { THEME_COLOR } from 'CONSTANTS';
import TouchableHandler from 'components/TouchableHandler'; import TouchableHandler from 'components/TouchableHandler';
@@ -24,9 +23,7 @@ import { queueTrackForDownload, removeDownloadedTrack } from 'store/downloads/ac
import { selectDownloadedTracks } from 'store/downloads/selectors'; import { selectDownloadedTracks } from 'store/downloads/selectors';
import { Header, SubHeader } from 'components/Typography'; import { Header, SubHeader } from 'components/Typography';
import Text from 'components/Text'; import Text from 'components/Text';
import { Shadow } from 'react-native-shadow-2'; import CoverImage from 'components/CoverImage';
const Screen = Dimensions.get('screen');
const styles = StyleSheet.create({ const styles = StyleSheet.create({
index: { index: {
@@ -39,12 +36,6 @@ const styles = StyleSheet.create({
}, },
}); });
const AlbumImage = styled(FastImage)`
border-radius: 12px;
height: ${Screen.width - 112}px;
width: ${Screen.width - 112}px;
`;
const AlbumImageContainer = styled.View` const AlbumImageContainer = styled.View`
margin: 0 12px 24px 12px; margin: 0 12px 24px 12px;
flex: 1; flex: 1;
@@ -122,17 +113,14 @@ const TrackListView: React.FC<TrackListViewProps> = ({
return ( return (
<ScrollView <ScrollView
style={defaultStyles.view} style={defaultStyles.view}
contentContainerStyle={{ padding: 32, paddingTop: 32, paddingBottom: 64 }} contentContainerStyle={{ padding: 24, paddingTop: 32, paddingBottom: 64 }}
refreshControl={ refreshControl={
<RefreshControl refreshing={isLoading} onRefresh={refresh} /> <RefreshControl refreshing={isLoading} onRefresh={refresh} />
} }
> >
<AlbumImageContainer> <AlbumImageContainer>
<Shadow radius={12} distance={48} startColor="#00000017"> <CoverImage src={getImage(entityId)} />
<AlbumImage source={{ uri: getImage(entityId) }} style={defaultStyles.imageBackground} />
</Shadow>
</AlbumImageContainer> </AlbumImageContainer>
<Image source={{ uri: getImage(entityId) }} blurRadius={100} style={{ height: 120, width: 120 }} />
<Header>{title}</Header> <Header>{title}</Header>
<SubHeader>{artist}</SubHeader> <SubHeader>{artist}</SubHeader>
<WrappableButtonRow> <WrappableButtonRow>
@@ -157,12 +145,20 @@ const TrackListView: React.FC<TrackListViewProps> = ({
{ opacity: 0.25 }, { opacity: 0.25 },
currentTrack?.backendId === trackId && styles.activeText currentTrack?.backendId === trackId && styles.activeText
]} ]}
numberOfLines={1}
> >
{listNumberingStyle === 'index' {listNumberingStyle === 'index'
? i + 1 ? i + 1
: tracks[trackId]?.IndexNumber} : tracks[trackId]?.IndexNumber}
</Text> </Text>
<Text style={currentTrack?.backendId === trackId && styles.activeText}> <Text
style={{
...currentTrack?.backendId === trackId && styles.activeText,
flexShrink: 1,
marginRight: 4,
}}
numberOfLines={1}
>
{tracks[trackId]?.Name} {tracks[trackId]?.Name}
</Text> </Text>
<View style={{ marginLeft: 'auto', flexDirection: 'row' }}> <View style={{ marginLeft: 'auto', flexDirection: 'row' }}>
@@ -171,6 +167,7 @@ const TrackListView: React.FC<TrackListViewProps> = ({
{ marginRight: 12, opacity: 0.25 }, { marginRight: 12, opacity: 0.25 },
currentTrack?.backendId === trackId && styles.activeText currentTrack?.backendId === trackId && styles.activeText
]} ]}
numberOfLines={1}
> >
{Math.round(tracks[trackId]?.RunTimeTicks / 10000000 / 60)} {Math.round(tracks[trackId]?.RunTimeTicks / 10000000 / 60)}
:{Math.round(tracks[trackId]?.RunTimeTicks / 10000000 % 60).toString().padStart(2, '0')} :{Math.round(tracks[trackId]?.RunTimeTicks / 10000000 % 60).toString().padStart(2, '0')}

View File

@@ -1,51 +1,25 @@
import React from 'react'; import React from 'react';
import { Dimensions, View, StyleSheet } from 'react-native'; import { View } from 'react-native';
import useCurrentTrack from 'utility/useCurrentTrack'; import useCurrentTrack from 'utility/useCurrentTrack';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import FastImage from 'react-native-fast-image'; import CoverImage from 'components/CoverImage';
import useDefaultStyles from 'components/Colors'; import { Header, SubHeader } from 'components/Typography';
import Text from 'components/Text';
const Screen = Dimensions.get('screen'); const Artwork = styled(CoverImage)`
margin: 0 auto 25px auto;
const Artwork = styled(FastImage)`
border-radius: 10px;
width: ${Screen.width * 0.8}px;
height: ${Screen.width * 0.8}px;
margin: 25px auto;
`; `;
const styles = StyleSheet.create({
artist: {
fontWeight: 'bold',
fontSize: 24,
marginBottom: 12,
},
title: {
fontSize: 18,
marginBottom: 12,
textAlign: 'center',
paddingLeft: 20,
paddingRight: 20,
}
});
export default function NowPlaying() { export default function NowPlaying() {
const { track } = useCurrentTrack(); const { track } = useCurrentTrack();
const defaultStyles = useDefaultStyles();
return ( return (
<View style={{ alignItems: 'center' }}> <View>
<Artwork <Artwork
style={defaultStyles.imageBackground} src={track?.artwork as string}
source={{ margin={80}
uri: track?.artwork as string | undefined,
priority: FastImage.priority.high,
}}
/> />
<Text style={styles.artist}>{track?.artist}</Text> <Header>{track?.title}</Header>
<Text style={styles.title}>{track?.title}</Text> <SubHeader>{track?.artist}{track?.album && `${track.album}`}</SubHeader>
</View> </View>
); );
} }

View File

@@ -6,12 +6,11 @@ import NowPlaying from './components/NowPlaying';
import Queue from './components/Queue'; import Queue from './components/Queue';
import useDefaultStyles from 'components/Colors'; import useDefaultStyles from 'components/Colors';
import ConnectionNotice from './components/ConnectionNotice'; import ConnectionNotice from './components/ConnectionNotice';
import { DismissableScrollView } from 'components/DismissableScrollView';
import { ScrollView } from 'react-native-gesture-handler'; import { ScrollView } from 'react-native-gesture-handler';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
inner: { inner: {
padding: 25, padding: 40,
} }
}); });