Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💻 Programs count #5278

Merged
merged 56 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
47d61b9
trying to make it work
Annelein Mar 14, 2024
9130b1c
try deleting it after noticing its not modified?
Annelein Mar 18, 2024
f2fb108
only show modified programs
Annelein Mar 18, 2024
c2452ef
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 18, 2024
b824db9
revert old code
Annelein Mar 18, 2024
a984aeb
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Mar 18, 2024
8b72a18
only show confetti when program is modified
Annelein Mar 25, 2024
a2593ba
🤖 Automatically update generated files
Annelein Mar 25, 2024
8154858
only show confett button when program is modifief
Annelein Mar 25, 2024
7f6595b
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Mar 25, 2024
f5694af
🤖 Automatically update generated files
Annelein Mar 25, 2024
f2fc947
if modified show confetti
Annelein Mar 25, 2024
a2b3ec8
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Mar 25, 2024
2b56e07
🤖 Automatically update generated files
Annelein Mar 25, 2024
1954809
new design of search dropdowns, needs design for programs saved
Annelein Apr 1, 2024
1b32b4c
Merge branch 'main' into programs-count
Annelein Apr 8, 2024
de8ec50
design my program page
Annelein Apr 8, 2024
b440498
program count added to frontend
Annelein Apr 8, 2024
29b2287
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 8, 2024
a296a22
remove comment
Annelein Apr 8, 2024
a23a1d7
solve merge error
Annelein Apr 8, 2024
8dddc00
🤖 Automatically update generated files
Annelein Apr 8, 2024
b9bee5f
remove text for one program for now
Annelein Apr 8, 2024
d218ef3
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Apr 8, 2024
2c43e84
🤖 Automatically update generated files
Annelein Apr 8, 2024
5bb3b2b
remove unneeded translation
Annelein Apr 8, 2024
91442e4
Revert "remove unneeded translation"
Annelein Apr 8, 2024
139cb09
remove unneeded translations
Annelein Apr 8, 2024
e06904b
Revert "remove unneeded translations"
Annelein Apr 8, 2024
1564c0c
remove unneeded translations
Annelein Apr 8, 2024
2a9cd3d
move check for program is_modified
Annelein Apr 9, 2024
fd92092
add tests
Annelein Apr 10, 2024
cee5447
Merge branch 'main' into programs-count
Annelein Apr 10, 2024
82b85f4
🤖 Automatically update generated files
Annelein Apr 10, 2024
9564d13
update
Annelein Apr 17, 2024
cf5b39f
update program count on page
Annelein Apr 17, 2024
0c25389
fixing checkig if program is modified
jpelay Apr 17, 2024
8ae0810
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Apr 17, 2024
8d5a691
only modified programs should be shown in search boxes
Annelein Apr 17, 2024
17452ce
Merge branch 'main' into programs-count
Annelein Apr 17, 2024
924aec5
line too long
Annelein Apr 17, 2024
97d6f90
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 17, 2024
185c3dd
🤖 Automatically update generated files
pre-commit-ci[bot] Apr 17, 2024
5785026
unneeded ts code
Annelein Apr 17, 2024
dea21dd
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Apr 17, 2024
916e769
🤖 Automatically update generated files
Annelein Apr 17, 2024
78a6c58
Merge branch 'main' into programs-count
Annelein Apr 18, 2024
fb13f87
looking into update my programs page
Annelein Apr 18, 2024
ab2ab4f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 18, 2024
0a5b065
updating the page with TS
Annelein Apr 22, 2024
e8e329a
Merge branch 'main' into programs-count
Annelein Apr 22, 2024
0852935
cleanup
Annelein Apr 22, 2024
706a148
Merge branch 'programs-count' of https://github.com/hedyorg/hedy into…
Annelein Apr 22, 2024
88c87cc
remove unused import
Annelein Apr 22, 2024
c12bc6b
fix tests
Annelein Apr 23, 2024
8779d5e
Merge branch 'main' into programs-count
Annelein Apr 23, 2024
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
50 changes: 33 additions & 17 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def get_locale():
DATABASE = database.Database()
ACHIEVEMENTS = achievements.Achievements(DATABASE, ACHIEVEMENTS_TRANSLATIONS)
SURVEYS = surveys.SurveysModule(DATABASE)
STATISTICS = statistics.StatisticsModule(DATABASE)

TAGS = collections.defaultdict(hedy_content.NoSuchAdventure)
for lang in ALL_LANGUAGES.keys():
Expand Down Expand Up @@ -658,17 +659,20 @@ def parse():
# Save this program (if the user is logged in)
if username and body.get('save_name'):
try:
program_logic = programs.ProgramsLogic(DATABASE, ACHIEVEMENTS)
program_logic = programs.ProgramsLogic(DATABASE, ACHIEVEMENTS, STATISTICS)
program = program_logic.store_user_program(
user=current_user(),
level=level,
name=body.get('save_name'),
program_id=body.get('program_id'),
adventure_name=body.get('adventure_name'),
short_name=body.get('short_name'),
code=code,
error=exception is not None)

response['save_info'] = SaveInfo.from_program(Program.from_database_row(program))
if program.get('is_modified'):
response['is_modified'] = True
except programs.NotYourProgramError:
# No permissions to overwrite, no biggie
pass
Expand Down Expand Up @@ -1016,6 +1020,8 @@ def programs_page(user):
program['adventure_name'] not in adventure_names:
ids_to_fetch.append(program['adventure_name'])

all_programs = [program for program in all_programs if program.get('is_modified')]

teacher_adventures = DATABASE.batch_get_adventures(ids_to_fetch)
for id, teacher_adventure in teacher_adventures.items():
if teacher_adventure is not None:
Expand All @@ -1033,19 +1039,20 @@ def programs_page(user):
date = utils.delta_timestamp(item['date'])
# This way we only keep the first 4 lines to show as preview to the user
preview_code = "\n".join(item['code'].split("\n")[:4])
programs.append(
{'id': item['id'],
'preview_code': preview_code,
'code': item['code'],
'date': date,
'level': item['level'],
'name': item['name'],
'adventure_name': item.get('adventure_name'),
'submitted': item.get('submitted'),
'public': item.get('public'),
'number_lines': item['code'].count('\n') + 1
}
)
if item.get('is_modified'):
programs.append(
{'id': item['id'],
'preview_code': preview_code,
'code': item['code'],
'date': date,
'level': item['level'],
'name': item['name'],
'adventure_name': item.get('adventure_name'),
'submitted': item.get('submitted'),
'public': item.get('public'),
'number_lines': item['code'].count('\n') + 1
}
)

sorted_level_programs = hedy_content.Adventures(g.lang) \
.get_sorted_level_programs(all_programs, adventure_names)
Expand All @@ -1067,7 +1074,8 @@ def programs_page(user):
adventure_names=adventure_names,
max_level=hedy.HEDY_MAX_LEVEL,
next_page_url=next_page_url,
second_teachers_programs=False)
second_teachers_programs=False,
user_program_count=len(programs))


@app.route('/logs/query', methods=['POST'])
Expand Down Expand Up @@ -2658,6 +2666,13 @@ def public_user_page(username):
'public_user_page',
username=username, **dict(request.args,
page=next_page_token)) if next_page_token else None

user = DATABASE.user_by_username(username)
if user.get('program_count'):
user_program_count = user.get('program_count')
else:
user_program_count = 0

return render_template(
'public-page.html',
user_info=user_public_info,
Expand All @@ -2670,7 +2685,8 @@ def public_user_page(username):
certificate_message=certificate_message,
next_page_url=next_page_url,
sorted_level_programs=sorted_level_programs,
sorted_adventure_programs=sorted_adventure_programs
sorted_adventure_programs=sorted_adventure_programs,
user_program_count=user_program_count,
)
return utils.error_page(error=404, ui_message=gettext('user_not_private'))

Expand Down Expand Up @@ -2733,7 +2749,7 @@ def current_user_allowed_to_see_program(program):

app.register_blueprint(auth_pages.AuthModule(DATABASE))
app.register_blueprint(profile.ProfileModule(DATABASE))
app.register_blueprint(programs.ProgramsModule(DATABASE, ACHIEVEMENTS))
app.register_blueprint(programs.ProgramsModule(DATABASE, ACHIEVEMENTS, STATISTICS))
app.register_blueprint(for_teachers.ForTeachersModule(DATABASE, ACHIEVEMENTS))
app.register_blueprint(classes.ClassModule(DATABASE, ACHIEVEMENTS))
app.register_blueprint(classes.MiscClassPages(DATABASE, ACHIEVEMENTS))
Expand Down
70 changes: 63 additions & 7 deletions static/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@ export function initializeHighlightedCodeBlocks(where: Element) {
if (dir === "rtl") {
symbol = "⇤";
}
$('<button>').css({ fontFamily: 'sans-serif' }).addClass('yellow-btn').text(symbol).appendTo(buttonContainer).click(function() {
const adventure = container.getAttribute('data-tabtarget')
$('<button>').css({ fontFamily: 'sans-serif' }).addClass('yellow-btn').attr('data-cy', `paste-example-code-${adventure}`).text(symbol).appendTo(buttonContainer).click(function() {
if (!theGlobalEditor?.isReadOnly) {
theGlobalEditor.contents = exampleEditor.contents + '\n';
}
Expand Down Expand Up @@ -538,6 +539,7 @@ export async function runit(level: number, lang: string, raw: boolean, disabled_
tutorial: $('#code_output').hasClass("z-40"), // if so -> tutorial mode
read_aloud : !!$('#speak_dropdown').val(),
adventure_name: adventureName,
short_name: adventure ? adventure.short_name : undefined,
raw: raw,

// Save under an existing id if this field is set
Expand Down Expand Up @@ -584,7 +586,7 @@ export async function runit(level: number, lang: string, raw: boolean, disabled_
program_data = theGlobalDebugger.get_program_data();
}

runPythonProgram(program_data.Code, program_data.source_map, program_data.has_turtle, program_data.has_pressed, program_data.has_sleep, program_data.has_clear, program_data.has_music, program_data.Warning, cb, run_type).catch(function(err: any) {
runPythonProgram(program_data.Code, program_data.source_map, program_data.has_turtle, program_data.has_pressed, program_data.has_sleep, program_data.has_clear, program_data.has_music, program_data.Warning, program_data.is_modified ,cb, run_type).catch(function(err: any) {
// The err is null if we don't understand it -> don't show anything
if (err != null) {
error.show(ClientMessages['Execute_error'], err.message);
Expand Down Expand Up @@ -720,12 +722,65 @@ export function viewProgramLink(programId: string) {
return window.location.origin + '/hedy/' + programId + '/view';
}

function updateProgramCount() {
const programCountDiv = $('#program_count');
const countText = programCountDiv.text();
const regex = /(\d+)/;
const match = countText.match(regex);

if (match && match.length > 0) {
const currentCount = parseInt(match[0]);
const newCount = currentCount - 1;
const newText = countText.replace(regex, newCount.toString());
programCountDiv.text(newText);
}
}

function updateSelectOptions(selectName: string) {
let optionsArray: string[] = [];
const select = $(`select[name='${selectName}']`);

// grabs all the levels and names from the remaining adventures
$(`[id="program_${selectName}"]`).each(function() {
const text = $(this).text().trim();
if (selectName == 'level'){
const number = text.match(/\d+/)
if (number && !optionsArray.includes(number[0])) {
optionsArray.push(number[0]);
}
} else if (!optionsArray.includes(text)){
optionsArray.push(text);
}
console.log(optionsArray);
});

if (selectName == 'level'){
optionsArray.sort();
}
// grabs the -- level -- or -- adventure -- from the options
const firstOption = select.find('option:first').text().trim();
optionsArray.unshift(firstOption);

select.empty();
optionsArray.forEach(optionText => {
const option = $('<option></option>').text(optionText);
select.append(option);
});
}

export async function delete_program(id: string, prompt: string) {
await modal.confirmP(prompt);
await tryCatchPopup(async () => {
$('#program_' + id).remove();
// only shows the remaining levels and programs in the options
updateSelectOptions('level');
updateSelectOptions('adventure');
// this function decreases the total programs saved
updateProgramCount();
const response = await postJsonWithAchievements('/programs/delete', { id });
showAchievements(response.achievement, true, "");
$('#program_' + id).remove();
// issue request on the Bar component.
console.log("resp", response)
modal.notifySuccess(response.message);
});
}
Expand Down Expand Up @@ -853,7 +908,7 @@ window.onerror = function reportClientException(message, source, line_number, co
});
}

export function runPythonProgram(this: any, code: string, sourceMap: any, hasTurtle: boolean, hasPressed: boolean, hasSleep: number[], hasClear: boolean, hasMusic: boolean, hasWarnings: boolean, cb: () => void, run_type: "run" | "debug" | "continue") {
export function runPythonProgram(this: any, code: string, sourceMap: any, hasTurtle: boolean, hasPressed: boolean, hasSleep: number[], hasClear: boolean, hasMusic: boolean, hasWarnings: boolean, isModified: boolean, cb: () => void, run_type: "run" | "debug" | "continue") {
// If we are in the Parsons problem -> use a different output
let outputDiv = $('#output');
let skip_faulty_found_errors = false;
Expand Down Expand Up @@ -1048,7 +1103,7 @@ export function runPythonProgram(this: any, code: string, sourceMap: any, hasTur
return;
}
if (!hasWarnings && code !== last_code) {
showSuccesMessage(); //FH nov 2023: typo in success :)
showSuccessMessage(isModified);
last_code = code;
}
if (cb) cb ();
Expand Down Expand Up @@ -1430,11 +1485,11 @@ export function modalStepOne(level: number){
}
}

function showSuccesMessage(){
function showSuccessMessage(isModified: boolean){
removeBulb();
var allsuccessmessages = ClientMessages['Transpile_success'].split('\n');
var randomnum: number = Math.floor(Math.random() * allsuccessmessages.length);
success.show(allsuccessmessages[randomnum]);
success.show(allsuccessmessages[randomnum], isModified);
}

function createModal(level:number ){
Expand Down Expand Up @@ -1970,6 +2025,7 @@ async function saveIfNecessary() {
program_id: saveInfo?.id,
// We pass 'public' in here to save the backend a lookup
share: saveInfo?.public,
short_name: adventure.short_name,
});

// Record that we saved successfully
Expand Down
66 changes: 57 additions & 9 deletions static/js/appbundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -56937,7 +56937,10 @@ ${i2}` : o2;
$("#okbox .details").text(message);
$("#okbox").show();
},
show(caption) {
show(caption, confetti) {
if (confetti) {
$("#confetti-button").show();
}
$("#okbox .caption").text(caption);
$("#okbox").show();
setTimeout(function() {
Expand Down Expand Up @@ -99100,7 +99103,8 @@ def note_with_error(value, err):
if (dir === "rtl") {
symbol = "\u21E4";
}
$("<button>").css({ fontFamily: "sans-serif" }).addClass("yellow-btn").text(symbol).appendTo(buttonContainer).click(function() {
const adventure = container.getAttribute("data-tabtarget");
$("<button>").css({ fontFamily: "sans-serif" }).addClass("yellow-btn").attr("data-cy", `paste-example-code-${adventure}`).text(symbol).appendTo(buttonContainer).click(function() {
if (!(theGlobalEditor == null ? void 0 : theGlobalEditor.isReadOnly)) {
theGlobalEditor.contents = exampleEditor.contents + "\n";
}
Expand Down Expand Up @@ -99207,6 +99211,7 @@ def note_with_error(value, err):
tutorial: $("#code_output").hasClass("z-40"),
read_aloud: !!$("#speak_dropdown").val(),
adventure_name: adventureName,
short_name: adventure ? adventure.short_name : void 0,
raw,
program_id: isServerSaveInfo(adventure == null ? void 0 : adventure.save_info) ? adventure.save_info.id : void 0,
save_name: saveNameFromInput()
Expand Down Expand Up @@ -99242,7 +99247,7 @@ def note_with_error(value, err):
} else {
program_data = theGlobalDebugger.get_program_data();
}
runPythonProgram(program_data.Code, program_data.source_map, program_data.has_turtle, program_data.has_pressed, program_data.has_sleep, program_data.has_clear, program_data.has_music, program_data.Warning, cb2, run_type).catch(function(err) {
runPythonProgram(program_data.Code, program_data.source_map, program_data.has_turtle, program_data.has_pressed, program_data.has_sleep, program_data.has_clear, program_data.has_music, program_data.Warning, program_data.is_modified, cb2, run_type).catch(function(err) {
if (err != null) {
error.show(ClientMessages["Execute_error"], err.message);
reportClientError(level3, code, err.message);
Expand Down Expand Up @@ -99352,12 +99357,54 @@ def note_with_error(value, err):
function viewProgramLink(programId) {
return window.location.origin + "/hedy/" + programId + "/view";
}
function updateProgramCount() {
const programCountDiv = $("#program_count");
const countText = programCountDiv.text();
const regex = /(\d+)/;
const match = countText.match(regex);
if (match && match.length > 0) {
const currentCount = parseInt(match[0]);
const newCount = currentCount - 1;
const newText = countText.replace(regex, newCount.toString());
programCountDiv.text(newText);
}
}
function updateSelectOptions(selectName) {
let optionsArray = [];
const select = $(`select[name='${selectName}']`);
$(`[id="program_${selectName}"]`).each(function() {
const text = $(this).text().trim();
if (selectName == "level") {
const number2 = text.match(/\d+/);
if (number2 && !optionsArray.includes(number2[0])) {
optionsArray.push(number2[0]);
}
} else if (!optionsArray.includes(text)) {
optionsArray.push(text);
}
console.log(optionsArray);
});
if (selectName == "level") {
optionsArray.sort();
}
const firstOption = select.find("option:first").text().trim();
optionsArray.unshift(firstOption);
select.empty();
optionsArray.forEach((optionText) => {
const option2 = $("<option></option>").text(optionText);
select.append(option2);
});
}
async function delete_program(id2, prompt) {
await modal.confirmP(prompt);
await tryCatchPopup(async () => {
$("#program_" + id2).remove();
updateSelectOptions("level");
updateSelectOptions("adventure");
updateProgramCount();
const response = await postJsonWithAchievements("/programs/delete", { id: id2 });
showAchievements(response.achievement, true, "");
$("#program_" + id2).remove();
console.log("resp", response);
modal.notifySuccess(response.message);
});
}
Expand Down Expand Up @@ -99462,7 +99509,7 @@ def note_with_error(value, err):
user_agent: navigator.userAgent
});
};
function runPythonProgram(code, sourceMap, hasTurtle, hasPressed, hasSleep, hasClear, hasMusic, hasWarnings, cb2, run_type) {
function runPythonProgram(code, sourceMap, hasTurtle, hasPressed, hasSleep, hasClear, hasMusic, hasWarnings, isModified, cb2, run_type) {
let outputDiv = $("#output");
let skip_faulty_found_errors = false;
let warning_box_shown = false;
Expand Down Expand Up @@ -99611,7 +99658,7 @@ def note_with_error(value, err):
return;
}
if (!hasWarnings && code !== last_code) {
showSuccesMessage();
showSuccessMessage(isModified);
last_code = code;
}
if (cb2)
Expand Down Expand Up @@ -99897,11 +99944,11 @@ def note_with_error(value, err):
theModalEditor = editorCreator2.initializeEditorWithGutter($modalEditor, EditorType.MODAL, dir);
}
}
function showSuccesMessage() {
function showSuccessMessage(isModified) {
removeBulb();
var allsuccessmessages = ClientMessages["Transpile_success"].split("\n");
var randomnum = Math.floor(Math.random() * allsuccessmessages.length);
success.show(allsuccessmessages[randomnum]);
success.show(allsuccessmessages[randomnum], isModified);
}
function createModal(level3) {
let editor = `<div id='modal-editor' class="w-full flex-1 text-lg rounded" style='height:200px; width:50vw;'></div>`.replace("{level}", level3.toString());
Expand Down Expand Up @@ -100294,7 +100341,8 @@ def note_with_error(value, err):
code,
adventure_name: adventureName,
program_id: saveInfo == null ? void 0 : saveInfo.id,
share: saveInfo == null ? void 0 : saveInfo.public
share: saveInfo == null ? void 0 : saveInfo.public,
short_name: adventure.short_name
});
adventure.editor_contents = code;
if (response.save_info) {
Expand Down
4 changes: 2 additions & 2 deletions static/js/appbundle.js.map

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion static/js/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,10 @@ export const success = {
$('#okbox').show();
},

show(caption: string) {
show(caption: string, confetti: boolean) {
if (confetti){
$('#confetti-button').show();
}
$('#okbox .caption').text(caption);
$('#okbox').show();
setTimeout(function() {
Expand Down
Loading
Loading