Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
"time": { "content": "$2" }
}
},
"settings_open_dev_setting": {"message": "Developer Settings"},
"settings_enable_syncsupport": {"message": "Enable Data Sync"},
"assignment_acquisition_date": {"message": "Assignment Acquisition Date: "},
"testquiz_acquisition_date": {"message": "Test&Quiz Acquisition Date: "},
"due24h": {"message": "Due within 24hrs"},
Expand Down
2 changes: 2 additions & 0 deletions _locales/ja/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
"time": { "content": "$2" }
}
},
"settings_open_dev_setting": {"message": "開発者設定項目"},
"settings_enable_syncsupport": {"message": "デバイス間同期を有効化する"},
"assignment_acquisition_date": {"message": "課題取得日時: "},
"testquiz_acquisition_date": {"message": "クイズ取得日時: "},
"due24h": {"message": "締め切り24時間以内"},
Expand Down
18 changes: 16 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"archiver": "^5.3.0",
"copy-webpack-plugin": "^10.2.4",
"lodash": "^4.17.21",
"lz-string": "^1.5.0",
"mustache": "^4.2.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
Expand Down
19 changes: 19 additions & 0 deletions public/css/comfortable-sakai.css
Original file line number Diff line number Diff line change
Expand Up @@ -802,3 +802,22 @@ input:checked + .cs-toggle-slider:after {
transform: translateX(-100%);
}

details {
padding-top: 10px;
}

details summary {
list-style: none;
cursor: pointer;
}
details summary::-webkit-details-marker {
display: none;
}

details summary::before {
content: "▶ ";
}

details[open] summary::before {
content: "▼ ";
}
14 changes: 13 additions & 1 deletion src/components/main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext } from "react";
import { useTranslation } from "./helper";
import { formatTimestamp, getEntities, updateIsReadFlag } from "../utils";
import { formatTimestamp, getEntities, saveEntities, updateIsReadFlag } from "../utils";
import { EntityUnion, EntryTab, EntryUnion, MemoAddInfo } from "./entryTab";
import { SettingsChange, SettingsTab } from "./settings";
import _ from "lodash";
Expand Down Expand Up @@ -97,6 +97,18 @@ export class MiniSakaiRoot extends React.Component<MiniSakaiRootProps, MiniSakai
});
});
return;
} else if (change.type === "sync-setting") {
const cacheOnly = this.props.subset;
getEntities(this.state.settings, getSakaiCourses(), cacheOnly).then((entities) => {
_.set(newSettings, change.id, change.newValue);
saveSettings(this.state.settings.appInfo.hostname, newSettings).then(() => {
this.setState({
settings: newSettings
});
});
saveEntities(newSettings, entities.assignment, entities.quiz, entities.memo);
});
return;
}

_.set(newSettings, change.id, change.newValue);
Expand Down
20 changes: 20 additions & 0 deletions src/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export type SettingsChange =
}
| {
type: "reset-color";
}
| {
type: "sync-setting";
id: string;
newValue: boolean;
};

export function SettingsTab(props: { onSettingsChange: (change: SettingsChange) => void; settings: Settings }) {
Expand Down Expand Up @@ -191,6 +196,21 @@ export function SettingsTab(props: { onSettingsChange: (change: SettingsChange)
})
}
/>

<details>
<summary>{useTranslationDeps("settings_open_dev_setting", ["settings_open_dev_setting"])}</summary>
<TranslatedBooleanItem
descriptionTag="settings_enable_syncsupport"
value={settings.syncSupport}
onChange={(v) =>
props.onSettingsChange({
type: "sync-setting",
id: "syncSupport",
newValue: v
})
}
/>
</details>
</div>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const QuizzesStorage = "Quizzes";
export const MemosStorage = "Memos";
export const CoursesStorage = "Courses";
export const SettingsStorage = "Settings";
export const SyncSupportStorage = "SyncSupport";
export const AssignmentFetchTimeStorage = "AssignmentFetchTime";
export const QuizFetchTimeStorage = "QuizFetchTime";
export const HostnameStorage = "Hostname";
Expand Down
2 changes: 1 addition & 1 deletion src/features/entity/assignment/saveAssignment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const saveAssignmentEntry = async (hostname: string, changedEntry: Assign
}
// console.log('before save: ', assignments);
await saveAssignments(hostname, assignments);
chrome.storage.local.get(null, (e) => {
chrome.storage.sync.get(null, (e) => {
// console.log(e);
});
};
8 changes: 8 additions & 0 deletions src/features/setting/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,11 @@ export const decodeSettings = (data: any): Settings => {
}
return settings;
};

export const decodesyncSupport = (data: any): boolean => {
let syncSupport = false;
if (typeof data === "undefined") return syncSupport;
syncSupport = data;
//console.log(syncSupport);
return syncSupport;
};
7 changes: 4 additions & 3 deletions src/features/setting/getSetting.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Settings } from "./types";
import { decodeSettings } from "./decode";
import { decodeSettings, decodesyncSupport } from "./decode";
import { fromStorage } from "../storage";
import { CurrentTime, SettingsStorage, VERSION } from "../../constant";
import { CurrentTime, SettingsStorage, SyncSupportStorage, VERSION } from "../../constant";
import { getFetchTime } from "../../utils";

export const getStoredSettings = async (hostname: string): Promise<Settings> => {
const syncSupport = await fromStorage<boolean>(hostname, SyncSupportStorage, decodesyncSupport, false);
const settings = await fromStorage<Settings>(hostname, SettingsStorage, decodeSettings);
const fetchTime = await getFetchTime(settings.appInfo.hostname);
settings.appInfo.currentTime = CurrentTime;
settings.appInfo.hostname = hostname;
settings.appInfo.version = VERSION;
settings.setFetchtime(fetchTime);

settings.syncSupport = syncSupport;
return settings;
};
4 changes: 3 additions & 1 deletion src/features/setting/saveSetting.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Settings } from "./types";
import { toStorage } from "../storage";
import { SettingsStorage } from "../../constant";
import { SettingsStorage, SyncSupportStorage } from "../../constant";

export const saveSettings = (hostname: string, settings: Settings): Promise<string> => {
// console.log(settings);
toStorage(hostname, SyncSupportStorage, settings.syncSupport, false);
return toStorage(hostname, SettingsStorage, settings);
};
1 change: 1 addition & 0 deletions src/features/setting/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export class Settings {
currentTime: CurrentTime,
useDarkTheme: false
};
syncSupport = false;
fetchTime: FetchTime = {
assignment: undefined,
quiz: undefined
Expand Down
53 changes: 47 additions & 6 deletions src/features/storage/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
import { HostnameStorage } from "../../constant";
import { HostnameStorage, SyncSupportStorage } from "../../constant";
import { decodesyncSupport } from "../setting/decode";
import LZString from "lz-string";

export const fromStorage = async <T>(
hostname: string,
key: string,
decoder: (data: any) => T,
allowSync = true
): Promise<T> => {
const storageKey = hostname + "-" + key;
if (allowSync) {
const syncSupport = await fromStorage<boolean>(hostname, SyncSupportStorage, decodesyncSupport, false);
if (syncSupport) {
return new Promise(function (resolve) {
chrome.storage.sync.get(storageKey, function (items: any) {
if (storageKey in items) {
resolve(decoder(JSON.parse(LZString.decompressFromUTF16(items[storageKey]))));
} else {
resolve(decoder(undefined));
}
});
});
}
}

export const fromStorage = <T>(hostname: string, key: string, decoder: (data: any) => T): Promise<T> => {
return new Promise(function (resolve) {
chrome.storage.local.get(hostname, function (items: any) {
if (hostname in items && key in items[hostname]) {
Expand All @@ -14,17 +37,35 @@ export const fromStorage = <T>(hostname: string, key: string, decoder: (data: an

export const loadHostName = (): Promise<string | undefined> => {
return new Promise(function (resolve) {
chrome.storage.local.get(HostnameStorage, function(items: any) {
chrome.storage.local.get(HostnameStorage, function (items: any) {
if (typeof items[HostnameStorage] === "undefined") {
resolve(undefined);
} else resolve(items[HostnameStorage]);
});
});
};

export const toStorage = (hostname: string, key: string, value: any): Promise<string> => {
const entity: { [key: string]: [value: any] } = {};
entity[key] = value;
export const toStorage = async (hostname: string, key: string, value: any, allowSync = true): Promise<string> => {
// items[hostname][key]だと1 Objectあたり8192Bの制限に引っかかるのでhostname-keyの形で分散させる
const storageKey = hostname + "-" + key;

if (allowSync) {
const syncSupport = await fromStorage<boolean>(hostname, SyncSupportStorage, decodesyncSupport, false);
if (syncSupport) {
return new Promise(function (resolve) {
chrome.storage.sync.get(storageKey, function (items: any) {
if (typeof items[storageKey] === "undefined") {
items[storageKey] = {};
}
items[storageKey] = LZString.compressToUTF16(JSON.stringify(value));
chrome.storage.sync.set({ [storageKey]: items[storageKey] }, () => {
resolve("saved");
});
});
});
}
}

return new Promise(function(resolve) {
chrome.storage.local.get(hostname, function (items: any) {
if (typeof items[hostname] === "undefined") {
Expand Down
15 changes: 15 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { fromStorage } from "./features/storage";
import { AssignmentFetchTimeStorage, CurrentTime, MaxTimestamp, QuizFetchTimeStorage } from "./constant";
import { saveAssignments } from "./features/entity/assignment/saveAssignment";
import { EntryProtocol } from "./features/entity/type";
import { saveQuizzes } from "./features/entity/quiz/saveQuiz";
import { saveMemos } from "./features/entity/memo/saveMemo";

export type DueCategory = "due24h" | "due5d" | "due14d" | "dueOver14d" | "duePassed";

Expand All @@ -36,6 +38,19 @@ export async function getEntities(settings: Settings, courses: Array<Course>, ca
};
}

export async function saveEntities(
settings: Settings,
assignment: Array<Assignment>,
quiz: Array<Quiz>,
memo: Array<Memo>
) {
const hostname = settings.appInfo.hostname;
saveAssignments(hostname, assignment);
saveQuizzes(hostname, quiz);
saveMemos(hostname, memo);
return;
}

const decodeTimestamp = (data: any): number | undefined => {
if (data === undefined) return undefined;
return data as number;
Expand Down