Skip to content

Commit 5369d85

Browse files
Allow guest editing anywhere (server & local)
1 parent 73fbd4d commit 5369d85

10 files changed

Lines changed: 223 additions & 267 deletions

File tree

src/_shared/frametrail-core/storage/StorageAdapterDownload.js

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,23 @@ class StorageAdapterDownload extends StorageAdapter {
1616
constructor() {
1717
super();
1818
this._data = {}; // In-memory cache
19-
20-
// Pre-load user identity so isLoggedIn() works before init() is called.
21-
// If a returning user is stored in localStorage, use it immediately.
22-
// Otherwise set a default so the edit button is visible; init() will
23-
// prompt for a real name on the first save attempt.
24-
var storedUser = null;
25-
try { storedUser = JSON.parse(localStorage.getItem('frametrail_local_user')); } catch (e) {}
26-
this._userInfo = (storedUser && storedUser.id)
27-
? storedUser
28-
: { id: 'localuser', name: 'Local User', role: 'admin', mail: '', color: '#FF9800' };
19+
this._userInfo = {}; // Set by UserManagement after guest login
2920
}
3021

3122
get type() { return 'download'; }
3223
get displayName() { return 'Download'; }
33-
get canSave() { return true; }
24+
get canSave() { return false; } // In-memory only — no persistent save target; use Save As / download
3425
get userInfo() { return this._userInfo; }
3526

27+
/**
28+
* Update the stored user info (called from UserManagement after guest login).
29+
* @param {Object} info - User info object {id, name, role, color}
30+
*/
31+
setUserInfo(info) {
32+
this._userInfo = info;
33+
}
34+
3635
async init() {
37-
var localUser = localStorage.getItem('frametrail_local_user');
38-
if (localUser) {
39-
this._userInfo = JSON.parse(localUser);
40-
} else {
41-
var name = prompt('Enter your name for annotations:', 'Local User');
42-
this._userInfo = {
43-
id: 'local-' + Date.now(),
44-
name: name || 'Local User',
45-
role: 'admin',
46-
mail: '',
47-
registrationDate: Date.now(),
48-
color: '#FF9800'
49-
};
50-
localStorage.setItem('frametrail_local_user', JSON.stringify(this._userInfo));
51-
}
5236
return true;
5337
}
5438

src/_shared/frametrail-core/storage/StorageAdapterLocal.js

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,17 @@ class StorageAdapterLocal extends StorageAdapter {
6363
await this._scaffoldEmptyProject();
6464
}
6565

66-
// Set up local user
67-
await this._initLocalUser();
68-
6966
return true;
7067
}
7168

69+
/**
70+
* Update the stored user info (called from UserManagement after guest login).
71+
* @param {Object} info - User info object {id, name, role, color}
72+
*/
73+
setUserInfo(info) {
74+
this._userInfo = info;
75+
}
76+
7277
/**
7378
* Create minimum project structure in an empty folder.
7479
* @private
@@ -94,49 +99,6 @@ class StorageAdapterLocal extends StorageAdapter {
9499
await this.writeJSON('resources/_index.json', { 'resources': {} });
95100
}
96101

97-
/**
98-
* Set up local user identity. Prompts for name on first use,
99-
* stores in localStorage for subsequent sessions.
100-
* @private
101-
*/
102-
async _initLocalUser() {
103-
var localUser = localStorage.getItem('frametrail_local_user');
104-
if (localUser) {
105-
this._userInfo = JSON.parse(localUser);
106-
} else {
107-
var name = prompt('Enter your name for annotations:', 'Local User');
108-
this._userInfo = {
109-
id: 'local-' + Date.now(),
110-
name: name || 'Local User',
111-
role: 'admin',
112-
mail: '',
113-
registrationDate: Date.now(),
114-
color: '#FF9800'
115-
};
116-
localStorage.setItem('frametrail_local_user', JSON.stringify(this._userInfo));
117-
}
118-
119-
await this._ensureUserInUsersFile();
120-
}
121-
122-
/**
123-
* Ensure the local user exists in the local users.json file.
124-
* @private
125-
*/
126-
async _ensureUserInUsersFile() {
127-
var users;
128-
try {
129-
users = await this.readJSON('users.json');
130-
} catch (e) {
131-
users = { 'user-increment': 0, 'user': {} };
132-
}
133-
134-
if (!users.user[this._userInfo.id]) {
135-
users.user[this._userInfo.id] = this._userInfo;
136-
await this.writeJSON('users.json', users);
137-
}
138-
}
139-
140102
async readJSON(path) {
141103
var handle = await this._getFileHandle(path, false);
142104
var file = await handle.getFile();

src/_shared/modules/Localization/locale/de.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ window.FrameTrail_L10n['de'] = {
370370
"UserColor": "Nutzer:innen-Farbe",
371371
"UserCreateAccount": "Account anlegen",
372372
"UserDividerOr": "oder",
373+
"UserEditAsGuest": "Als Gast bearbeiten",
374+
"UserGuestEditNote": "Bearbeiten und exportieren ohne Account. Änderungen können nicht auf dem Server gespeichert werden.",
375+
"UserGuestName": "Dein Name",
373376
"UserInactive": "Inaktiv",
374377
"UserLogin": "Anmelden",
375378
"UserLogout": "Abmelden",

src/_shared/modules/Localization/locale/en-US.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ window.FrameTrail_L10n['en-US'] = {
370370
"UserColor": "User Color",
371371
"UserCreateAccount": "Create Account",
372372
"UserDividerOr": "or",
373+
"UserEditAsGuest": "Edit as Guest",
374+
"UserGuestEditNote": "Edit and export without an account. Changes cannot be saved to the server.",
375+
"UserGuestName": "Your name",
373376
"UserInactive": "Inactive",
374377
"UserLogin": "Login",
375378
"UserLogout": "Logout",

src/_shared/modules/StorageManager/module.js

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -179,20 +179,22 @@ FrameTrail.defineModule('StorageManager', function(FrameTrail) {
179179
if (!_currentAdapter) return false;
180180

181181
if (_currentAdapter.type === 'server') {
182-
return FrameTrail.getState('loggedIn');
182+
return FrameTrail.getState('loggedIn') &&
183+
!FrameTrail.module('UserManagement').isGuestMode();
183184
}
184185
return _currentAdapter.canSave;
185186
}
186187

187188

188189
/**
189-
* Check if server save is available (server present and user logged in).
190+
* Check if server save is available (server present, user logged in, and not in guest mode).
190191
* @method canSaveToServer
191192
* @return {Boolean}
192193
*/
193194
function canSaveToServer() {
194195
return FrameTrail.module('RouteNavigation').environment.server &&
195-
FrameTrail.getState('loggedIn');
196+
FrameTrail.getState('loggedIn') &&
197+
!FrameTrail.module('UserManagement').isGuestMode();
196198
}
197199

198200

@@ -206,25 +208,6 @@ FrameTrail.defineModule('StorageManager', function(FrameTrail) {
206208
}
207209

208210

209-
/**
210-
* Lazily initialize the Download adapter's user identity.
211-
* Called on first edit attempt in download mode.
212-
* Checks localStorage; if no user is stored, prompts for a name.
213-
*
214-
* @method ensureDownloadUser
215-
* @return {Promise<Object>} Resolves with the user info object
216-
*/
217-
function ensureDownloadUser() {
218-
var info = _downloadAdapter.userInfo;
219-
if (info && info.id) {
220-
return Promise.resolve(info);
221-
}
222-
return _downloadAdapter.init().then(function() {
223-
return _downloadAdapter.userInfo;
224-
});
225-
}
226-
227-
228211
/**
229212
* Get current user info from the active adapter.
230213
* @method getCurrentUserInfo
@@ -263,8 +246,7 @@ FrameTrail.defineModule('StorageManager', function(FrameTrail) {
263246
canSaveToServer: canSaveToServer,
264247
canSaveToLocal: canSaveToLocal,
265248
getCurrentUserInfo: getCurrentUserInfo,
266-
getFolderName: getFolderName,
267-
ensureDownloadUser: ensureDownloadUser
249+
getFolderName: getFolderName
268250
};
269251

270252
});

0 commit comments

Comments
 (0)