User talk:Zhuyifei1999/Archive 55

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search

hi Mr. Zhuyifei1999, I would like to ask you if it was possible to overload the current portrait with the google version found here, but without frame please?--37.183.21.252 20:31, 20 February 2020 (UTC)

This isn't a gigapixel. Use dezoomify --Zhuyifei1999 (talk) 22:23, 20 February 2020 (UTC)
thanks for the suggestion, I hope that with the portrait you can also see the close details, he gave me a 'great suggestion ,, excuse the question, but it also works for google art project portraits ??? or for those you need a program on purpose ,, you see I don't pretend a TITANIC image, I just need a 2000x4000 stuff about, but it is an example of a limit where I want to go, and the right program for certain sizes of portraits?--37.183.21.252 23:57, 20 February 2020 (UTC)
Can't comprehend what you said --Zhuyifei1999 (talk) 00:28, 21 February 2020 (UTC)

21:00, 24 February 2020 (UTC)

Un grazie per WLM e un libro sulla conoscenza libera per te

Wikimedia Italia
Wikimedia Italia

Gentile Zhuyifei1999,

oggi ti scrivo a nome dell'associazione Wikimedia Italia per ringraziarti di aver partecipato a Wiki Loves Monuments Italia. Il tuo contributo è particolarmente apprezzato perché .

Come piccolo omaggio avremmo piacere di spedirti una copia (tutta in carta riciclata) del libro di Carlo Piana, Open source, software libero e altre libertà. Fornisci un recapito per ricevere una copia del libro.

Il libro comprende anche un capitolo sul tuo lavoro! Si parla infatti di libertà di panorama, cioè la libertà di fare e diffondere foto come le tue, ma tutto l'anno e su tutti i monumenti d'Italia. Finché resta la legge attuale, per aumentare le foto caricabili puoi chiedere a un ente vicino a te di aderire a Wiki Loves Monuments. Speriamo che questo libro ti sia utile per apprezzare quanto hai fatto e per trasmettere la passione della conoscenza libera a una persona a te vicina.

Se desideri una copia ma non puoi fornirci un indirizzo a cui spedirla, contatta la segreteria Wikimedia Italia e troviamo una soluzione insieme.

Grazie ancora e a presto,

Lorenzo Losa (msg) 10:30, 25 February 2020 (UTC)

Hi! I wonder why the bot reviewed this image. Did Flickr user upload a new file? --MGA73 (talk) 18:22, 25 February 2020 (UTC)

Same here File:Palácio do Catete (cidade do Rio de Janeiro, Brasil) (abaixo o imperialismo linguístico) 40.jpg. --MGA73 (talk) 18:24, 25 February 2020 (UTC)
It did exactly what it was told to do --Zhuyifei1999 (talk) 18:27, 25 February 2020 (UTC)
Great. I just thought it was strange because the file on Commons is not the same as on Flickr. I think there is 10 different images on Commons that all link to the same file on Flickr. --MGA73 (talk) 18:34, 25 February 2020 (UTC)
Weird. It should not pass an image if they are different. Looking. --Zhuyifei1999 (talk) 18:38, 25 February 2020 (UTC)
I think Commons user and Flickr user is the same. Perhaps he uploaded a pic, asked for review, uploaded a new pic, asked for review etc. --MGA73 (talk) 18:46, 25 February 2020 (UTC)
Yeah I do think that is the case. The archives reference images that could not load. I just tested the code and it says size_not_found. --Zhuyifei1999 (talk) 18:52, 25 February 2020 (UTC)
Sounds good :-) --MGA73 (talk) 19:03, 25 February 2020 (UTC)

00:36, 3 March 2020 (UTC)

SignBot appears stuck again

Hi again. Please restart SignBot again.   — Jeff G. please ping or talk to me 14:34, 5 March 2020 (UTC)

✓ Done --Zhuyifei1999 (talk) 17:05, 5 March 2020 (UTC)

17:15, 9 March 2020 (UTC)

Wiki Loves Africa 2020

Contribute to Wiki Loves Africa and to how the world sees Africa! Contribuez à Wiki Loves Africa et impactez la façon dont le monde voit l’Afrique!
Dear Zhuyifei1999

In the past, you contributed to the Wiki Loves Africa competition. This February, you have another opportunity to create beautiful photographs on the theme of "transportation" that could change how the world understands people and culture in your part of Africa. As with previous years, there are also many exciting cash prizes.

Wiki Loves Africa is an annual public contest where people across Africa can contribute media (photographs, video and audio) about their environment to Wikimedia Commons for use on Wikipedia and other project websites of the Wikimedia Foundation.

Images from the competition have helped millions learn more about Africa and see Africa more clearly from an African perspective. Overall, nearly 5000 people like you have contributed to this photo contest, and contributed 18,000 images about Africa.

When does it take place?

The 2020 competition will start on the 15th of February 2020 and close on 31st March 2020.

What should we contribute?

Pictures ! audios ! videos ! The theme for the 2020 contest is... Africa on the Move ! This theme encompasses a host of approaches and is intentionally open to interpretation. It encourages the submission of visual representations of movement or transportation, whether by path, road, sea air, by self-propelled, animal or mechanical means, or the historical or contemporary structures that have been created to facilitate movement or the transportation of people, goods, or animals.

In addition to the value your photos contribute to understanding and African visibility, there are several prizes on offer. The international prizes are:

  • 1st prize: US$1000
  • 2nd prize: US$800
  • 3rd prize: US$500

Additional categories are:

  • Culturally specific or traditional representations of transport or structures that facilitate transportation : US$500
  • Prize for best quality video: $500


Each winner will also receive a pack of goodies (proposed: a hat "I edit Wikipedia from Africa", a branded battery, stickers). Additional prizes will be available in some countries.

For rules and information about how to participate, or to join the contest, click on Contribute to the Wiki Loves Africa photo contest.

Warmest,

Anthere, for the Wiki Loves Africa Team


Cher ou chère Zhuyifei1999,

Au cours des années passées, vous avez participé au concours photographique Wiki Loves Africa. Ce mois de février vous avez à nouveau l'opportunité de proposer de fabuleuses illustrations sur le thème du "transport", qui pourraient profondément modifier la façon dont le reste du monde voit l’Afrique et comprend ses habitants et ses coutumes. Bonus, comme lors des années précédentes, il y a plusieurs prix à la clé.

Wiki Loves Africa un concours public annuel où chacun est invité à partager des illustrations via Wikimedia Commons, en rapport avec le thème de l’année, illustrations qui pourront être utilisées sur Wikipédia ou les autres sites de la Wikimedia Foundation.

Les photos collectées par le passé dans le cadre du concours ont aidé des millions de personne à mieux connaitre et comprendre l’Afrique et à la voir selon une perspective africaine. Au cours des dernières années, près de 5000 personnes comme vous ont contribué au concours, un total de 18,000 photos sur l’Afrique.

Quand le concours se déroule t-il?

Le concours 2020 démarre le 15 février 2020 et cloture le 31 mars 2020.

Quelles sont les contenus attendus?

Des photos ! Des enregistrements audio ! Des vidéos ! Le thème du concours 2020 est ... Le transport.

Ce thème englobe de nombreuses approches, il est aussi intentionnellement ouvert à l’interprétation. Le thème Transport ! encourage à proposer des représentations liées au mouvement ou au transport, que ce soit par la route, ou l’air, ou l’eau, de façon auto-propulsée ou avec l’aide de la force animale ou mécanique, ou bien également les structures architecturales historiques ou contemporaines qui sont à l’origine ou ont facilité le mouvement et le transport des êtres humains, des animaux ou des biens.

En plus de la valeur intrinsèque que vos photos apportent pour une meilleure visibilité et compréhension de l’Afrique à travers le monde, il y a de nombreux prix à gagner. Les prix internationaux sont les suivants:

  • 1er prix: US$1000
  • 2ème prix: US$800
  • 3ème prix: US$500

Catégories additionnelles:

  • Transport ou structures de transport traditionnelles : US$500
  • Prix de la meilleure vidéo: US$500

Chaque gagnant recevra également des cadeaux supplémentaires tels qu'une casquette "I edit Wikipedia from Africa", une batterie portable, des stickers... Des prix supplémentaires seront offerts dans certains pays.

Pour plus d'informations, règles de participation et pour participer au concours, cliquez sur Participer au concours Wiki Loves Africa.

Bien à vous,

Anthere, pour l'équipe Wiki Loves Africa

AjaxQuickDelete and Cat-a-lot on betacommons

As to not further derail the discussion on Commons:Administrators' noticeboard/User problems#Jameslwoodward, it seems AjaxQuickDelete isn't loading on betacommons either. Cat-a-lot uses jquery.ui.resizable and jquery.ui.dialog so I checked what else uses that and nothing else uses jquery.ui.resizable but AjaxQuickDelete uses jquery.ui.dialog.

And now I noticed what's probably going on:

	mw.loader.using([
			'jquery.ui', // deprecated
			'mediawiki.user',

Oh, snap. @Krinkle: I think this means Cat-a-lot and AjaxQuickDelete are about to break. - Alexis Jazz ping plz 10:02, 2 March 2020 (UTC)

I haz fixed ur deprukasion! - Alexis Jazz ping plz 10:27, 2 March 2020 (UTC)
I am getting close I think: https://commons.wikimedia.beta.wmflabs.org/wiki/User:AJ/Restore-a-lot MediaWiki:Gadget-Restore-a-lot.js
A list of files would have to be edited with a simple search and replace. That's far more doable than clicking hundreds of times. (pywikibot is nice, but it would also be nice to have an on-wiki alternative)
I have to figure out how to make Restore-a-lot pass the token (I modified the request that.. does err something, not the actual edit-request) and figure out how to "satisfy" cat-a-lot so it continues editing after the first file. I'm a total noob so this takes forever. It's not very efficient. - Alexis Jazz ping plz 12:31, 2 March 2020 (UTC)
It compiles, ship it! Only works when using English UI (?uselang=en for anyone who doesn't use English as the default) and only tested on Special:DeletedContributions. Reason it only works in English is because Cat-a-lot uses the "title" attribute, which on Special:DeletedContributions contains "(page does not exist)". I remove this "(page does not exist)" nonsense and it should be easy to just use the contents of the <a> tag (because it's like <a href="File:example.jpg" title="File:example.jpg (page does not exist)">File:example.jpg</a>) instead of the title attribute, but again, I'm a noob. - Alexis Jazz ping plz 11:20, 3 March 2020 (UTC)
@GreenMeansGo: no lot of repetitive clicking in your near future. - Alexis Jazz ping plz 11:22, 3 March 2020 (UTC)
Oh god. It's my arch nemesis, code. GMGtalk 11:25, 3 March 2020 (UTC)
@GreenMeansGo: I've been busy for hours getting it to work and even broke MediaWiki in the process just so we could have an undeletion tool that works like Cat-a-lot. I'm no besties with code either. - Alexis Jazz ping plz 12:13, 3 March 2020 (UTC)
@Alexis Jazz: I can fix that <a> issue. Could you remove any code that are unused and change any namings from cat-a-lot to restore-a-lot (except those referring specifically to cat-a-lot)? --Zhuyifei1999 (talk) 17:10, 3 March 2020 (UTC)
Also, forgot to say, very nice work! I'm sure you will get more experienced with coding ;) --Zhuyifei1999 (talk) 17:21, 3 March 2020 (UTC)
Thank you. :-) I'll try, but I probably can't remove everything because the tool otherwise breaks and I don't always understand why. It's now at User:Alexis Jazz/Restore-a-lot.js so admins can load it in their common.js. I'll keep that version stable (well, as stable whatever I do gets ;-)) and mess about on betacommons. - Alexis Jazz ping plz 17:32, 3 March 2020 (UTC)
I tried, but I don't think I can. I'm working at https://commons.wikimedia.beta.wmflabs.org/wiki/User:AJ/Restore-a-lot.js (refreshes faster than the version in MediaWiki:) and I can't even add an undeletion button/link that actually works. After hours I managed to add an undeletion link (which would hopefully allow getting rid of results.html), but it just doesn't work. - Alexis Jazz ping plz 18:25, 4 March 2020 (UTC)
@Alexis Jazz: I don't understand; what exactly is the issue you are hitting? Like code + expected behavior + actual behavior --Zhuyifei1999 (talk) 20:19, 4 March 2020 (UTC)
The code is spaghetti, but I got it to work. :-) The way I think it works/worked is: the original "undelete" button was just a modified "add category" button that when pressed would fake-add some invisible category to the files which would normally be seen left of the button. The button/link I made did the same, but there was no invisible category left of it, so it tried to add "undefined" and that didn't go down well. I've solved it by hardcoding "Images" as the category. :-P - Alexis Jazz ping plz 20:27, 4 March 2020 (UTC)
@Alexis Jazz: But why do you need a category? We aren't working on categories and should just remove all code related to categories --Zhuyifei1999 (talk) 20:50, 4 March 2020 (UTC)
I 100% agree, but it'll take some time for me to figure out how to remove that stuff without breaking everything. I simply have no idea what I'm doing ("you pay peanuts, you get monkeys"), but at least the tool looks quite neat now as all the unneeded visible elements are gone or invisible now. - Alexis Jazz ping plz 21:18, 4 March 2020 (UTC)
The javascript console and console.log is your friend :) --Zhuyifei1999 (talk) 22:55, 4 March 2020 (UTC)
I gotta look into that.. anyway, how is now? If more cleanup is needed, do you have any suggestions? - Alexis Jazz ping plz 00:05, 5 March 2020 (UTC)
Can I have your permission do code review in line (add comments)? --Zhuyifei1999 (talk) 00:08, 5 March 2020 (UTC)
You don't need permission to do that! Of course you can, please, that would be very helpful. :-) - Alexis Jazz ping plz 08:38, 5 March 2020 (UTC)
Thanks for your comments! I've made some more changes. Really stupid question (I feel like I'm just poking at unknown things in the dark): in a line like: "getContent: function ( page, targetcat, mode )", what are page, targetcat and mode? Are they variables that go into the function? Or does the function output them? How are they called inside the function (if input)/retrieved afterwards (if output)? - Alexis Jazz ping plz 17:04, 5 March 2020 (UTC)
They are the parameters for the function. Simple example:
function fibonacci(i) {
	if (i < 2)
		return i;

	return fibonacci(i-1) + fibonacci(i-2);
}

fibonacci(10); // returns 55
When you call fibonacci(10) and the execution enters fibonacci(i), i is 10. It then recurses into fibonacci(i-1) and fibonacci(i-2), and in these inner frames i takes 8 and 9. More recursion happens until i reaches 0 and 1. Also, each frame is independent from each other. --Zhuyifei1999 (talk) 17:13, 5 March 2020 (UTC)
Simple.. this is very much stretching what I might understand, but I think I somewhat get it. :-) I think I made some progress again, but I can't eliminate getContent. When I do, the operation will cancel with "connection errors", which I think happen because it's checking for a "title" in the response. I tried disabling that check, but the operation just hangs when I do. I think I need another hint.. - Alexis Jazz ping plz 16:55, 7 March 2020 (UTC)
The good news: Restore-a-lot now also works on COM:UDR and deletion requests! :-)
The bad news: that setTimeout thing didn't work and I still can't get rid of getContent. - Alexis Jazz ping plz 19:03, 7 March 2020 (UTC)
Regarding getContent: You don't need the result parameter to undeleteFile do you?
I don't see how that wouldn't work. 5000 is 5 seconds --Zhuyifei1999 (talk) 20:14, 7 March 2020 (UTC)
I don't? I'll try!
I dunno, but I tried it and it just wouldn't wait. Or maybe it starts the next request while it's waiting, not sure. I had set it to 5 seconds to make sure I could verify it works. - Alexis Jazz ping plz 20:53, 7 March 2020 (UTC)
Ah I see why "it starts the next request while it's waiting" would happen. getContent is in a loop so the function would return before the timeout, starting the next request --Zhuyifei1999 (talk) 21:08, 7 March 2020 (UTC)
I got rid of getContent. :-) Does anything more have to be done? - Alexis Jazz ping plz 02:10, 8 March 2020 (UTC)
Get rid of spin wait. I'll look tomorrow. I'm quite bust this weekend and next week, but after that I will hopefully have a ton of time for just a week --Zhuyifei1999 (talk) 03:28, 8 March 2020 (UTC)
Presumably you mean the jquery.spinner. It's gone, I agree, this is better. - Alexis Jazz ping plz 13:06, 8 March 2020 (UTC)
Uh no I was referring to pausecomp. "spin wait" meant a wait that is implemented via spinning --Zhuyifei1999 (talk) 14:12, 8 March 2020 (UTC)
Oh, oops. Still, I'm leaving the jquery.spinner out. I like it better this way. Also, I think I resolved the issue. I currently have the delay set to 800ms because betacommons is seriously underperforming, but on production a lower value can be tried. If betacommons is still down when you read this, I also updated User:Alexis Jazz/Restore-a-lot.js. - Alexis Jazz ping plz 18:37, 8 March 2020 (UTC)
Mind if I properly add a the wait? --Zhuyifei1999 (talk) 19:49, 8 March 2020 (UTC)
This is a collaborative project, do anything that you think will improve it, please. :-) - Alexis Jazz ping plz 20:20, 8 March 2020 (UTC)
I'll do it this weekend or next week. No time right now --Zhuyifei1999 (talk) 18:59, 10 March 2020 (UTC)
Thanks. :-) I've tweaked the interface a little bit, but I haven't changed the delay stuff. - Alexis Jazz ping plz 18:07, 15 March 2020 (UTC)
Is there anything I could do? It would be great to see Restore-a-lot as a regular gadget, but I don't know how to "properly add a the wait". - Alexis Jazz ping plz 22:52, 20 March 2020 (UTC)
Oops, sorry. Forgot about it. Doing --Zhuyifei1999 (talk) 23:09, 20 March 2020 (UTC)

@Alexis Jazz: I did the part of properly-async. Shall I explain how it works? --Zhuyifei1999 (talk) 23:53, 20 March 2020 (UTC)

Thanks, that would be interesting. I see you create an array of pages, I'm not sure how you cycle through them but it does work. It's not a nested thing where the variable keeps calling itself or something, is it? Is anything else needed to add Restore-a-lot as a gadget? - Alexis Jazz ping plz 19:19, 21 March 2020 (UTC)
So the code is
// precondition: pages is a jquery object (array-like) of pages
pages = Array.from( pages ).map( function ( page ) {
    return function () {
        var defer = $.Deferred();
        setTimeout( function timer() {
            RAL.undeleteFile( page );
            defer.resolve();
        }, 800 );
        return defer;
    };
} );

var defer = pages.shift()();
pages.map( function ( pagefunc ) {
    defer = defer.then( pagefunc );
} );
It's hard to explain it without an 'intro to javascript asynchronism', so (a lot of pseudocode, lots of API functions are inaccurate, only represents the idea):

In the beginning asynchronism was simple. You click on a button, an attribute of the button is called. Something happens, one of its attributes is called. Sort of like:

var button = document.find('button');
button.onclick = function() {
  this.text = "Hey I'm clicked!";
};

You can think of it being implemented like this:

struct event event;

while (nextevent(&event)) {
  switch (event.type) {
  case EVENT_GUI: {
    struct jsobject *jsobject = find_jsobject_coords(event.gui.coords);
    switch (event.gui.action) {
    case GUI_CLICK:
      call_jsmethod(jsobject, "onclick");
      break;
    [...]
    break;
  }
  [...]
}

^ is an 'event loop'. It loops to wait on events and calls the appropriate handler method.

However, things got complicated. User interaction isn't only thing that's asynchronous events. Timer waits and networking events too. Now you might wonder, why can't we be synchronous like every other language out there? Why must we:

setTimeout(function() {
  window.say_hi = 'Hi!';
}, 1000);

instead of:

sleep(1000);
window.say_hi = 'Hi!';

The reson is somewhat interesting. One, JS is originally intended only for browsers, which has GUI, and GUI libraries implement clicks and button presses as events and expect one to use event loops. So you can't make the underlying native code sleep on a certain GUI object. Then JS has a 'run-to-completion semantics', to avoid race conditions. One event handler is expected to finish it's synchronous code fully before the next handler will execute.

So, if you have a synchronous sleep, the handler will block every other handler, so if you sleep(1000), then nothing would possibly be handled for a second. No mouse clicks, key presses, no rendering, nothing.

But this has an issue. Remember I said networking events are asynchronous? Well, you can also start networking from within js. Here comes XMLHttpRequest (XHR), chained:

var xhr1 = XHR('api/gettoken');
xhr1.onload = function(data) {
  var xhr2 = XHR('api/edit', {text: 'blahblahblah', token: data.token});
};

'gettoken' is probably some frequently used code, so people invented callbacks:

function gettoken_and_do(cb) {
  var xhr = XHR('api/gettoken');
  xhr.onload = cb;
}

gettoken_and_do(function(data) {
  XHR('api/edit', {text: 'blahblahblah', token: data.token});
});

Here a function is passed into another function as a callback, gettoken_and_do would call the callback back when the token is fetched. It's like how you pass a function to setTimeout.

Let's chain them:

document.find('button').onclick = function() {
  setTimeout(function() {
    gettoken_and_do(function(data) {
      XHR('api/edit', {text: 'blahblahblah', token: data.token});
    });
  }, 500);
};

How ugly :( nesting callbacks lead to "callback hell". I would love to write it as:

document.find('button').onclick = function() {
  sleep(500);
  data = gettoken();
  XHR('api/edit', {text: 'blahblahblah', token: data.token});
};

This will be possible, ... many many years later..., but, people found a solution that kind of looks much better. Enter promises. A deferred / promise is an object representing something that will be finished in the future, so you can say something like, 'when this promise is resolved, do that'.

jQuery might have been one of the earliest adopters and implementers of deferred / promise. A rewrite of the above code, using jquery deferred / promises only (no other peatures of jquery) would be:

function sleep(millis) {
  var defer = $.deferred();
  setTimeout(function() {
    defer.resolve();
  }, millis);
  return defer;
}

function gettoken() {
  var defer = $.deferred();
  var xhr = XHR('api/gettoken');
  xhr.onload = function(data) {
    defer.resolve(data);
  };
  return defer;
}

document.find('button').onclick = function() {
  sleep(500)
    .then(gettoken)
    .then(function(data) {
      XHR('api/edit', {text: 'blahblahblah', token: data.token});
    });
};

Oh, much better. We are just doing .then chaining. Not perfect, but workable. A lot of JS were written this way (or other similar ways) until ES6 / ES7 (we will get to this later).

The implementation of promise... you can think of it as (very bad and inaccurate, but will probably work for above cases):

$.deferred = function() {
  var resolved = false;
  var resolvedata = undefined;
  var handlers = [];
  return {
    then: function(cb) {
      // returns a promise of the return value of the callback.
      // if the callback returns a promise, then we wait on that promise
      var defer = $.deferred();
      var _then = function() {
        res = cb(resolvedata);
        if (res && res.then)
          // might be a promise, resolve with the value of the returned promise
          res.then(funstion(_res) {
            defer.resolve(_res);
          };
        } else {
          defer.resolve(res);
        }
      }
      if (resolved) {
        _then();
      } else {
        handlers.push(_then);
      }
      return defer;
    },
    resolve: function(data) {
      // execute all thens
      if (resolved) {
        throw new Error("Can't resolve a second time!");
      }
      resolved = true;
      resolvedata = data;
      for (int i = 0; i < handlers.length; i++) {
        handlers[i]();
      }
    }
  };
};

So back to my code:

// precondition: pages is a jquery object (array-like) of pages
pages = Array.from( pages ).map( function ( page ) {
    return function () {
        var defer = $.Deferred();
        setTimeout( function timer() {
            RAL.undeleteFile( page );
            defer.resolve();
        }, 800 );
        return defer;
    };
} );

var defer = pages.shift()();
pages.map( function ( pagefunc ) {
    defer = defer.then( pagefunc );
} );

In Array.from, I converted a jquery object to a native JS array. In the first .map I mapped each page, to a function (return function () {) that takes nothing and returns a promise when the page is processed.

In var defer = pages.shift()();, .shift() removes and returns the first entry in the array of functions, and I immediately call it, which returns the prsomise for the first page's processing.

When I have another .map, which, simply chains the rest of functions with .then. Since every function returns a promise, every function would be called after the previous function's promise is resolved.

This is how it works.

Oh, did I say I would get to ES6 / ES7? Well, in ES6 promise became a JS built-in, and in ES7, a new way to write it is possible with async / await syntax. So the previous example becomes:

function sleep(millis) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, millis);
  });
}

function gettoken() {
  return new Promise(function(resolve) {
    var xhr = XHR('api/gettoken');
    xhr.onload = function(data) {
      resolve(data);
    };
  });
}

document.find('button').onclick = async function() {
  await sleep(500);
  var data = await gettoken();
  XHR('api/edit', {text: 'blahblahblah', token: data.token});
};

And my gadget code would become:

// precondition: pages is a jquery object (array-like) of pages
// change function to async function
for ( let page of Array.from( pages ) )
  await sleep( 800 );
  RAL.undeleteFile( page );
} );

You can't get better than this. Unfortunately, I doubt MediaWiki's ReourceLoader supports ES6 even. phab:T75714. So promises is the best we can do with asynchronous javascript in Gadgets :(

To clarify, ES7 async functions are more or less syntactic sugar. async simply makes the function returns a JS native promise that wraps what looks to be the 'return value' in the return statement, and await evaluates into the value wrapped by the promise. --Zhuyifei1999 (talk) 04:35, 23 March 2020 (UTC)

As for 'Is anything else needed to add Restore-a-lot as a gadget?' No. Though, I would like to hear other's opinion first. Maybe ping the others who were involved in the previous discussion here (I don't remember where the discussion was)? --Zhuyifei1999 (talk) 21:48, 21 March 2020 (UTC)

By the way, none of the above code are tested. lol. A lot of them are half-pseudo half-real code anyways :) --Zhuyifei1999 (talk) 22:00, 21 March 2020 (UTC)

Oh and, do you want to become an IA here? I welcome anyone with the curiosity on how stuffs works. (And yes, please ask if you can't figure out how something works or how to properly do something) --Zhuyifei1999 (talk) 23:38, 21 March 2020 (UTC)

Oh wow, there's a lot to take in here. That's a thorough explanation. A lot of it is going over my head at the moment (I'm just a newbie), I'll have to sit down in a few days and read it again to try and understand it better. Perhaps you could add it to b:JavaScript?
I'm not very confident in writing book content -- just like I'm not confident in writing encyclopedic content. I'm fine with explaining something, but writing it in a way that looks to be coming out of a book... uh :/
Yes, I can tell you don't have much experience in coding, hence Special:Diff/401311383 --Zhuyifei1999 (talk) 01:33, 23 March 2020 (UTC)
There wasn't much previous discussion, mostly Commons:Administrators' noticeboard/User problems/Archive 83#Jameslwoodward where Jameslwoodward said "If there weren't 105 files in the list, I would suggest that it would be better to restore the files and have the discussion in a DR -- it would get wider attention there. " and GreenMeansGo said "Is there way to batch undelete these and nominate them for DR? Or do I just have a lot of repetitive clicking in my near future?"
Pinging @JuTa, GreenMeansGo, Ankry, Geagea, Krd, Sreejithk2000, Natuur12, Jameslwoodward, Ymblanter, Taivo (can I ping this many people at once?), our top restorers according to [11]. Do you like the tool? Here's a (slightly outdated) screenshot: https://phab.wmfusercontent.org/file/data/vv23otceztfgjcsjep7l/PHID-FILE-ijcuhqv5zebwhrjb2rsp/why_is_betacommons_in_simple_English.png. - Alexis Jazz ping plz 00:45, 23 March 2020 (UTC)
I am quite happy being an IA on betacommons. I doubt it's practical for me to be an IA without admin rights. Also I like having a second set of eyes before I mess things up.. - Alexis Jazz ping plz 00:43, 23 March 2020 (UTC)
I think it is a good idea but don't understand how I can check it. -- Geagea (talk) 23:16, 23 March 2020 (UTC)
Alright I'll import this. --Zhuyifei1999 (talk) 00:16, 24 March 2020 (UTC)
✓ Done --Zhuyifei1999 (talk) 00:29, 24 March 2020 (UTC)
Awesome, thanks! The 800ms delay can probably be much lower here (performance on betacommons is teh suck), but I suspect 100ms or even 50ms would never cause any problem here.
I don't think there is much of an issue keeping the delay (gives you time to rethink your admin actions :P), otherwise I could probably do it without delay because one request always completes before the next. --Zhuyifei1999 (talk) 08:05, 24 March 2020 (UTC)
Introducing some 800ms delay on deletions, that would be an interesting thought.. Anyway, how about 400ms? That should be fast enough not to be annoying (restore 50 files in 20 seconds), yet still gives you a moment to reconsider before hundreds of files have been restored. 800ms is purely based on what betacommons can handle. - Alexis Jazz ping plz 11:31, 24 March 2020 (UTC)
✓ Done --Zhuyifei1999 (talk) 18:24, 24 March 2020 (UTC)