This commit is contained in:
2026-03-29 09:21:01 -04:00
parent 821e71b387
commit a7d4f4e4d3
6 changed files with 500 additions and 205 deletions

570
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"name": "rssuper", "name": "rssuper",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@react-native-async-storage/async-storage": "^3.0.2",
"@react-navigation/bottom-tabs": "^7.15.5", "@react-navigation/bottom-tabs": "^7.15.5",
"@react-navigation/elements": "^2.9.10", "@react-navigation/elements": "^2.9.10",
"@react-navigation/native": "^7.1.33", "@react-navigation/native": "^7.1.33",
@@ -20,21 +21,22 @@
"expo-glass-effect": "55.0.9-canary-20260328-2049187", "expo-glass-effect": "55.0.9-canary-20260328-2049187",
"expo-image": "55.0.7-canary-20260328-2049187", "expo-image": "55.0.7-canary-20260328-2049187",
"expo-linking": "55.0.10-canary-20260328-2049187", "expo-linking": "55.0.10-canary-20260328-2049187",
"expo-localization": "^55.0.10-canary-20260328-bdc6273", "expo-localization": "55.0.10-canary-20260328-2049187",
"expo-notifications": "^55.0.15-canary-20260328-bdc6273", "expo-notifications": "55.0.15-canary-20260328-2049187",
"expo-router": "55.0.9-canary-20260328-2049187", "expo-router": "55.0.9-canary-20260328-2049187",
"expo-splash-screen": "55.0.14-canary-20260328-2049187", "expo-splash-screen": "55.0.14-canary-20260328-2049187",
"expo-sqlite": "^55.0.12-canary-20260328-bdc6273", "expo-sqlite": "55.0.12-canary-20260328-2049187",
"expo-status-bar": "55.0.5-canary-20260328-2049187", "expo-status-bar": "55.0.5-canary-20260328-2049187",
"expo-symbols": "55.0.6-canary-20260328-2049187", "expo-symbols": "55.0.6-canary-20260328-2049187",
"expo-system-ui": "55.0.12-canary-20260328-2049187", "expo-system-ui": "55.0.12-canary-20260328-2049187",
"expo-task-manager": "^55.0.11-canary-20260328-bdc6273", "expo-task-manager": "55.0.11-canary-20260328-2049187",
"expo-web-browser": "55.0.11-canary-20260328-2049187", "expo-web-browser": "55.0.11-canary-20260328-2049187",
"react": "19.2.0", "react": "19.2.0",
"react-dom": "19.2.0", "react-dom": "19.2.0",
"react-native": "0.83.4", "react-native": "0.83.4",
"react-native-gesture-handler": "~2.30.0", "react-native-gesture-handler": "~2.30.0",
"react-native-reanimated": "4.2.1", "react-native-reanimated": "4.2.1",
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "~5.6.2", "react-native-safe-area-context": "~5.6.2",
"react-native-screens": "~4.23.0", "react-native-screens": "~4.23.0",
"react-native-web": "~0.21.0", "react-native-web": "~0.21.0",
@@ -2149,6 +2151,57 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@jsamr/counter-style": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@jsamr/counter-style/-/counter-style-2.0.2.tgz",
"integrity": "sha512-2mXudGVtSzVxWEA7B9jZLKjoXUeUFYDDtFrQoC0IFX9/Dszz4t1vZOmafi3JSw/FxD+udMQ+4TAFR8Qs0J3URQ==",
"license": "MIT"
},
"node_modules/@jsamr/react-native-li": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@jsamr/react-native-li/-/react-native-li-2.3.1.tgz",
"integrity": "sha512-Qbo4NEj48SQ4k8FZJHFE2fgZDKTWaUGmVxcIQh3msg5JezLdTMMHuRRDYctfdHI6L0FZGObmEv3haWbIvmol8w==",
"license": "MIT",
"peerDependencies": {
"@jsamr/counter-style": "^1.0.0 || ^2.0.0",
"react": "*",
"react-native": "*"
}
},
"node_modules/@native-html/css-processor": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@native-html/css-processor/-/css-processor-1.11.0.tgz",
"integrity": "sha512-NnhBEbJX5M2gBGltPKOetiLlKhNf3OHdRafc8//e2ZQxXN8JaSW/Hy8cm94pnIckQxwaMKxrtaNT3x4ZcffoNQ==",
"license": "MIT",
"dependencies": {
"css-to-react-native": "^3.0.0",
"csstype": "^3.0.8"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-native": "*"
}
},
"node_modules/@native-html/transient-render-engine": {
"version": "11.2.3",
"resolved": "https://registry.npmjs.org/@native-html/transient-render-engine/-/transient-render-engine-11.2.3.tgz",
"integrity": "sha512-zXwgA3gPUEmFs3I3syfnvDvS6WiUHXEE6jY09OBzK+trq7wkweOSFWIoyXiGkbXrozGYG0KY90YgPyr8Tg8Uyg==",
"license": "MIT",
"dependencies": {
"@native-html/css-processor": "1.11.0",
"@types/ramda": "^0.27.44",
"csstype": "^3.0.9",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.2",
"domutils": "^2.8.0",
"htmlparser2": "^7.1.2",
"ramda": "^0.27.2"
},
"peerDependencies": {
"@types/react-native": "*",
"react-native": "^*"
}
},
"node_modules/@radix-ui/primitive": { "node_modules/@radix-ui/primitive": {
"version": "1.1.3", "version": "1.1.3",
"license": "MIT" "license": "MIT"
@@ -2588,6 +2641,19 @@
} }
} }
}, },
"node_modules/@react-native-async-storage/async-storage": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-3.0.2.tgz",
"integrity": "sha512-XP0zDIl+1XoeuQ7f878qXKdl77zLwzLALPpxvNRc7ZtDh9ew36WSvOdQOhFkexMySapFAWxEbZxS8K8J2DU4eg==",
"license": "MIT",
"dependencies": {
"idb": "8.0.3"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/@react-native/assets-registry": { "node_modules/@react-native/assets-registry": {
"version": "0.83.4", "version": "0.83.4",
"license": "MIT", "license": "MIT",
@@ -3015,18 +3081,57 @@
"undici-types": "~7.18.0" "undici-types": "~7.18.0"
} }
}, },
"node_modules/@types/ramda": {
"version": "0.27.66",
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.66.tgz",
"integrity": "sha512-i2YW+E2U6NfMt3dp0RxNcejox+bxJUNDjB7BpYuRuoHIzv5juPHkJkNgcUOu+YSQEmaWu8cnAo/8r63C0NnuVA==",
"license": "MIT",
"dependencies": {
"ts-toolbelt": "^6.15.1"
}
},
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.2.14", "version": "19.2.14",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
} }
}, },
"node_modules/@types/react-native": {
"version": "0.72.8",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.72.8.tgz",
"integrity": "sha512-St6xA7+EoHN5mEYfdWnfYt0e8u6k2FR0P9s2arYgakQGFgU1f9FlPrIEcj0X24pLCF5c5i3WVuLCUdiCYHmOoA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@react-native/virtualized-lists": "^0.72.4",
"@types/react": "*"
}
},
"node_modules/@types/react-native/node_modules/@react-native/virtualized-lists": {
"version": "0.72.8",
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz",
"integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==",
"license": "MIT",
"peer": true,
"dependencies": {
"invariant": "^2.2.4",
"nullthrows": "^1.1.1"
},
"peerDependencies": {
"react-native": "*"
}
},
"node_modules/@types/stack-utils": { "node_modules/@types/stack-utils": {
"version": "2.0.3", "version": "2.0.3",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/urijs": {
"version": "1.19.26",
"resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.26.tgz",
"integrity": "sha512-wkXrVzX5yoqLnndOwFsieJA7oKM8cNkOKJtf/3vVGSUFkWDKZvFHpIl9Pvqb/T9UsawBBFMTTD8xu7sK5MWuvg==",
"license": "MIT"
},
"node_modules/@types/xml2js": { "node_modules/@types/xml2js": {
"version": "0.4.14", "version": "0.4.14",
"resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz", "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz",
@@ -3602,6 +3707,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001781", "version": "1.0.30001781",
"funding": [ "funding": [
@@ -3647,6 +3761,26 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1" "url": "https://github.com/chalk/ansi-styles?sponsor=1"
} }
}, },
"node_modules/character-entities-html4": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz",
"integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/character-entities-legacy": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
"integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/chrome-launcher": { "node_modules/chrome-launcher": {
"version": "0.15.2", "version": "0.15.2",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -3899,6 +4033,15 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
"license": "ISC",
"engines": {
"node": ">=4"
}
},
"node_modules/css-in-js-utils": { "node_modules/css-in-js-utils": {
"version": "3.1.0", "version": "3.1.0",
"license": "MIT", "license": "MIT",
@@ -3906,9 +4049,19 @@
"hyphenate-style-name": "^1.0.3" "hyphenate-style-name": "^1.0.3"
} }
}, },
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"license": "MIT",
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.2.3", "version": "3.2.3",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/debug": { "node_modules/debug": {
@@ -3996,6 +4149,61 @@
"version": "1.1.4", "version": "1.1.4",
"license": "MIT" "license": "MIT"
}, },
"node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
"integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
"license": "MIT",
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"license": "BSD-2-Clause"
},
"node_modules/domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.2.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dunder-proto": { "node_modules/dunder-proto": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -4029,6 +4237,15 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"license": "BSD-2-Clause",
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/error-stack-parser": { "node_modules/error-stack-parser": {
"version": "2.1.4", "version": "2.1.4",
"license": "MIT", "license": "MIT",
@@ -4180,12 +4397,12 @@
} }
}, },
"node_modules/expo-application": { "node_modules/expo-application": {
"version": "55.0.11-canary-20260328-bdc6273", "version": "55.0.11-canary-20260328-2049187",
"resolved": "https://registry.npmjs.org/expo-application/-/expo-application-55.0.11-canary-20260328-bdc6273.tgz", "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-55.0.11-canary-20260328-2049187.tgz",
"integrity": "sha512-tXk3YZaTJ2W3vbawnEtOy5o/SVpaUqygqZwbiOearcnXFGtJOS/U3J5KRhH9FZVomeW19h+aplcy4mPPMbc65g==", "integrity": "sha512-XrWghJefOb3fTdxK0B3RKuz9l31nZn2SIPqn2qhYx4kOPXa/CytaUvH5wG5gHJ2ZGtonk4JPmw+a69OiDj7MfQ==",
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"expo": "55.0.10-canary-20260328-bdc6273" "expo": "55.0.10-canary-20260328-2049187"
} }
}, },
"node_modules/expo-asset": { "node_modules/expo-asset": {
@@ -4291,15 +4508,15 @@
} }
}, },
"node_modules/expo-localization": { "node_modules/expo-localization": {
"version": "55.0.10-canary-20260328-bdc6273", "version": "55.0.10-canary-20260328-2049187",
"resolved": "https://registry.npmjs.org/expo-localization/-/expo-localization-55.0.10-canary-20260328-bdc6273.tgz", "resolved": "https://registry.npmjs.org/expo-localization/-/expo-localization-55.0.10-canary-20260328-2049187.tgz",
"integrity": "sha512-BCawgtUzcRIoT8DA8k4O8CYV3NuunPHe3TnYTt9ETIfMIxeKXAF2f2LlRrbhIqsbwjPWnMcZwpse2q/HSXxXcQ==", "integrity": "sha512-4ZxHWAssJzQzkzcEGNzSxB/BpoN5IWE/FvMbJExByYqh2/x7EVJqamT8lNvFmfTdwrVCwGX6AhzMB6MGmf38Yg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"rtl-detect": "^1.0.2" "rtl-detect": "^1.0.2"
}, },
"peerDependencies": { "peerDependencies": {
"expo": "55.0.10-canary-20260328-bdc6273", "expo": "55.0.10-canary-20260328-2049187",
"react": "*" "react": "*"
} }
}, },
@@ -4335,191 +4552,23 @@
} }
}, },
"node_modules/expo-notifications": { "node_modules/expo-notifications": {
"version": "55.0.15-canary-20260328-bdc6273", "version": "55.0.15-canary-20260328-2049187",
"resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-55.0.15-canary-20260328-bdc6273.tgz", "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-55.0.15-canary-20260328-2049187.tgz",
"integrity": "sha512-odWh8KPkk9P6aZv/NR83poePVFfcz4jW70sgyaFv0EpDZkSN3gJKFCmgfaMldCKrn52Q9q4xrXfFzZRJdDe4xg==", "integrity": "sha512-Z6eQ5HPs2q71O+tt+dmINigAT+WxB2pCp/EAmvhtIPVYhopSuxJDmPGd+sMjeUe/npiwJqbr2agDLPcH8NxsHA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@expo/image-utils": "0.8.13-canary-20260328-bdc6273", "@expo/image-utils": "0.8.13-canary-20260328-2049187",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"badgin": "^1.1.5", "badgin": "^1.1.5",
"expo-application": "55.0.11-canary-20260328-bdc6273", "expo-application": "55.0.11-canary-20260328-2049187",
"expo-constants": "55.0.10-canary-20260328-bdc6273" "expo-constants": "55.0.10-canary-20260328-2049187"
}, },
"peerDependencies": { "peerDependencies": {
"expo": "55.0.10-canary-20260328-bdc6273", "expo": "55.0.10-canary-20260328-2049187",
"react": "*", "react": "*",
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-notifications/node_modules/@expo/config": {
"version": "55.0.12-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/config/-/config-55.0.12-canary-20260328-bdc6273.tgz",
"integrity": "sha512-79kzhpY5VAkLem/BPZasapvtZShK1PAWQYg/78edXRdLAL0k7x7Gy9ubgNgkT6KzbC9xvN6rwQ9wKx95Wd+Urg==",
"license": "MIT",
"dependencies": {
"@expo/config-plugins": "55.0.8-canary-20260328-bdc6273",
"@expo/config-types": "55.0.6-canary-20260328-bdc6273",
"@expo/json-file": "10.0.13-canary-20260328-bdc6273",
"@expo/require-utils": "55.0.4-canary-20260328-bdc6273",
"deepmerge": "^4.3.1",
"getenv": "^2.0.0",
"glob": "^13.0.0",
"resolve-from": "^5.0.0",
"resolve-workspace-root": "^2.0.0",
"semver": "^7.6.0",
"slugify": "^1.3.4"
}
},
"node_modules/expo-notifications/node_modules/@expo/config-plugins": {
"version": "55.0.8-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-55.0.8-canary-20260328-bdc6273.tgz",
"integrity": "sha512-djT9urGkLkL9kJcO1+frUkFgZk63J4akISvXtUmoNGe+k7zGSQmoQRy/tWmhMwwNMGm2BrmVyoLX+243gmnHwA==",
"license": "MIT",
"dependencies": {
"@expo/config-types": "55.0.6-canary-20260328-bdc6273",
"@expo/json-file": "10.0.13-canary-20260328-bdc6273",
"@expo/plist": "0.5.3-canary-20260328-bdc6273",
"@expo/sdk-runtime-versions": "^1.0.0",
"chalk": "^4.1.2",
"debug": "^4.3.5",
"getenv": "^2.0.0",
"glob": "^13.0.0",
"resolve-from": "^5.0.0",
"semver": "^7.5.4",
"slugify": "^1.6.6",
"xcode": "^3.0.1",
"xml2js": "0.6.0"
}
},
"node_modules/expo-notifications/node_modules/@expo/config-types": {
"version": "55.0.6-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-55.0.6-canary-20260328-bdc6273.tgz",
"integrity": "sha512-IUD5dTOZkTr+dxNmqJi09GzxxRMqTlIFCSWa5DIjioyxCBkRQ1fi3jkmDcS4owHjZpNA2XRKG8QNum+OKwXw/g==",
"license": "MIT"
},
"node_modules/expo-notifications/node_modules/@expo/env": {
"version": "2.1.2-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/env/-/env-2.1.2-canary-20260328-bdc6273.tgz",
"integrity": "sha512-iopcE9NDqKTaLEuiAEEYS0zohyXJamyX7csFTTI93tcnXEr/eh3ZnvQjkEKhPNAVcB9MmcAiowCHQCfiDcV0Nw==",
"license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
"debug": "^4.3.4",
"getenv": "^2.0.0"
},
"engines": {
"node": ">=20.12.0"
}
},
"node_modules/expo-notifications/node_modules/@expo/image-utils": {
"version": "0.8.13-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.13-canary-20260328-bdc6273.tgz",
"integrity": "sha512-1n6J1iVSM58n0mTw/czSHmHGXMUUau0PQc0aQqdQyzElrluNpdShJL5McFsr6usbhztz6Fg4dWMFWXuuON9R+Q==",
"license": "MIT",
"dependencies": {
"@expo/spawn-async": "^1.7.2",
"chalk": "^4.0.0",
"getenv": "^2.0.0",
"jimp-compact": "0.16.1",
"parse-png": "^2.1.0",
"resolve-from": "^5.0.0",
"semver": "^7.6.0"
}
},
"node_modules/expo-notifications/node_modules/@expo/json-file": {
"version": "10.0.13-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.13-canary-20260328-bdc6273.tgz",
"integrity": "sha512-bB+r3u2BIIl4tpc0bc2h9vc6hhwzf0w9vG1co3WHXCDLBfWx0Dvxc5xfUq4E5+Lz61oAO0Qq9dUM8f8qgra4TA==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.20.0",
"json5": "^2.2.3"
}
},
"node_modules/expo-notifications/node_modules/@expo/plist": {
"version": "0.5.3-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.5.3-canary-20260328-bdc6273.tgz",
"integrity": "sha512-Mibai5bnKjtaSuQtPS1CuTvIwN9Fi3Vw6+5ZNdoPQ1bwJSYLMDxIIBKBUaAPgJSB/EHYd1rErYabozWGhj1ebg==",
"license": "MIT",
"dependencies": {
"@xmldom/xmldom": "^0.8.8",
"base64-js": "^1.5.1",
"xmlbuilder": "^15.1.1"
}
},
"node_modules/expo-notifications/node_modules/@expo/require-utils": {
"version": "55.0.4-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-55.0.4-canary-20260328-bdc6273.tgz",
"integrity": "sha512-PhOAVBPFCfgMYKnLWogOLprNEr/S78TRUo1gvK9rPF/PYhLXJBpmrQB8Te7PmbaqD2AoB6rYopy858lrVHHjOw==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.20.0",
"@babel/core": "^7.25.2",
"@babel/plugin-transform-modules-commonjs": "^7.24.8"
},
"peerDependencies": {
"typescript": "^5.0.0 || ^5.0.0-0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/expo-notifications/node_modules/expo-constants": {
"version": "55.0.10-canary-20260328-bdc6273",
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-55.0.10-canary-20260328-bdc6273.tgz",
"integrity": "sha512-K6Eu2OFjIlDmHsupLdaS/qxIDk+kzPVmFC0kmsME5NDZpPiH7eyS47q3wiMa9ZRxOtk4bLbSYMfMXQ1pcnhh/w==",
"license": "MIT",
"dependencies": {
"@expo/config": "55.0.12-canary-20260328-bdc6273",
"@expo/env": "2.1.2-canary-20260328-bdc6273"
},
"peerDependencies": {
"expo": "55.0.10-canary-20260328-bdc6273",
"react-native": "*"
}
},
"node_modules/expo-notifications/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/expo-notifications/node_modules/xml2js": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz",
"integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==",
"license": "MIT",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/expo-notifications/node_modules/xml2js/node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"license": "MIT",
"engines": {
"node": ">=4.0"
}
},
"node_modules/expo-router": { "node_modules/expo-router": {
"version": "55.0.9-canary-20260328-2049187", "version": "55.0.9-canary-20260328-2049187",
"license": "MIT", "license": "MIT",
@@ -4611,15 +4660,15 @@
} }
}, },
"node_modules/expo-sqlite": { "node_modules/expo-sqlite": {
"version": "55.0.12-canary-20260328-bdc6273", "version": "55.0.12-canary-20260328-2049187",
"resolved": "https://registry.npmjs.org/expo-sqlite/-/expo-sqlite-55.0.12-canary-20260328-bdc6273.tgz", "resolved": "https://registry.npmjs.org/expo-sqlite/-/expo-sqlite-55.0.12-canary-20260328-2049187.tgz",
"integrity": "sha512-iDPDnn4IJhi/ajlPKlb7qf4IwAVoyVDNSyYyacDz3YKfc4xajsW78AosDeJo+RxdAhFzPen3Bd0WinROmuwb+w==", "integrity": "sha512-pzcd8T1A1a/SKDkFrUXQP/VQXdmsSRpE1XJwFps6Jt3+7DT1kQlFuQEp1xx7hqko/Qhjo7i1X0s67b1pt0lYWg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"await-lock": "^2.2.2" "await-lock": "^2.2.2"
}, },
"peerDependencies": { "peerDependencies": {
"expo": "55.0.10-canary-20260328-bdc6273", "expo": "55.0.10-canary-20260328-2049187",
"react": "*", "react": "*",
"react-native": "*" "react-native": "*"
} }
@@ -4668,15 +4717,15 @@
} }
}, },
"node_modules/expo-task-manager": { "node_modules/expo-task-manager": {
"version": "55.0.11-canary-20260328-bdc6273", "version": "55.0.11-canary-20260328-2049187",
"resolved": "https://registry.npmjs.org/expo-task-manager/-/expo-task-manager-55.0.11-canary-20260328-bdc6273.tgz", "resolved": "https://registry.npmjs.org/expo-task-manager/-/expo-task-manager-55.0.11-canary-20260328-2049187.tgz",
"integrity": "sha512-b+iQORUVW5fHk8zbI5l1I+bD+h4iJmFNI1IZN2ii+IR3wF0h8P4UcXkXHbISHHAEYoEFVtSqaUEKE0LiEFHrrA==", "integrity": "sha512-eneHR2t2WLWeRKfFuY2UDREh9OSryVDGWXy2V+IBlAKdOEQBQ1FlJESbLrYCEkhu6qiLUYMd61e0tgn3fbRhWQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"unimodules-app-loader": "55.0.3-canary-20260328-bdc6273" "unimodules-app-loader": "55.0.3-canary-20260328-2049187"
}, },
"peerDependencies": { "peerDependencies": {
"expo": "55.0.10-canary-20260328-bdc6273", "expo": "55.0.10-canary-20260328-2049187",
"react-native": "*" "react-native": "*"
} }
}, },
@@ -5122,6 +5171,37 @@
"version": "10.4.3", "version": "10.4.3",
"license": "ISC" "license": "ISC"
}, },
"node_modules/htmlparser2": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
"integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"license": "MIT",
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.2",
"domutils": "^2.8.0",
"entities": "^3.0.1"
}
},
"node_modules/htmlparser2/node_modules/entities": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/http-errors": { "node_modules/http-errors": {
"version": "2.0.1", "version": "2.0.1",
"license": "MIT", "license": "MIT",
@@ -5155,6 +5235,12 @@
"version": "1.1.0", "version": "1.1.0",
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/idb": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz",
"integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==",
"license": "ISC"
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "5.3.2", "version": "5.3.2",
"license": "MIT", "license": "MIT",
@@ -6515,6 +6601,23 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT"
},
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
@@ -6547,6 +6650,12 @@
"inherits": "~2.0.3" "inherits": "~2.0.3"
} }
}, },
"node_modules/ramda": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
"integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
"license": "MIT"
},
"node_modules/range-parser": { "node_modules/range-parser": {
"version": "1.2.1", "version": "1.2.1",
"license": "MIT", "license": "MIT",
@@ -6705,6 +6814,27 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/react-native-render-html": {
"version": "6.3.4",
"resolved": "https://registry.npmjs.org/react-native-render-html/-/react-native-render-html-6.3.4.tgz",
"integrity": "sha512-H2jSMzZjidE+Wo3qCWPUMU1nm98Vs2SGCvQCz/i6xf0P3Y9uVtG/b0sDbG/cYFir2mSYBYCIlS1Dv0WC1LjYig==",
"license": "BSD-2-Clause",
"dependencies": {
"@jsamr/counter-style": "^2.0.1",
"@jsamr/react-native-li": "^2.3.0",
"@native-html/transient-render-engine": "11.2.3",
"@types/ramda": "^0.27.40",
"@types/urijs": "^1.19.15",
"prop-types": "^15.5.7",
"ramda": "^0.27.2",
"stringify-entities": "^3.1.0",
"urijs": "^1.19.6"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-safe-area-context": { "node_modules/react-native-safe-area-context": {
"version": "5.6.2", "version": "5.6.2",
"license": "MIT", "license": "MIT",
@@ -7270,6 +7400,21 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/stringify-entities": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz",
"integrity": "sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg==",
"license": "MIT",
"dependencies": {
"character-entities-html4": "^1.0.0",
"character-entities-legacy": "^1.0.0",
"xtend": "^4.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/strip-ansi": { "node_modules/strip-ansi": {
"version": "5.2.0", "version": "5.2.0",
"license": "MIT", "license": "MIT",
@@ -7427,6 +7572,12 @@
"version": "0.0.3", "version": "0.0.3",
"license": "MIT" "license": "MIT"
}, },
"node_modules/ts-toolbelt": {
"version": "6.15.5",
"resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz",
"integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==",
"license": "Apache-2.0"
},
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.8.1", "version": "2.8.1",
"license": "0BSD" "license": "0BSD"
@@ -7447,7 +7598,7 @@
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.9.3", "version": "5.9.3",
"dev": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@@ -7518,9 +7669,9 @@
} }
}, },
"node_modules/unimodules-app-loader": { "node_modules/unimodules-app-loader": {
"version": "55.0.3-canary-20260328-bdc6273", "version": "55.0.3-canary-20260328-2049187",
"resolved": "https://registry.npmjs.org/unimodules-app-loader/-/unimodules-app-loader-55.0.3-canary-20260328-bdc6273.tgz", "resolved": "https://registry.npmjs.org/unimodules-app-loader/-/unimodules-app-loader-55.0.3-canary-20260328-2049187.tgz",
"integrity": "sha512-L95O/qGf1Z5AC+Hc4scmzTdXkZ7SSwyZxJeEuyDL79tfUxTtn88gbIvzxSV0ml4oAQMEFCZmulVDLXZBdUQrNw==", "integrity": "sha512-kqGCLCS35FFs4ue6BCIMuCVLO/KTco9WOHq/ghEVsR4NgGnhb9D3td2/D6KAFRY3c8qQ83x8mBAsHTwN7EUnNA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/unpipe": { "node_modules/unpipe": {
@@ -7558,6 +7709,12 @@
"browserslist": ">= 4.21.0" "browserslist": ">= 4.21.0"
} }
}, },
"node_modules/urijs": {
"version": "1.19.11",
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
"integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==",
"license": "MIT"
},
"node_modules/use-callback-ref": { "node_modules/use-callback-ref": {
"version": "1.3.3", "version": "1.3.3",
"license": "MIT", "license": "MIT",
@@ -7815,6 +7972,15 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"license": "ISC", "license": "ISC",

View File

@@ -11,6 +11,7 @@
"lint": "expo lint" "lint": "expo lint"
}, },
"dependencies": { "dependencies": {
"@react-native-async-storage/async-storage": "^3.0.2",
"@react-navigation/bottom-tabs": "^7.15.5", "@react-navigation/bottom-tabs": "^7.15.5",
"@react-navigation/elements": "^2.9.10", "@react-navigation/elements": "^2.9.10",
"@react-navigation/native": "^7.1.33", "@react-navigation/native": "^7.1.33",
@@ -38,6 +39,7 @@
"react-native": "0.83.4", "react-native": "0.83.4",
"react-native-gesture-handler": "~2.30.0", "react-native-gesture-handler": "~2.30.0",
"react-native-reanimated": "4.2.1", "react-native-reanimated": "4.2.1",
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "~5.6.2", "react-native-safe-area-context": "~5.6.2",
"react-native-screens": "~4.23.0", "react-native-screens": "~4.23.0",
"react-native-web": "~0.21.0", "react-native-web": "~0.21.0",

View File

@@ -13,6 +13,7 @@ import {
import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { SymbolView } from 'expo-symbols'; import { SymbolView } from 'expo-symbols';
import { useLocalSearchParams } from 'expo-router'; import { useLocalSearchParams } from 'expo-router';
import RenderHtml from 'react-native-render-html';
import { ThemedText } from '@/components/themed-text'; import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view'; import { ThemedView } from '@/components/themed-view';
@@ -81,9 +82,46 @@ export default function ArticleDetailScreen() {
}); });
}; };
const extractImagesFromHtml = (html: string): string[] => {
const imgRegex = /<img[^>]+src=["']([^"']+)["'][^>]*>/gi;
const images: string[] = [];
let match;
while ((match = imgRegex.exec(html)) !== null) {
if (match[1] && !images.includes(match[1])) {
images.push(match[1]);
}
}
return images;
};
const getGalleryImages = (): string[] => {
const images: string[] = [];
if (article?.content) {
images.push(...extractImagesFromHtml(article.content));
}
if (article?.description) {
images.push(...extractImagesFromHtml(article.description));
}
return [...new Set(images)];
};
const galleryImages = getGalleryImages();
const renderContent = (content?: string) => { const renderContent = (content?: string) => {
if (!content) return null; if (!content) return null;
const isHtml = /<[a-z][\s\S]*>/i.test(content);
if (isHtml) {
return (
<RenderHtml
contentWidth={350}
source={{ html: content }}
baseStyle={styles.content}
/>
);
}
return ( return (
<ThemedText style={styles.content}> <ThemedText style={styles.content}>
{content} {content}
@@ -169,6 +207,26 @@ export default function ArticleDetailScreen() {
</Pressable> </Pressable>
</ThemedView> </ThemedView>
{galleryImages.length > 0 && (
<ThemedView style={styles.gallery}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.galleryContent}
>
{galleryImages.map((imgUrl, index) => (
<Pressable key={index} onPress={() => Linking.openURL(imgUrl)}>
<Image
source={{ uri: imgUrl }}
style={styles.galleryImage}
resizeMode="cover"
/>
</Pressable>
))}
</ScrollView>
</ThemedView>
)}
{article.description && ( {article.description && (
<ThemedView style={styles.section}> <ThemedView style={styles.section}>
<ThemedText type="default" style={styles.description}> <ThemedText type="default" style={styles.description}>
@@ -244,6 +302,18 @@ const styles = StyleSheet.create({
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
}, },
gallery: {
paddingVertical: Spacing.two,
},
galleryContent: {
paddingHorizontal: Spacing.four,
gap: Spacing.two,
},
galleryImage: {
width: 200,
height: 150,
borderRadius: Spacing.two,
},
section: { section: {
padding: Spacing.four, padding: Spacing.four,
paddingTop: 0, paddingTop: 0,

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { StyleSheet, TouchableOpacity, Linking } from 'react-native'; import { StyleSheet, TouchableOpacity, Linking } from 'react-native';
import { useRouter } from 'expo-router';
import { FeedItem } from '@/types/feed'; import { FeedItem } from '@/types/feed';
import { ThemedText } from './themed-text'; import { ThemedText } from './themed-text';
import { ThemedView } from './themed-view'; import { ThemedView } from './themed-view';
@@ -18,10 +19,13 @@ interface FeedItemCardProps {
export function FeedItemCard({ item, onPress, onLongPress }: FeedItemCardProps) { export function FeedItemCard({ item, onPress, onLongPress }: FeedItemCardProps) {
const scheme = useColorScheme(); const scheme = useColorScheme();
const colors = Colors[scheme === 'unspecified' ? 'light' : scheme]; const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
const router = useRouter();
const handlePress = () => { const handlePress = () => {
if (onPress) { if (onPress) {
onPress(item); onPress(item);
} else if (item.id) {
router.push(`/article/${item.id}` as any);
} else if (item.link) { } else if (item.link) {
Linking.openURL(item.link); Linking.openURL(item.link);
} }
@@ -63,7 +67,7 @@ export function FeedItemCard({ item, onPress, onLongPress }: FeedItemCardProps)
return ''; return '';
}, [item.content, item.description]); }, [item.content, item.description]);
return ( const cardContent = (
<TouchableOpacity <TouchableOpacity
style={[styles.container, { backgroundColor: colors.background }]} style={[styles.container, { backgroundColor: colors.background }]}
onPress={handlePress} onPress={handlePress}
@@ -110,6 +114,58 @@ export function FeedItemCard({ item, onPress, onLongPress }: FeedItemCardProps)
</ThemedView> </ThemedView>
</TouchableOpacity> </TouchableOpacity>
); );
if (item.id) {
return (
<TouchableOpacity
style={[styles.container, { backgroundColor: colors.background }]}
onPress={handlePress}
onLongPress={handleLongPress}
activeOpacity={0.7}
>
<ThemedView style={styles.content}>
{item.subscriptionTitle && (
<ThemedText type="small" style={styles.feedTitle} numberOfLines={1}>
{item.subscriptionTitle}
</ThemedText>
)}
<ThemedText type="smallBold" style={styles.title} numberOfLines={2}>
{item.title}
</ThemedText>
{excerpt && (
<ThemedText type="small" style={styles.excerpt} numberOfLines={3}>
{excerpt}
</ThemedText>
)}
<ThemedView style={styles.metaRow}>
{item.author && (
<ThemedText type="small" style={styles.author} numberOfLines={1}>
{item.author}
</ThemedText>
)}
{item.published && (
<ThemedText type="small" style={styles.date}>
{formatDate(item.published)}
</ThemedText>
)}
</ThemedView>
{item.enclosure && item.enclosure.type.includes('audio') && (
<ThemedView style={styles.audioBadge}>
<ThemedText type="small" style={styles.audioBadgeText}>
🎧 Audio
</ThemedText>
</ThemedView>
)}
</ThemedView>
</TouchableOpacity>
);
}
return cardContent;
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({

View File

@@ -387,7 +387,7 @@ export default function SettingsScreen() {
<ThemedView style={styles.prefGroup}> <ThemedView style={styles.prefGroup}>
<ThemedText style={styles.prefTitle}>Timezone</ThemedText> <ThemedText style={styles.prefTitle}>Timezone</ThemedText>
<TextInput <TextInput
style={styles.input} style={[styles.input, { backgroundColor: theme.backgroundElement }]}
placeholder="e.g., UTC" placeholder="e.g., UTC"
value={accountSettings.timezone} value={accountSettings.timezone}
onChangeText={(text) => handleAccountSettingChange('timezone', text)} onChangeText={(text) => handleAccountSettingChange('timezone', text)}

View File

@@ -2,6 +2,7 @@
import { create } from 'zustand'; import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware'; import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
interface BookmarkState { interface BookmarkState {
bookmarkedIds: Set<string>; bookmarkedIds: Set<string>;
@@ -50,7 +51,7 @@ export const useBookmarkStore = create<BookmarkState>()(
}), }),
{ {
name: 'rssuper-bookmarks', name: 'rssuper-bookmarks',
storage: createJSONStorage(() => localStorage), storage: createJSONStorage(() => AsyncStorage),
partialize: (state) => ({ partialize: (state) => ({
bookmarkedIds: Array.from(state.bookmarkedIds), bookmarkedIds: Array.from(state.bookmarkedIds),
}), }),