photo.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. Photo.js
  3. Author: tobychui
  4. This is a complete rewrite of the legacy Photo module for ArozOS
  5. */
  6. let photoList = [];
  7. let prePhoto = "";
  8. let nextPhoto = "";
  9. let currentModel = "";
  10. function scrollbarVisable(){
  11. return $("body")[0].scrollHeight > $("body").height();
  12. }
  13. function getImageWidth(){
  14. let boxCount = 4;
  15. if (window.innerWidth < 500) {
  16. boxCount = 3;
  17. } else if (window.innerWidth < 800) {
  18. boxCount = 4;
  19. } else if (window.innerWidth < 1200) {
  20. boxCount = 6;
  21. }else if (window.innerWidth < 1600){
  22. boxCount = 8;
  23. } else {
  24. boxCount = 10;
  25. }
  26. let offsets = 2;
  27. if (scrollbarVisable()){
  28. offsets = offsets * 1.2;
  29. }
  30. return $("#viewbox").width() / boxCount - offsets;
  31. }
  32. function updateImageSizes(){
  33. let newImageWidth = getImageWidth();
  34. //Updates all the size of the images
  35. $(".imagecard").css({
  36. width: newImageWidth,
  37. height: newImageWidth
  38. });
  39. }
  40. function closeSideMenu(){
  41. $('#menu').toggle('fast', function(){
  42. updateImageSizes();
  43. });
  44. }
  45. function extractFolderName(folderpath){
  46. return folderpath.split("/").pop();
  47. }
  48. function initSelectedModelValue(){
  49. ao_module_agirun("Photo/backend/modelSelector.js",{
  50. }, function(data){
  51. currentModel = data;
  52. $("#selectedModel").dropdown("set selected", data);
  53. })
  54. }
  55. function updateSelectedModel(nnnm){
  56. if (nnnm != ""){
  57. ao_module_agirun("Photo/backend/modelSelector.js",{
  58. set: true,
  59. model: nnnm
  60. }, function(data){
  61. console.log("Update model status: ", data);
  62. $("#modelUpdated").slideDown("fast").delay(3000).slideUp('fast');
  63. })
  64. }
  65. }
  66. function settingObject(){
  67. return {
  68. excludeDirs: ["Manga","thumbnail"],
  69. init(){
  70. this.loadExcludeList();
  71. $('#newexc input').off("keypress").on("keypress",function (e) {
  72. if (e.which == 13) {
  73. addDir($('#newexc input'));
  74. }
  75. });
  76. $(".ui.dropdown").dropdown();
  77. initSelectedModelValue();
  78. },
  79. addDir(element){
  80. var dir = $(element).parent().find("input").val();
  81. $("#newexc").removeClass("error");
  82. for (var i = 0; i < this.excludeDirs.length; i++){
  83. if (this.excludeDirs[i] == dir){
  84. //Already exists
  85. $("#newexc").addClass("error");
  86. return;
  87. }
  88. }
  89. this.excludeDirs.push(dir);
  90. $('#newexc input').val("");
  91. },
  92. removeDir(filepath){
  93. //Pop the given filepath from list
  94. var newExcludeDirs = [];
  95. for ( var i = 0; i < this.excludeDirs.length; i++){
  96. var thisExcludeDir = this.excludeDirs[i];
  97. if (thisExcludeDir != filepath){
  98. newExcludeDirs.push(thisExcludeDir);
  99. }
  100. }
  101. this.excludeDirs = newExcludeDirs;
  102. },
  103. loadExcludeList(){
  104. $("#noexcRecords").hide();
  105. fetch(ao_root + "system/ajgi/interface?script=Photo/backend/exclude.js", {
  106. method: 'POST',
  107. cache: 'no-cache',
  108. headers: {
  109. 'Content-Type': 'application/json'
  110. },
  111. body: JSON.stringify({
  112. })
  113. }).then(resp => {
  114. resp.json().then(data => {
  115. console.log(data);
  116. this.excludeDirs = data;
  117. if (data.length == 0){
  118. $("#noexcRecords").show();
  119. }
  120. })
  121. });
  122. },
  123. save(){
  124. fetch(ao_root + "system/ajgi/interface?script=Photo/backend/exclude.js", {
  125. method: 'POST',
  126. cache: 'no-cache',
  127. headers: {
  128. 'Content-Type': 'application/json'
  129. },
  130. body: JSON.stringify({
  131. "set":true,
  132. "folders": this.excludeDirs
  133. })
  134. }).then(resp => {
  135. resp.json().then(data => {
  136. })
  137. });
  138. }
  139. }
  140. }
  141. function photoListObject() {
  142. return {
  143. // data
  144. pathWildcard: "user:/Photo/*",
  145. currentPath: "user:/Photo",
  146. renderSize: 200,
  147. vroots: [],
  148. images: [],
  149. folders: [],
  150. tags: [],
  151. // init
  152. init() {
  153. this.getFolderInfo();
  154. this.getRootInfo();
  155. this.renderSize = getImageWidth();
  156. updateImageSizes();
  157. },
  158. updateRenderingPath(newPath){
  159. this.currentPath = JSON.parse(JSON.stringify(newPath));
  160. this.pathWildcard = newPath + '/*';
  161. if (this.pathWildcard.split("/").length == 3){
  162. //Root path already
  163. $("#parentFolderButton").hide();
  164. }else{
  165. $("#parentFolderButton").show();
  166. }
  167. this.getFolderInfo();
  168. },
  169. parentFolder(){
  170. var parentPath = JSON.parse(JSON.stringify(this.currentPath));
  171. parentPath = parentPath.split("/");
  172. parentPath.pop();
  173. this.currentPath = parentPath.join("/");
  174. this.updateRenderingPath( this.currentPath);
  175. },
  176. getFolderInfo() {
  177. fetch(ao_root + "system/ajgi/interface?script=Photo/backend/listFolder.js", {
  178. method: 'POST',
  179. cache: 'no-cache',
  180. headers: {
  181. 'Content-Type': 'application/json'
  182. },
  183. body: JSON.stringify({
  184. "folder": this.pathWildcard
  185. })
  186. }).then(resp => {
  187. resp.json().then(data => {
  188. console.log(data);
  189. this.folders = data[0];
  190. this.images = data[1];
  191. if (this.images.length == 0){
  192. $("#noimg").show();
  193. }else{
  194. $("#noimg").hide();
  195. }
  196. if (this.folders.length == 0){
  197. $("#nosubfolder").show();
  198. }else{
  199. $("#nosubfolder").hide();
  200. }
  201. console.log(this.folders);
  202. });
  203. });
  204. this.getTags();
  205. },
  206. getRootInfo() {
  207. fetch(ao_root + "system/ajgi/interface?script=Photo/backend/listRoots.js", {
  208. method: 'POST',
  209. cache: 'no-cache',
  210. headers: {
  211. 'Content-Type': 'application/json'
  212. },
  213. body: JSON.stringify({})
  214. }).then(resp => {
  215. resp.json().then(data => {
  216. this.vroots = data;
  217. });
  218. })
  219. },
  220. getTags(){
  221. fetch(ao_root + "system/ajgi/interface?script=Photo/backend/listTags.js", {
  222. method: 'POST',
  223. cache: 'no-cache',
  224. headers: {
  225. 'Content-Type': 'application/json'
  226. },
  227. body: JSON.stringify({
  228. "vroot": this.currentPath
  229. })
  230. }).then(resp => {
  231. resp.json().then(data => {
  232. this.tags = data;
  233. });
  234. });
  235. }
  236. }
  237. }
  238. function renderImageList(object){
  239. var fd = $(object).attr("filedata");
  240. fd = JSON.parse(decodeURIComponent(fd));
  241. console.log(fd);
  242. }
  243. function ShowModal(){
  244. $('.ui.modal.viewer').modal({
  245. onHide: function(){
  246. ao_module_setWindowTitle("Photo");
  247. setTimeout(function(){
  248. $("#fullImage").attr("src","img/loading.png");
  249. }, 300)
  250. }
  251. }).modal('show');
  252. }
  253. function showImage(object){
  254. var fd = JSON.parse(decodeURIComponent($(object).attr("filedata")));
  255. $("#fullImage").attr('src', "../media?file=" + fd.filepath);
  256. var nextCard = $(object).next(".imagecard");
  257. var prevCard = $(object).prev(".imagecard");
  258. if (nextCard.length > 0){
  259. nextPhoto = nextCard[0];
  260. }else{
  261. nextPhoto = null;
  262. }
  263. if (prevCard.length > 0){
  264. prePhoto = prevCard[0];
  265. }else{
  266. prePhoto = null;
  267. }
  268. ao_module_setWindowTitle("Photo - " + fd.filename);
  269. }
  270. $(document).on("keydown", function(e){
  271. if (e.keyCode == 37){
  272. //Left
  273. if (prePhoto != null){
  274. //$('.ui.modal').modal("hide");
  275. showImage(prePhoto);
  276. }
  277. }else if (e.keyCode == 39){
  278. //Right
  279. if (nextPhoto != null){
  280. //$('.ui.modal').modal("hide");
  281. showImage(nextPhoto);
  282. }
  283. }
  284. })
  285. function showSetting(){
  286. $('.ui.modal.setting').modal('show');
  287. }
  288. function rescan(object){
  289. var originalContent = $(object).html();
  290. $(object).addClass("disabled");
  291. $(object).html(`<i class="ui spinner loading icon"></i> Analysing`);
  292. ao_module_agirun("Photo/backend/classify.js", {
  293. }, function(data){
  294. //Done
  295. $(object).removeClass("disabled");
  296. $(object).html(`<i class="ui green checkmark icon"></i> Done`);
  297. setTimeout(function(){
  298. $(object).html(originalContent);
  299. }, 3000);
  300. });
  301. }