From f3c50288e4373615047fba03c5e1256f75530c4b Mon Sep 17 00:00:00 2001 From: bagng Date: Tue, 19 Sep 2023 15:52:41 +0900 Subject: [PATCH 1/6] fix image data source. --- Flamingo.js | 72 ++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/Flamingo.js b/Flamingo.js index 3b661e8..e6294a4 100644 --- a/Flamingo.js +++ b/Flamingo.js @@ -1,6 +1,9 @@ // Variables used by Scriptable. // These must be at the very top of the file. Do not edit. // icon-color: pink; icon-glyph: dove; +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: pink; icon-glyph: dove; // Flamingo Widget v1.1 - by UnvsDev // Dive into the world of art, in your iPhone. // Learn More: https://github.com/unvsDev/Flamingo @@ -52,12 +55,12 @@ var endMode = false if(config.runsInApp){ const settings = new UITable() settings.showSeparators = true - + const info = new UITableRow() info.dismissOnSelect = false info.addText("Welcome to Flamingo", "Developed by unvsDev") settings.addRow(info) - + const selectArtist = new UITableRow() selectArtist.dismissOnSelect = false selectArtist.addText("Set Artwork Filter") @@ -70,7 +73,7 @@ if(config.runsInApp){ alert.addAction("Artvee's Weekly Pick") alert.addAction("Special Collections") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response == 0) { let inAlert = new Alert() @@ -79,7 +82,7 @@ if(config.runsInApp){ inAlert.addTextField("Leonardo Da Vinci", "") inAlert.addAction("Done") inAlert.addCancelAction("Cancel") - + if(await inAlert.present() != -1){ prefData.artist = inAlert.textFieldValue() } @@ -88,22 +91,22 @@ if(config.runsInApp){ } else if(response == 2){ const collectionView = new UITable() collectionView.showSeparators = true - + for(name in artveeCollections){ const collectionRow = new UITableRow() collectionRow.dismissOnSelect = true collectionRow.addText(name) collectionView.addRow(collectionRow) - + collectionRow.onSelect = async () => { prefData.artist = artveeCollections[name] } } - + await collectionView.present() } } - + const selectLocal = new UITableRow() selectLocal.dismissOnSelect = false selectLocal.addText("Local Artworks") @@ -116,13 +119,13 @@ if(config.runsInApp){ alert.addAction("Show only local Artworks") alert.addDestructiveAction("Never download Artworks") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response != -1){ prefData.local = response } } - + const selectRef = new UITableRow() selectRef.dismissOnSelect = false selectRef.addText("Refresh Interval") @@ -134,13 +137,13 @@ if(config.runsInApp){ alert.addTextField("(second)", prefData.refresh.toString()) alert.addAction("Done") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response != -1){ prefData.refresh = parseInt(alert.textFieldValue()) } } - + const selectTitle = new UITableRow() selectTitle.dismissOnSelect = false selectTitle.addText("Show Artwork's Detail") @@ -151,13 +154,13 @@ if(config.runsInApp){ alert.message = "Widget will show Artwork's Name and Author." alert.addAction("Yes") alert.addAction("No") - + let response = await alert.present() if(response != -1){ prefData.title = response ? false : true } } - + const selectRt = new UITableRow() selectRt.dismissOnSelect = false selectRt.addText("Show Last Refreshed Time") @@ -168,13 +171,13 @@ if(config.runsInApp){ alert.message = "Widget will show Artwork's last refreshed time." alert.addAction("Yes") alert.addAction("No") - + let response = await alert.present() if(response != -1){ prefData.rtitle = response ? false : true } } - + const selectLoad = new UITableRow() selectLoad.dismissOnSelect = false selectLoad.addText("Artwork Search Range") @@ -188,13 +191,13 @@ if(config.runsInApp){ alert.addAction("100 (Big)") alert.addAction("200 (Large)") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response != -1){ prefData.load = response } } - + const resetOption = new UITableRow() resetOption.dismissOnSelect = true resetOption.addText("Reset all data") @@ -207,7 +210,7 @@ if(config.runsInApp){ alert.addDestructiveAction("Delete only user data") alert.addDestructiveAction("Delete all artworks with data") alert.addCancelAction("No") - + let response = await alert.present() if(response == 0){ await fm.remove(prefPath) @@ -215,7 +218,7 @@ if(config.runsInApp){ await fm.remove(fDir) } } - + const saveOption = new UITableRow() saveOption.dismissOnSelect = true saveOption.addText("Save and quit") @@ -223,7 +226,7 @@ if(config.runsInApp){ saveOption.onSelect = () => { endMode = true } - + await settings.present() fm.writeString(prefPath, JSON.stringify(prefData)) } @@ -234,14 +237,14 @@ prefData = JSON.parse(fm.readString(prefPath)) const artistInput = prefData.artist const artist = artistInput.replace(/ /gi, "-").toLowerCase() - + async function loadArts(artist){ var chunk if(prefData.load == 0) { chunk = 20 } else if(prefData.load == 1) { chunk = 50 } else if(prefData.load == 2) { chunk = 100 } else { chunk = 200 } - + const baseUrl = 'https://artvee.com' var source if(artistInput == "!weekly") { @@ -251,12 +254,12 @@ async function loadArts(artist){ } else { source = `${baseUrl}/artist/${artist}/?per_page=`+ chunk } - + let webView = new WebView() await webView.loadURL(source) - + return webView.evaluateJavaScript(` - let arts = [...document.querySelectorAll('.products .product-grid-item .product-wrapper')].map((ele) => { + let arts = [...document.querySelectorAll('.products, .product-grid-item, .product-wrapper')].map((ele) => { let productLinkEle = ele.querySelector('.product-element-top') let imageEle = productLinkEle.querySelector('img') let productInfoEle = ele.querySelector('.product-element-bottom') @@ -270,13 +273,13 @@ async function loadArts(artist){ }, link: productLinkEle.getAttribute('href'), image: { - link: imageEle.getAttribute('src'), + link: imageEle.getAttribute('data-src'), width: imageEle.getAttribute('width'), height: imageEle.getAttribute('height'), } } }).sort((prev, next) => prev.id - next.id) - + completion(arts) `, true) } @@ -309,7 +312,7 @@ let targetArt; let todayIdx if(offlineMode){ let localData = JSON.parse(fm.readString(localPath)) todayIdx = Math.floor(Math.random() * localData.image.length) - + var artAuthor = localData.author[todayIdx] var artName = localData.name[todayIdx] var artUrl = localData.url[todayIdx] @@ -318,12 +321,12 @@ if(offlineMode){ // console.log('arts: ' + JSON.stringify(arts, null, 4)) todayIdx = Math.floor(Math.random() * arts.length) let todayArt = arts[todayIdx] - + var artId = todayArt.id var artAuthor = todayArt.artist.info.split("(")[0] var artName = todayArt.title.split("(")[0] var artUrl = todayArt.link - + let localData = JSON.parse(fm.readString(localPath)) if(localData.image.indexOf(artId) != -1){ targetArt = await fm.readImage(fm.joinPath(fDir2, artId + ".jpg")) @@ -332,7 +335,7 @@ if(offlineMode){ targetArt = await new Request(todayArt.image.link).loadImage() console.log("[*] Downloaded image.. (" + artId + ")") } - + if(prefData.local == 0){ let localData = JSON.parse(fm.readString(localPath)) if(localData.image.indexOf(artId) == -1){ @@ -364,7 +367,7 @@ if(prefData.title){ let author = lStack.addText(artAuthor) author.textColor = Color.white() author.font = Font.lightMonospacedSystemFont(12) - + let title = lStack.addText(artName) title.textColor = Color.white() title.font = Font.boldMonospacedSystemFont(15) @@ -375,7 +378,7 @@ if(prefData.rtitle){ rTitle.textColor = Color.white() rTitle.font = Font.lightMonospacedSystemFont(9) } - + function formatTime(date) { let df = new DateFormatter() df.useNoDateStyle() @@ -398,3 +401,4 @@ widget.addSpacer(3) widget.backgroundImage = targetArt widget.presentLarge() + From 2c799e669d30f05fdeda98c2f45b33d737d68c2b Mon Sep 17 00:00:00 2001 From: bagng Date: Wed, 20 Sep 2023 08:55:18 +0900 Subject: [PATCH 2/6] Remove complic souce comments. --- Flamingo.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/Flamingo.js b/Flamingo.js index e6294a4..2670bb3 100644 --- a/Flamingo.js +++ b/Flamingo.js @@ -1,9 +1,6 @@ // Variables used by Scriptable. // These must be at the very top of the file. Do not edit. // icon-color: pink; icon-glyph: dove; -// Variables used by Scriptable. -// These must be at the very top of the file. Do not edit. -// icon-color: pink; icon-glyph: dove; // Flamingo Widget v1.1 - by UnvsDev // Dive into the world of art, in your iPhone. // Learn More: https://github.com/unvsDev/Flamingo From 3c2251f3bbdf71f8959acf2de0ef5e1e05edc3c0 Mon Sep 17 00:00:00 2001 From: Nhokon Park Date: Mon, 18 Aug 2025 09:36:34 +0900 Subject: [PATCH 3/6] Update Flamingo.js "data-src" changed to "src" --- Flamingo.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Flamingo.js b/Flamingo.js index 2670bb3..10d1ac4 100644 --- a/Flamingo.js +++ b/Flamingo.js @@ -232,6 +232,9 @@ if(endMode){ return 0 } prefData = JSON.parse(fm.readString(prefPath)) +if(prefData.artist == null) + return + const artistInput = prefData.artist const artist = artistInput.replace(/ /gi, "-").toLowerCase() @@ -270,7 +273,7 @@ async function loadArts(artist){ }, link: productLinkEle.getAttribute('href'), image: { - link: imageEle.getAttribute('data-src'), + link: imageEle.getAttribute('src'), width: imageEle.getAttribute('width'), height: imageEle.getAttribute('height'), } From 2d1901ab91f2d121923fc44c327c9f5e71a9bf72 Mon Sep 17 00:00:00 2001 From: Nhokon Park Date: Fri, 29 Aug 2025 13:56:19 +0900 Subject: [PATCH 4/6] Update Flamingo.js --- Flamingo.js | 66 ++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/Flamingo.js b/Flamingo.js index 10d1ac4..af83dc0 100644 --- a/Flamingo.js +++ b/Flamingo.js @@ -52,12 +52,12 @@ var endMode = false if(config.runsInApp){ const settings = new UITable() settings.showSeparators = true - + const info = new UITableRow() info.dismissOnSelect = false info.addText("Welcome to Flamingo", "Developed by unvsDev") settings.addRow(info) - + const selectArtist = new UITableRow() selectArtist.dismissOnSelect = false selectArtist.addText("Set Artwork Filter") @@ -70,7 +70,7 @@ if(config.runsInApp){ alert.addAction("Artvee's Weekly Pick") alert.addAction("Special Collections") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response == 0) { let inAlert = new Alert() @@ -79,7 +79,7 @@ if(config.runsInApp){ inAlert.addTextField("Leonardo Da Vinci", "") inAlert.addAction("Done") inAlert.addCancelAction("Cancel") - + if(await inAlert.present() != -1){ prefData.artist = inAlert.textFieldValue() } @@ -88,22 +88,22 @@ if(config.runsInApp){ } else if(response == 2){ const collectionView = new UITable() collectionView.showSeparators = true - + for(name in artveeCollections){ const collectionRow = new UITableRow() collectionRow.dismissOnSelect = true collectionRow.addText(name) collectionView.addRow(collectionRow) - + collectionRow.onSelect = async () => { prefData.artist = artveeCollections[name] } } - + await collectionView.present() } } - + const selectLocal = new UITableRow() selectLocal.dismissOnSelect = false selectLocal.addText("Local Artworks") @@ -116,13 +116,13 @@ if(config.runsInApp){ alert.addAction("Show only local Artworks") alert.addDestructiveAction("Never download Artworks") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response != -1){ prefData.local = response } } - + const selectRef = new UITableRow() selectRef.dismissOnSelect = false selectRef.addText("Refresh Interval") @@ -134,13 +134,13 @@ if(config.runsInApp){ alert.addTextField("(second)", prefData.refresh.toString()) alert.addAction("Done") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response != -1){ prefData.refresh = parseInt(alert.textFieldValue()) } } - + const selectTitle = new UITableRow() selectTitle.dismissOnSelect = false selectTitle.addText("Show Artwork's Detail") @@ -151,13 +151,13 @@ if(config.runsInApp){ alert.message = "Widget will show Artwork's Name and Author." alert.addAction("Yes") alert.addAction("No") - + let response = await alert.present() if(response != -1){ prefData.title = response ? false : true } } - + const selectRt = new UITableRow() selectRt.dismissOnSelect = false selectRt.addText("Show Last Refreshed Time") @@ -168,13 +168,13 @@ if(config.runsInApp){ alert.message = "Widget will show Artwork's last refreshed time." alert.addAction("Yes") alert.addAction("No") - + let response = await alert.present() if(response != -1){ prefData.rtitle = response ? false : true } } - + const selectLoad = new UITableRow() selectLoad.dismissOnSelect = false selectLoad.addText("Artwork Search Range") @@ -188,13 +188,13 @@ if(config.runsInApp){ alert.addAction("100 (Big)") alert.addAction("200 (Large)") alert.addCancelAction("Cancel") - + let response = await alert.present() if(response != -1){ prefData.load = response } } - + const resetOption = new UITableRow() resetOption.dismissOnSelect = true resetOption.addText("Reset all data") @@ -207,7 +207,7 @@ if(config.runsInApp){ alert.addDestructiveAction("Delete only user data") alert.addDestructiveAction("Delete all artworks with data") alert.addCancelAction("No") - + let response = await alert.present() if(response == 0){ await fm.remove(prefPath) @@ -215,7 +215,7 @@ if(config.runsInApp){ await fm.remove(fDir) } } - + const saveOption = new UITableRow() saveOption.dismissOnSelect = true saveOption.addText("Save and quit") @@ -223,7 +223,7 @@ if(config.runsInApp){ saveOption.onSelect = () => { endMode = true } - + await settings.present() fm.writeString(prefPath, JSON.stringify(prefData)) } @@ -232,19 +232,20 @@ if(endMode){ return 0 } prefData = JSON.parse(fm.readString(prefPath)) -if(prefData.artist == null) +if(prefData.artist == undefined && prefData.artist == null) return +console.log(prefData.artist) const artistInput = prefData.artist const artist = artistInput.replace(/ /gi, "-").toLowerCase() - + async function loadArts(artist){ var chunk if(prefData.load == 0) { chunk = 20 } else if(prefData.load == 1) { chunk = 50 } else if(prefData.load == 2) { chunk = 100 } else { chunk = 200 } - + const baseUrl = 'https://artvee.com' var source if(artistInput == "!weekly") { @@ -254,10 +255,10 @@ async function loadArts(artist){ } else { source = `${baseUrl}/artist/${artist}/?per_page=`+ chunk } - + let webView = new WebView() await webView.loadURL(source) - + return webView.evaluateJavaScript(` let arts = [...document.querySelectorAll('.products, .product-grid-item, .product-wrapper')].map((ele) => { let productLinkEle = ele.querySelector('.product-element-top') @@ -279,7 +280,7 @@ async function loadArts(artist){ } } }).sort((prev, next) => prev.id - next.id) - + completion(arts) `, true) } @@ -312,7 +313,7 @@ let targetArt; let todayIdx if(offlineMode){ let localData = JSON.parse(fm.readString(localPath)) todayIdx = Math.floor(Math.random() * localData.image.length) - + var artAuthor = localData.author[todayIdx] var artName = localData.name[todayIdx] var artUrl = localData.url[todayIdx] @@ -321,12 +322,10 @@ if(offlineMode){ // console.log('arts: ' + JSON.stringify(arts, null, 4)) todayIdx = Math.floor(Math.random() * arts.length) let todayArt = arts[todayIdx] - var artId = todayArt.id var artAuthor = todayArt.artist.info.split("(")[0] var artName = todayArt.title.split("(")[0] var artUrl = todayArt.link - let localData = JSON.parse(fm.readString(localPath)) if(localData.image.indexOf(artId) != -1){ targetArt = await fm.readImage(fm.joinPath(fDir2, artId + ".jpg")) @@ -335,7 +334,7 @@ if(offlineMode){ targetArt = await new Request(todayArt.image.link).loadImage() console.log("[*] Downloaded image.. (" + artId + ")") } - + if(prefData.local == 0){ let localData = JSON.parse(fm.readString(localPath)) if(localData.image.indexOf(artId) == -1){ @@ -367,7 +366,7 @@ if(prefData.title){ let author = lStack.addText(artAuthor) author.textColor = Color.white() author.font = Font.lightMonospacedSystemFont(12) - + let title = lStack.addText(artName) title.textColor = Color.white() title.font = Font.boldMonospacedSystemFont(15) @@ -378,7 +377,7 @@ if(prefData.rtitle){ rTitle.textColor = Color.white() rTitle.font = Font.lightMonospacedSystemFont(9) } - + function formatTime(date) { let df = new DateFormatter() df.useNoDateStyle() @@ -401,4 +400,3 @@ widget.addSpacer(3) widget.backgroundImage = targetArt widget.presentLarge() - From 6a96af69571fb94bc8bbeead9f9eecc6b142fcd2 Mon Sep 17 00:00:00 2001 From: Nhokon Park Date: Fri, 29 Aug 2025 13:59:58 +0900 Subject: [PATCH 5/6] Update Flamingo.js remove whitespace. --- Flamingo.js | 570 ++++++++++++++++++++++++++-------------------------- 1 file changed, 285 insertions(+), 285 deletions(-) diff --git a/Flamingo.js b/Flamingo.js index af83dc0..adce330 100644 --- a/Flamingo.js +++ b/Flamingo.js @@ -12,254 +12,254 @@ const fDir2 = fm.joinPath(fDir, "/artworks/") const localPath = fm.joinPath(fDir, "artwork.txt") const prefPath = fm.joinPath(fDir, "flamPref.txt") var prefData = { - artist: "!weekly", - local: 0, - refresh: 1800, - title: true, - rtitle: false, - load: 0 + artist: "!weekly", + local: 0, + refresh: 1800, + title: true, + rtitle: false, + load: 0 } var artworkOrgPref = { - author: [], - name: [], - url: [], - image: [] + author: [], + name: [], + url: [], + image: [] } var bnum = 101 // Do not edit this area -if(!fm.fileExists(fDir)){ fm.createDirectory(fDir) } -if(fm.fileExists(prefPath)){ - prefData = JSON.parse(fm.readString(prefPath)) +if (!fm.fileExists(fDir)) { fm.createDirectory(fDir) } +if (fm.fileExists(prefPath)) { + prefData = JSON.parse(fm.readString(prefPath)) } -if(!fm.fileExists(localPath)){ - fm.writeString(localPath, JSON.stringify(artworkOrgPref)) - fm.createDirectory(fDir2) +if (!fm.fileExists(localPath)) { + fm.writeString(localPath, JSON.stringify(artworkOrgPref)) + fm.createDirectory(fDir2) } var artveeCollections = { - "Advertising Lithographs" : "https://artvee.com/collection/advertising-lithographs/", - "Fashion Lithographs" : "https://artvee.com/collection/fashion-lithographs/", - "Popular American Songs Covers" : "https://artvee.com/collection/popular-american-songs-covers/", - "Fairy Tale illustrations" : "https://artvee.com/collection/fairy-tale-illustrations-from-elizabeth-tylers-home-and-school-series/", - "NASA's Visions of the Future" : "https://artvee.com/collection/nasas-visions-of-the-future/", - "Dietmar Winkler's MIT Posters" : "https://artvee.com/collection/dietmar-winklers-mit-posters/", - "Book Promo Posters" : "https://artvee.com/collection/book-promo-posters/" + "Advertising Lithographs": "https://artvee.com/collection/advertising-lithographs/", + "Fashion Lithographs": "https://artvee.com/collection/fashion-lithographs/", + "Popular American Songs Covers": "https://artvee.com/collection/popular-american-songs-covers/", + "Fairy Tale illustrations": "https://artvee.com/collection/fairy-tale-illustrations-from-elizabeth-tylers-home-and-school-series/", + "NASA's Visions of the Future": "https://artvee.com/collection/nasas-visions-of-the-future/", + "Dietmar Winkler's MIT Posters": "https://artvee.com/collection/dietmar-winklers-mit-posters/", + "Book Promo Posters": "https://artvee.com/collection/book-promo-posters/" } var endMode = false -if(config.runsInApp){ - const settings = new UITable() - settings.showSeparators = true - - const info = new UITableRow() - info.dismissOnSelect = false - info.addText("Welcome to Flamingo", "Developed by unvsDev") - settings.addRow(info) - - const selectArtist = new UITableRow() - selectArtist.dismissOnSelect = false - selectArtist.addText("Set Artwork Filter") - settings.addRow(selectArtist) - selectArtist.onSelect = async () => { - let alert = new Alert() - alert.title = "Choose Topic" - alert.message = "What artwork do you want to show in your widget?" - alert.addAction("Specific Artist") - alert.addAction("Artvee's Weekly Pick") - alert.addAction("Special Collections") - alert.addCancelAction("Cancel") - - let response = await alert.present() - if(response == 0) { - let inAlert = new Alert() - inAlert.title = "Type your Artist" - inAlert.message = "Just type artist's name,\nlike \"Leonardo Da Vinci\"." - inAlert.addTextField("Leonardo Da Vinci", "") - inAlert.addAction("Done") - inAlert.addCancelAction("Cancel") - - if(await inAlert.present() != -1){ - prefData.artist = inAlert.textFieldValue() - } - } else if(response == 1){ - prefData.artist = "!weekly" - } else if(response == 2){ - const collectionView = new UITable() - collectionView.showSeparators = true - - for(name in artveeCollections){ - const collectionRow = new UITableRow() - collectionRow.dismissOnSelect = true - collectionRow.addText(name) - collectionView.addRow(collectionRow) - - collectionRow.onSelect = async () => { - prefData.artist = artveeCollections[name] +if (config.runsInApp) { + const settings = new UITable() + settings.showSeparators = true + + const info = new UITableRow() + info.dismissOnSelect = false + info.addText("Welcome to Flamingo", "Developed by unvsDev") + settings.addRow(info) + + const selectArtist = new UITableRow() + selectArtist.dismissOnSelect = false + selectArtist.addText("Set Artwork Filter") + settings.addRow(selectArtist) + selectArtist.onSelect = async () => { + let alert = new Alert() + alert.title = "Choose Topic" + alert.message = "What artwork do you want to show in your widget?" + alert.addAction("Specific Artist") + alert.addAction("Artvee's Weekly Pick") + alert.addAction("Special Collections") + alert.addCancelAction("Cancel") + + let response = await alert.present() + if (response == 0) { + let inAlert = new Alert() + inAlert.title = "Type your Artist" + inAlert.message = "Just type artist's name,\nlike \"Leonardo Da Vinci\"." + inAlert.addTextField("Leonardo Da Vinci", "") + inAlert.addAction("Done") + inAlert.addCancelAction("Cancel") + + if (await inAlert.present() != -1) { + prefData.artist = inAlert.textFieldValue() + } + } else if (response == 1) { + prefData.artist = "!weekly" + } else if (response == 2) { + const collectionView = new UITable() + collectionView.showSeparators = true + + for (name in artveeCollections) { + const collectionRow = new UITableRow() + collectionRow.dismissOnSelect = true + collectionRow.addText(name) + collectionView.addRow(collectionRow) + + collectionRow.onSelect = async () => { + prefData.artist = artveeCollections[name] + } + } + + await collectionView.present() } - } - - await collectionView.present() } - } - - const selectLocal = new UITableRow() - selectLocal.dismissOnSelect = false - selectLocal.addText("Local Artworks") - settings.addRow(selectLocal) - selectLocal.onSelect = async () => { - let alert = new Alert() - alert.title = "Get Local Artworks?" - alert.message = "Widget will load only downloaded Artworks, enable you to surf through offline." - alert.addAction("Always download Artworks") - alert.addAction("Show only local Artworks") - alert.addDestructiveAction("Never download Artworks") - alert.addCancelAction("Cancel") - - let response = await alert.present() - if(response != -1){ - prefData.local = response + + const selectLocal = new UITableRow() + selectLocal.dismissOnSelect = false + selectLocal.addText("Local Artworks") + settings.addRow(selectLocal) + selectLocal.onSelect = async () => { + let alert = new Alert() + alert.title = "Get Local Artworks?" + alert.message = "Widget will load only downloaded Artworks, enable you to surf through offline." + alert.addAction("Always download Artworks") + alert.addAction("Show only local Artworks") + alert.addDestructiveAction("Never download Artworks") + alert.addCancelAction("Cancel") + + let response = await alert.present() + if (response != -1) { + prefData.local = response + } } - } - - const selectRef = new UITableRow() - selectRef.dismissOnSelect = false - selectRef.addText("Refresh Interval") - settings.addRow(selectRef) - selectRef.onSelect = async () => { - let alert = new Alert() - alert.title = "Refresh Interval?" - alert.message = "Due to iOS Widget policy, refresh could be delayed up to several hours." - alert.addTextField("(second)", prefData.refresh.toString()) - alert.addAction("Done") - alert.addCancelAction("Cancel") - - let response = await alert.present() - if(response != -1){ - prefData.refresh = parseInt(alert.textFieldValue()) + + const selectRef = new UITableRow() + selectRef.dismissOnSelect = false + selectRef.addText("Refresh Interval") + settings.addRow(selectRef) + selectRef.onSelect = async () => { + let alert = new Alert() + alert.title = "Refresh Interval?" + alert.message = "Due to iOS Widget policy, refresh could be delayed up to several hours." + alert.addTextField("(second)", prefData.refresh.toString()) + alert.addAction("Done") + alert.addCancelAction("Cancel") + + let response = await alert.present() + if (response != -1) { + prefData.refresh = parseInt(alert.textFieldValue()) + } } - } - - const selectTitle = new UITableRow() - selectTitle.dismissOnSelect = false - selectTitle.addText("Show Artwork's Detail") - settings.addRow(selectTitle) - selectTitle.onSelect = async () => { - let alert = new Alert() - alert.title = "Show Artwork's Detail?" - alert.message = "Widget will show Artwork's Name and Author." - alert.addAction("Yes") - alert.addAction("No") - - let response = await alert.present() - if(response != -1){ - prefData.title = response ? false : true + + const selectTitle = new UITableRow() + selectTitle.dismissOnSelect = false + selectTitle.addText("Show Artwork's Detail") + settings.addRow(selectTitle) + selectTitle.onSelect = async () => { + let alert = new Alert() + alert.title = "Show Artwork's Detail?" + alert.message = "Widget will show Artwork's Name and Author." + alert.addAction("Yes") + alert.addAction("No") + + let response = await alert.present() + if (response != -1) { + prefData.title = response ? false : true + } } - } - - const selectRt = new UITableRow() - selectRt.dismissOnSelect = false - selectRt.addText("Show Last Refreshed Time") - settings.addRow(selectRt) - selectRt.onSelect = async () => { - let alert = new Alert() - alert.title = "Show Last Refreshed Time?" - alert.message = "Widget will show Artwork's last refreshed time." - alert.addAction("Yes") - alert.addAction("No") - - let response = await alert.present() - if(response != -1){ - prefData.rtitle = response ? false : true + + const selectRt = new UITableRow() + selectRt.dismissOnSelect = false + selectRt.addText("Show Last Refreshed Time") + settings.addRow(selectRt) + selectRt.onSelect = async () => { + let alert = new Alert() + alert.title = "Show Last Refreshed Time?" + alert.message = "Widget will show Artwork's last refreshed time." + alert.addAction("Yes") + alert.addAction("No") + + let response = await alert.present() + if (response != -1) { + prefData.rtitle = response ? false : true + } } - } - - const selectLoad = new UITableRow() - selectLoad.dismissOnSelect = false - selectLoad.addText("Artwork Search Range") - settings.addRow(selectLoad) - selectLoad.onSelect = async () => { - let alert = new Alert() - alert.title = "Input search range" - alert.message = "Widget will search this amount of artworks at once. Larger range allows you to find various artworks, However smaller range lets you see artwork faster. Remember that if there's not enough artworks, this range can be ignored." - alert.addAction("20 (Small)") - alert.addAction("50 (Medium)") - alert.addAction("100 (Big)") - alert.addAction("200 (Large)") - alert.addCancelAction("Cancel") - - let response = await alert.present() - if(response != -1){ - prefData.load = response + + const selectLoad = new UITableRow() + selectLoad.dismissOnSelect = false + selectLoad.addText("Artwork Search Range") + settings.addRow(selectLoad) + selectLoad.onSelect = async () => { + let alert = new Alert() + alert.title = "Input search range" + alert.message = "Widget will search this amount of artworks at once. Larger range allows you to find various artworks, However smaller range lets you see artwork faster. Remember that if there's not enough artworks, this range can be ignored." + alert.addAction("20 (Small)") + alert.addAction("50 (Medium)") + alert.addAction("100 (Big)") + alert.addAction("200 (Large)") + alert.addCancelAction("Cancel") + + let response = await alert.present() + if (response != -1) { + prefData.load = response + } } - } - - const resetOption = new UITableRow() - resetOption.dismissOnSelect = true - resetOption.addText("Reset all data") - settings.addRow(resetOption) - resetOption.onSelect = async () => { - endMode = true - let alert = new Alert() - alert.title = "Reset Confirmation" - alert.message = "Do you really want to reset all data? Since Thanos helps me to delete them, you cannot undo your action." - alert.addDestructiveAction("Delete only user data") - alert.addDestructiveAction("Delete all artworks with data") - alert.addCancelAction("No") - - let response = await alert.present() - if(response == 0){ - await fm.remove(prefPath) - } else if(response == 1){ - await fm.remove(fDir) + + const resetOption = new UITableRow() + resetOption.dismissOnSelect = true + resetOption.addText("Reset all data") + settings.addRow(resetOption) + resetOption.onSelect = async () => { + endMode = true + let alert = new Alert() + alert.title = "Reset Confirmation" + alert.message = "Do you really want to reset all data? Since Thanos helps me to delete them, you cannot undo your action." + alert.addDestructiveAction("Delete only user data") + alert.addDestructiveAction("Delete all artworks with data") + alert.addCancelAction("No") + + let response = await alert.present() + if (response == 0) { + await fm.remove(prefPath) + } else if (response == 1) { + await fm.remove(fDir) + } } - } - - const saveOption = new UITableRow() - saveOption.dismissOnSelect = true - saveOption.addText("Save and quit") - settings.addRow(saveOption) - saveOption.onSelect = () => { - endMode = true - } - - await settings.present() - fm.writeString(prefPath, JSON.stringify(prefData)) + + const saveOption = new UITableRow() + saveOption.dismissOnSelect = true + saveOption.addText("Save and quit") + settings.addRow(saveOption) + saveOption.onSelect = () => { + endMode = true + } + + await settings.present() + fm.writeString(prefPath, JSON.stringify(prefData)) } -if(endMode){ return 0 } +if (endMode) { return 0 } prefData = JSON.parse(fm.readString(prefPath)) -if(prefData.artist == undefined && prefData.artist == null) - return +if (prefData.artist == undefined && prefData.artist == null) + return console.log(prefData.artist) const artistInput = prefData.artist const artist = artistInput.replace(/ /gi, "-").toLowerCase() - -async function loadArts(artist){ - var chunk - if(prefData.load == 0) { chunk = 20 } - else if(prefData.load == 1) { chunk = 50 } - else if(prefData.load == 2) { chunk = 100 } - else { chunk = 200 } - - const baseUrl = 'https://artvee.com' - var source - if(artistInput == "!weekly") { - source = 'https://artvee.com/highlights/' - } else if(artistInput.indexOf("http") != -1){ - source = artistInput - } else { - source = `${baseUrl}/artist/${artist}/?per_page=`+ chunk - } - - let webView = new WebView() - await webView.loadURL(source) - - return webView.evaluateJavaScript(` + +async function loadArts(artist) { + var chunk + if (prefData.load == 0) { chunk = 20 } + else if (prefData.load == 1) { chunk = 50 } + else if (prefData.load == 2) { chunk = 100 } + else { chunk = 200 } + + const baseUrl = 'https://artvee.com' + var source + if (artistInput == "!weekly") { + source = 'https://artvee.com/highlights/' + } else if (artistInput.indexOf("http") != -1) { + source = artistInput + } else { + source = `${baseUrl}/artist/${artist}/?per_page=` + chunk + } + + let webView = new WebView() + await webView.loadURL(source) + + return webView.evaluateJavaScript(` let arts = [...document.querySelectorAll('.products, .product-grid-item, .product-wrapper')].map((ele) => { let productLinkEle = ele.querySelector('.product-element-top') let imageEle = productLinkEle.querySelector('img') @@ -280,7 +280,7 @@ async function loadArts(artist){ } } }).sort((prev, next) => prev.id - next.id) - + completion(arts) `, true) } @@ -288,64 +288,64 @@ async function loadArts(artist){ var offlineMode = (prefData.local == 1) ? true : false let arts = [] -try{ - const uServer = "https://github.com/unvsDev/Flamingo/raw/main/VERSION" - const cServer = "https://github.com/unvsDev/Flamingo/raw/main/Flamingo.js" - var minVer = parseInt(await new Request(uServer).loadString()) - if(bnum < minVer){ - var code = await new Request(cServer).loadString() - fm.writeString(fm.joinPath(fm.documentsDirectory(), Script.name() + ".js"), code) - return 0 - } -} catch(e) { - offlineMode = true +try { + const uServer = "https://github.com/unvsDev/Flamingo/raw/main/VERSION" + const cServer = "https://github.com/unvsDev/Flamingo/raw/main/Flamingo.js" + var minVer = parseInt(await new Request(uServer).loadString()) + if (bnum < minVer) { + var code = await new Request(cServer).loadString() + fm.writeString(fm.joinPath(fm.documentsDirectory(), Script.name() + ".js"), code) + return 0 + } +} catch (e) { + offlineMode = true } -if(!offlineMode){ - arts = await loadArts(artist) - if(arts.length < 1){ - throw new Error("[!] No result found.") - return 0 - } +if (!offlineMode) { + arts = await loadArts(artist) + if (arts.length < 1) { + throw new Error("[!] No result found.") + return 0 + } } let targetArt; let todayIdx -if(offlineMode){ - let localData = JSON.parse(fm.readString(localPath)) - todayIdx = Math.floor(Math.random() * localData.image.length) - - var artAuthor = localData.author[todayIdx] - var artName = localData.name[todayIdx] - var artUrl = localData.url[todayIdx] - targetArt = await fm.readImage(fm.joinPath(fDir2, localData.image[todayIdx] + ".jpg")) +if (offlineMode) { + let localData = JSON.parse(fm.readString(localPath)) + todayIdx = Math.floor(Math.random() * localData.image.length) + + var artAuthor = localData.author[todayIdx] + var artName = localData.name[todayIdx] + var artUrl = localData.url[todayIdx] + targetArt = await fm.readImage(fm.joinPath(fDir2, localData.image[todayIdx] + ".jpg")) } else { - // console.log('arts: ' + JSON.stringify(arts, null, 4)) - todayIdx = Math.floor(Math.random() * arts.length) - let todayArt = arts[todayIdx] - var artId = todayArt.id - var artAuthor = todayArt.artist.info.split("(")[0] - var artName = todayArt.title.split("(")[0] - var artUrl = todayArt.link - let localData = JSON.parse(fm.readString(localPath)) - if(localData.image.indexOf(artId) != -1){ - targetArt = await fm.readImage(fm.joinPath(fDir2, artId + ".jpg")) - console.log("[*] Getting preloaded image.. (" + artId + ")") - } else { - targetArt = await new Request(todayArt.image.link).loadImage() - console.log("[*] Downloaded image.. (" + artId + ")") - } - - if(prefData.local == 0){ + // console.log('arts: ' + JSON.stringify(arts, null, 4)) + todayIdx = Math.floor(Math.random() * arts.length) + let todayArt = arts[todayIdx] + var artId = todayArt.id + var artAuthor = todayArt.artist.info.split("(")[0] + var artName = todayArt.title.split("(")[0] + var artUrl = todayArt.link let localData = JSON.parse(fm.readString(localPath)) - if(localData.image.indexOf(artId) == -1){ - localData.author.push(artAuthor) - localData.name.push(artName) - localData.image.push(artId) - localData.url.push(artUrl) - fm.writeImage(fm.joinPath(fDir2, artId + ".jpg"), targetArt) - fm.writeString(localPath, JSON.stringify(localData)) + if (localData.image.indexOf(artId) != -1) { + targetArt = await fm.readImage(fm.joinPath(fDir2, artId + ".jpg")) + console.log("[*] Getting preloaded image.. (" + artId + ")") + } else { + targetArt = await new Request(todayArt.image.link).loadImage() + console.log("[*] Downloaded image.. (" + artId + ")") + } + + if (prefData.local == 0) { + let localData = JSON.parse(fm.readString(localPath)) + if (localData.image.indexOf(artId) == -1) { + localData.author.push(artAuthor) + localData.name.push(artName) + localData.image.push(artId) + localData.url.push(artUrl) + fm.writeImage(fm.joinPath(fDir2, artId + ".jpg"), targetArt) + fm.writeString(localPath, JSON.stringify(localData)) + } } - } } let widget = new ListWidget() @@ -362,27 +362,27 @@ lStack.layoutVertically() lStack.addSpacer() -if(prefData.title){ - let author = lStack.addText(artAuthor) - author.textColor = Color.white() - author.font = Font.lightMonospacedSystemFont(12) - - let title = lStack.addText(artName) - title.textColor = Color.white() - title.font = Font.boldMonospacedSystemFont(15) +if (prefData.title) { + let author = lStack.addText(artAuthor) + author.textColor = Color.white() + author.font = Font.lightMonospacedSystemFont(12) + + let title = lStack.addText(artName) + title.textColor = Color.white() + title.font = Font.boldMonospacedSystemFont(15) } -if(prefData.rtitle){ - let rTitle = lStack.addText("Last updated: " + formatTime(today) + " (" + `${todayIdx + 1} / ${arts.length}` + ", ID: " + artId + ")") - rTitle.textColor = Color.white() - rTitle.font = Font.lightMonospacedSystemFont(9) +if (prefData.rtitle) { + let rTitle = lStack.addText("Last updated: " + formatTime(today) + " (" + `${todayIdx + 1} / ${arts.length}` + ", ID: " + artId + ")") + rTitle.textColor = Color.white() + rTitle.font = Font.lightMonospacedSystemFont(9) } - + function formatTime(date) { - let df = new DateFormatter() - df.useNoDateStyle() - df.useShortTimeStyle() - return df.string(date) + let df = new DateFormatter() + df.useNoDateStyle() + df.useShortTimeStyle() + return df.string(date) } hStack.addSpacer() From 5c2115205f6a0024c863b52338da2355878c7764 Mon Sep 17 00:00:00 2001 From: Nhokon Park Date: Thu, 4 Sep 2025 07:21:36 +0900 Subject: [PATCH 6/6] Update Flamingo.js Error on line 235:13: TypeError: null is not an object (evaluating 'prefData.artist') fix error. --- Flamingo.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flamingo.js b/Flamingo.js index adce330..258bb26 100644 --- a/Flamingo.js +++ b/Flamingo.js @@ -32,6 +32,7 @@ var bnum = 101 // Do not edit this area if (!fm.fileExists(fDir)) { fm.createDirectory(fDir) } if (fm.fileExists(prefPath)) { prefData = JSON.parse(fm.readString(prefPath)) + if (!prefData.artist) prefData.artist = "!weekly"; } if (!fm.fileExists(localPath)) { fm.writeString(localPath, JSON.stringify(artworkOrgPref)) @@ -232,9 +233,8 @@ if (endMode) { return 0 } prefData = JSON.parse(fm.readString(prefPath)) -if (prefData.artist == undefined && prefData.artist == null) +if (prefData.artist == undefined || prefData.artist == null) return -console.log(prefData.artist) const artistInput = prefData.artist const artist = artistInput.replace(/ /gi, "-").toLowerCase()