class LocalStoragePlus {
constructor() {
this.USER_KEY = 'pm_local_user';
this.LOG_KEY = 'pm_local_log';
this.ALLOWED_USER = 'ralsei-';
}
getInfo() {
return {
id: 'localstorageplus',
name: 'Local Storage+',
color1: '#5ba58c',
color2: '#4b8d78',
blocks: [
{
opcode: 'setUser',
blockType: Scratch.BlockType.COMMAND,
text: 'set username to [USER]',
arguments: {
USER: { type: Scratch.ArgumentType.STRING, defaultValue: 'guest' }
}
},
{
opcode: 'setValue',
blockType: Scratch.BlockType.COMMAND,
text: 'set storage [KEY] to [VALUE]',
arguments: {
KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'score' },
VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: '0' }
}
},
{
opcode: 'getValue',
blockType: Scratch.BlockType.REPORTER,
text: 'get storage [KEY]',
arguments: {
KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'score' }
}
},
{
opcode: 'createList',
blockType: Scratch.BlockType.COMMAND,
text: 'create list [LIST]',
arguments: {
LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }
}
},
{
opcode: 'addToList',
blockType: Scratch.BlockType.COMMAND,
text: 'add [ITEM] to list [LIST]',
arguments: {
ITEM: { type: Scratch.ArgumentType.STRING, defaultValue: 'thing' },
LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }
}
},
{
opcode: 'getFromList',
blockType: Scratch.BlockType.REPORTER,
text: 'item [INDEX] of list [LIST]',
arguments: {
INDEX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 },
LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }
}
},
{
opcode: 'listLength',
blockType: Scratch.BlockType.REPORTER,
text: 'length of list [LIST]',
arguments: {
LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }
}
},
{
opcode: 'clearList',
blockType: Scratch.BlockType.COMMAND,
text: 'clear list [LIST]',
arguments: {
LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }
}
},
{
opcode: 'logEvent',
blockType: Scratch.BlockType.COMMAND,
text: 'log [TEXT]',
arguments: {
TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: 'did something' }
}
},
{
opcode: 'readLog',
blockType: Scratch.BlockType.REPORTER,
text: 'read log (ralsei- only)'
}
]
};
}
_key(k) {
return 'pm_local_' + k;
}
_listKey(name) {
return 'pm_list_' + name;
}
_getUser() {
return localStorage.getItem(this.USER_KEY) || '';
}
_isAllowed() {
return this._getUser() === this.ALLOWED_USER;
}
setUser(args) {
localStorage.setItem(this.USER_KEY, args.USER);
}
setValue(args) {
localStorage.setItem(this._key(args.KEY), args.VALUE);
}
getValue(args) {
return localStorage.getItem(this._key(args.KEY)) || '';
}
createList(args) {
localStorage.setItem(this._listKey(args.LIST), '[]');
}
_getList(name) {
return JSON.parse(localStorage.getItem(this._listKey(name)) || '[]');
}
_setList(name, arr) {
localStorage.setItem(this._listKey(name), JSON.stringify(arr));
}
addToList(args) {
const list = this._getList(args.LIST);
list.push(args.ITEM);
this._setList(args.LIST, list);
}
getFromList(args) {
const list = this._getList(args.LIST);
return list[args.INDEX - 1] ?? '';
}
listLength(args) {
return this._getList(args.LIST).length;
}
clearList(args) {
this._setList(args.LIST, []);
}
logEvent(args) {
const log = JSON.parse(localStorage.getItem(this.LOG_KEY) || '[]');
log.push({
time: new Date().toLocaleString(),
user: this._getUser(),
text: args.TEXT
});
localStorage.setItem(this.LOG_KEY, JSON.stringify(log));
}
readLog() {
if (!this._isAllowed()) return '[access denied]';
const log = JSON.parse(localStorage.getItem(this.LOG_KEY) || '[]');
return log.map(e => `[${e.time}] ${e.user}: ${e.text}`).join('\n');
}
}
Scratch.extensions.register(new LocalStoragePlus());










0 comments