This commit is contained in:
Bryce
2025-08-06 21:30:33 -07:00
parent 3387867561
commit d021f045ae
14 changed files with 426 additions and 375 deletions

View File

@@ -16,7 +16,8 @@ def index():
folders = Folder.query.filter_by(user_id=current_user.id).all()
return render_template('index.html',
folders=folders)
folders=folders,
show_hidden=False)
@main.route('/api/folders/new', methods=['GET'])
@login_required
@@ -62,12 +63,17 @@ def add_folder():
# Default to 'destination' type for manually created folders
folder_type = 'tidy' if name.strip().lower() == 'inbox' else 'destination'
# If folder_type is 'ignore', reset emails_count to 0
if folder_type == 'ignore':
emails_count = 0
folder = Folder(
user_id=current_user.id,
name=name.strip(),
rule_text=rule_text.strip(),
priority=int(priority) if priority else 0,
folder_type=folder_type
folder_type=folder_type,
emails_count=0 if folder_type == 'ignore' else None
)
db.session.add(folder)
@@ -78,7 +84,7 @@ def add_folder():
response = make_response(render_template('partials/folders_list.html', folders=folders))
response.headers['HX-Trigger'] = 'close-modal'
response.headers["HX-Target"] = 'folder-list'
response.headers["HX-Target"] = '#folders-list'
response.status_code = 201
return response
@@ -126,9 +132,9 @@ def delete_folder(folder_id):
# Return both sections
return render_template('partials/folders_list.html', folders=folders)
@main.route('/api/folders/<folder_id>/toggle', methods=['PUT'])
@main.route('/api/folders/<folder_id>/type', methods=['PUT'])
@login_required
def toggle_folder_organize(folder_id):
def update_folder_type(folder_id):
try:
# Find the folder by ID and ensure it belongs to the current user
folder = Folder.query.filter_by(id=folder_id, user_id=current_user.id).first()
@@ -136,21 +142,30 @@ def toggle_folder_organize(folder_id):
if not folder:
return jsonify({'error': 'Folder not found'}), 404
# Toggle the organize_enabled flag
folder.organize_enabled = not folder.organize_enabled
# Get the new folder type from form data
new_folder_type = request.form.get('folder_type')
# Validate the folder type
if new_folder_type not in ['tidy', 'destination', 'ignore']:
return jsonify({'error': 'Invalid folder type'}), 400
# If changing to 'ignore', reset the emails_count to 0
if new_folder_type == 'ignore' and folder.folder_type != 'ignore':
folder.emails_count = 0
# Update the folder type
folder.folder_type = new_folder_type
db.session.commit()
# Return just the updated folder card HTML for this specific folder
# Use the appropriate template based on folder type
if folder.folder_type == 'tidy':
return render_template('partials/folder_card_tidy.html', folder=folder)
else:
return render_template('partials/folder_card_destination.html', folder=folder)
# Get updated list of folders for the current user
folders = Folder.query.filter_by(user_id=current_user.id).all()
return render_template('partials/folders_list.html', folders=folders)
except Exception as e:
# Print unhandled exceptions to the console as required
logging.exception("Error toggling folder organize flag: %s", e)
logging.exception("Error updating folder type: %s", e)
db.session.rollback()
return jsonify({'error': 'An unexpected error occurred'}), 500
@@ -219,11 +234,13 @@ def update_folder(folder_id):
folder.rule_text = rule_text.strip()
folder.priority = int(priority) if priority else 0
# Update folder type if the name changed to/from 'inbox'
if name.strip().lower() == 'inbox' and folder.folder_type != 'tidy':
folder.folder_type = 'tidy'
elif name.strip().lower() != 'inbox' and folder.folder_type != 'destination':
folder.folder_type = 'destination'
# Check if folder type is being changed to 'ignore'
old_folder_type = folder.folder_type
folder.folder_type = 'tidy' if name.strip().lower() == 'inbox' else 'destination'
# If changing to 'ignore', reset emails_count to 0
if folder.folder_type == 'ignore' and old_folder_type != 'ignore':
folder.emails_count = 0
db.session.commit()
@@ -373,6 +390,9 @@ def sync_imap_folders():
synced_count = 0
processed_emails_service = ProcessedEmailsService(current_user)
# Create a list of folders to process
folders_to_process = []
for imap_folder in unique_folders:
folder_name = imap_folder['name'].strip()
@@ -400,6 +420,7 @@ def sync_imap_folders():
)
db.session.add(new_folder)
synced_count += 1
folders_to_process.append(new_folder)
else:
# Update existing folder with email counts and recent emails
# Get all email UIDs in this folder
@@ -417,13 +438,22 @@ def sync_imap_folders():
# Get the most recent emails for this folder
recent_emails = imap_service.get_recent_emails(folder_name, 3)
existing_folder.recent_emails = recent_emails
folders_to_process.append(existing_folder)
db.session.commit()
# Get updated list of folders
folders = Folder.query.filter_by(user_id=current_user.id).all()
return render_template('partials/folders_list.html', folders=folders)
# Check if we should show the folder type selection modal
# Only show the modal if there are new folders to configure
if synced_count > 0:
# Return the folder type selection modal
response = make_response(render_template('partials/folder_type_selection_modal.html', folders=folders_to_process))
response.headers['HX-Trigger'] = 'open-modal'
return response
else:
# Just return the updated folders list
folders = Folder.query.filter_by(user_id=current_user.id).all()
return render_template('partials/folders_list.html', folders=folders)
except Exception as e:
logging.exception("Error syncing IMAP folders: %s", e)
@@ -438,6 +468,7 @@ def get_folders():
# Get filter parameter from query string
filter_type = request.args.get('filter', 'all')
folder_type = request.args.get('type', None)
show_hidden = request.args.get('show_hidden', 'off').lower() == 'on'
# Get folders for the current authenticated user
if folder_type:
@@ -454,15 +485,26 @@ def get_folders():
folders = Folder.query.filter_by(user_id=current_user.id).all()
if folder_type == 'tidy':
response = make_response(render_template('partials/folders_to_tidy_section.html', folders=folders))
response["HX-Retarget"] = "#folders-to-tidy"
response = make_response(render_template('partials/folders_to_tidy_section.html', folders=folders, show_hidden=show_hidden))
response.headers["HX-Retarget"] = "#folders-to-tidy"
return response
elif folder_type == 'destination':
response = make_response(render_template('partials/destination_folders_section.html', folders=folders))
response["HX-Retarget"] = "#destination-folders"
response = make_response(render_template('partials/destination_folders_section.html', folders=folders, show_hidden=show_hidden))
response.headers["HX-Retarget"] = "#destination-folders"
return response
elif folder_type == 'ignore':
response = make_response(render_template('partials/hidden_folders_section.html', folders=folders, show_hidden=show_hidden))
response.headers["HX-Retarget"] = "#hidden-folders"
# Show or hide the hidden folders section based on the show_hidden parameter
if show_hidden:
response.headers['HX-Trigger'] = 'show-hidden'
else:
response.headers['HX-Trigger'] = 'hide-hidden'
return response
else:
return render_template('partials/folders_list.html', folders=folders)
return render_template('partials/folders_list.html', folders=folders, show_hidden=show_hidden)
# Processed Emails API Endpoints