Compare commits

..

No commits in common. "b1eb1676aa95d776ff9085002641ad62e040cd93" and "d17a848fe275c3e8734a4dfcaf2eae8ca0dc361c" have entirely different histories.

41 changed files with 679 additions and 771 deletions

View File

@ -2,15 +2,7 @@
if [ ! -d /data/git/.ssh ]; then if [ ! -d /data/git/.ssh ]; then
mkdir -p /data/git/.ssh mkdir -p /data/git/.ssh
fi chmod 700 /data/git/.ssh
# Set the correct permissions on the .ssh directory and authorized_keys file,
# or sshd will refuse to use them and lead to clone/push/pull failures.
# It could happen when users have copied their data to a new volume and changed the file permission by accident,
# and it would be very hard to troubleshoot unless users know how to check the logs of sshd which is started by s6.
chmod 700 /data/git/.ssh
if [ -f /data/git/.ssh/authorized_keys ]; then
chmod 600 /data/git/.ssh/authorized_keys
fi fi
if [ ! -f /data/git/.ssh/environment ]; then if [ ! -f /data/git/.ssh/environment ]; then

View File

@ -532,6 +532,27 @@ func GetOrgsCanCreateRepoByUserID(userID int64) ([]*Organization, error) {
Find(&orgs) Find(&orgs)
} }
// GetOrgUsersByUserID returns all organization-user relations by user ID.
func GetOrgUsersByUserID(uid int64, opts *SearchOrganizationsOptions) ([]*OrgUser, error) {
ous := make([]*OrgUser, 0, 10)
sess := db.GetEngine(db.DefaultContext).
Join("LEFT", "`user`", "`org_user`.org_id=`user`.id").
Where("`org_user`.uid=?", uid)
if !opts.All {
// Only show public organizations
sess.And("is_public=?", true)
}
if opts.PageSize != 0 {
sess = db.SetSessionPagination(sess, opts)
}
err := sess.
Asc("`user`.name").
Find(&ous)
return ous, err
}
// GetOrgUsersByOrgID returns all organization-user relations by organization ID. // GetOrgUsersByOrgID returns all organization-user relations by organization ID.
func GetOrgUsersByOrgID(ctx context.Context, opts *FindOrgMembersOpts) ([]*OrgUser, error) { func GetOrgUsersByOrgID(ctx context.Context, opts *FindOrgMembersOpts) ([]*OrgUser, error) {
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID) sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)

View File

@ -207,6 +207,42 @@ func TestFindOrgs(t *testing.T) {
assert.EqualValues(t, 1, total) assert.EqualValues(t, 1, total)
} }
func TestGetOrgUsersByUserID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
orgUsers, err := organization.GetOrgUsersByUserID(5, &organization.SearchOrganizationsOptions{All: true})
assert.NoError(t, err)
if assert.Len(t, orgUsers, 3) {
assert.Equal(t, organization.OrgUser{
ID: orgUsers[0].ID,
OrgID: 23,
UID: 5,
IsPublic: false,
}, *orgUsers[0])
assert.Equal(t, organization.OrgUser{
ID: orgUsers[1].ID,
OrgID: 6,
UID: 5,
IsPublic: true,
}, *orgUsers[1])
assert.Equal(t, organization.OrgUser{
ID: orgUsers[2].ID,
OrgID: 7,
UID: 5,
IsPublic: false,
}, *orgUsers[2])
}
publicOrgUsers, err := organization.GetOrgUsersByUserID(5, &organization.SearchOrganizationsOptions{All: false})
assert.NoError(t, err)
assert.Len(t, publicOrgUsers, 1)
assert.Equal(t, *orgUsers[1], *publicOrgUsers[0])
orgUsers, err = organization.GetOrgUsersByUserID(1, &organization.SearchOrganizationsOptions{All: true})
assert.NoError(t, err)
assert.Len(t, orgUsers, 0)
}
func TestGetOrgUsersByOrgID(t *testing.T) { func TestGetOrgUsersByOrgID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())

View File

@ -336,7 +336,7 @@ func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListO
// GetUserFollowing returns range of user's following. // GetUserFollowing returns range of user's following.
func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) { func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) {
sess := db.GetEngine(ctx). sess := db.GetEngine(db.DefaultContext).
Select("`user`.*"). Select("`user`.*").
Join("LEFT", "follow", "`user`.id=follow.follow_id"). Join("LEFT", "follow", "`user`.id=follow.follow_id").
Where("follow.user_id=?", u.ID). Where("follow.user_id=?", u.ID).

View File

@ -161,6 +161,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
} }
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
ctx.Data["IsProjectEnabled"] = true
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["IsPublicMember"] = func(uid int64) bool { ctx.Data["IsPublicMember"] = func(uid int64) bool {

View File

@ -31,8 +31,8 @@ func garbageCollectLFSCheck(ctx context.Context, logger log.Logger, autofix bool
} }
if err := repository.GarbageCollectLFSMetaObjects(ctx, repository.GarbageCollectLFSMetaObjectsOptions{ if err := repository.GarbageCollectLFSMetaObjects(ctx, repository.GarbageCollectLFSMetaObjectsOptions{
LogDetail: logger.Info, Logger: logger,
AutoFix: autofix, AutoFix: autofix,
// Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload // Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload
// and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby // and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby
// an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid // an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid

View File

@ -188,6 +188,7 @@ func InitFull(ctx context.Context) (err error) {
if CheckGitVersionAtLeast("2.9") == nil { if CheckGitVersionAtLeast("2.9") == nil {
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=") globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
} }
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
if setting.LFS.StartServer { if setting.LFS.StartServer {

View File

@ -79,8 +79,6 @@ milestones=Ορόσημα
ok=OK ok=OK
cancel=Ακύρωση cancel=Ακύρωση
rerun=Επανεκτέλεση
rerun_all=Επανεκτέλεση όλων
save=Αποθήκευση save=Αποθήκευση
add=Προσθήκη add=Προσθήκη
add_all=Προσθήκη Όλων add_all=Προσθήκη Όλων
@ -115,19 +113,11 @@ unknown=Άγνωστη
rss_feed=Ροή RSS rss_feed=Ροή RSS
pin=Στήριξη
unpin=Άφεση
artifacts=Αντικείμενα
concept_system_global=Γενικό
concept_user_individual=Ατομικό
concept_code_repository=Αποθετήριο concept_code_repository=Αποθετήριο
concept_user_organization=Οργανισμός concept_user_organization=Οργανισμός
show_timestamps=Εμφάνιση χρονοσημάνσεων
show_log_seconds=Εμφάνιση δευτερολέπτων
show_full_screen=Εμφάνιση πλήρους οθόνης
[aria] [aria]
navbar=Γραμμή Πλοήγησης navbar=Γραμμή Πλοήγησης
@ -324,7 +314,6 @@ repos=Αποθετήρια
users=Χρήστες users=Χρήστες
organizations=Οργανισμοί organizations=Οργανισμοί
search=Αναζήτηση search=Αναζήτηση
go_to=Μετάβαση σε
code=Κώδικας code=Κώδικας
search.type.tooltip=Τύπος αναζήτησης search.type.tooltip=Τύπος αναζήτησης
search.fuzzy=Fuzzy search.fuzzy=Fuzzy
@ -528,7 +517,6 @@ lang_select_error=Επιλέξτε μια γλώσσα από τη λίστα.
username_been_taken=Το όνομα χρήστη χρησιμοποιείται ήδη. username_been_taken=Το όνομα χρήστη χρησιμοποιείται ήδη.
username_change_not_local_user=Δεν επιτρέπεται στους μη τοπικούς χρήστες να αλλάξουν το όνομα χρήστη τους. username_change_not_local_user=Δεν επιτρέπεται στους μη τοπικούς χρήστες να αλλάξουν το όνομα χρήστη τους.
username_has_not_been_changed=Το όνομα χρήστη δεν άλλαξε
repo_name_been_taken=Το όνομα του αποθετηρίου χρησιμοποιείται ήδη. repo_name_been_taken=Το όνομα του αποθετηρίου χρησιμοποιείται ήδη.
repository_force_private=Η επιλογή Μόνο Ιδιωτικά είναι ενεργοποιημένη: τα ιδιωτικά αποθετήρια δεν μπορούν να δημοσιευθούν. repository_force_private=Η επιλογή Μόνο Ιδιωτικά είναι ενεργοποιημένη: τα ιδιωτικά αποθετήρια δεν μπορούν να δημοσιευθούν.
repository_files_already_exist=Αρχεία υπάρχουν ήδη για αυτό το αποθετήριο. Επικοινωνήστε με το διαχειριστή του συστήματος. repository_files_already_exist=Αρχεία υπάρχουν ήδη για αυτό το αποθετήριο. Επικοινωνήστε με το διαχειριστή του συστήματος.
@ -577,7 +565,6 @@ target_branch_not_exist=Ο κλάδος προορισμού δεν υπάρχε
[user] [user]
change_avatar=Αλλαγή του avatar σας… change_avatar=Αλλαγή του avatar σας…
joined_on=Εγγράφηκε την %s
repositories=Αποθετήρια repositories=Αποθετήρια
activity=Δημόσια Δραστηριότητα activity=Δημόσια Δραστηριότητα
followers=Ακόλουθοι followers=Ακόλουθοι
@ -773,8 +760,6 @@ ssh_principal_deletion_desc=Η διαγραφή μιας αρχής πιστοπ
ssh_key_deletion_success=Το SSH κλειδί έχει διαγραφεί. ssh_key_deletion_success=Το SSH κλειδί έχει διαγραφεί.
gpg_key_deletion_success=Το κλειδί GPG έχει διαγραφεί. gpg_key_deletion_success=Το κλειδί GPG έχει διαγραφεί.
ssh_principal_deletion_success=Η αρχή πιστοποιητικού έχει διαγραφεί. ssh_principal_deletion_success=Η αρχή πιστοποιητικού έχει διαγραφεί.
added_on=Προστέθηκαν στις %s
valid_until_date=Έγκυρο μέχρι τη %s
valid_forever=Έγκυρο για πάντα valid_forever=Έγκυρο για πάντα
last_used=Τελευταία χρήση στις last_used=Τελευταία χρήση στις
no_activity=Καμία πρόσφατη δραστηριότητα no_activity=Καμία πρόσφατη δραστηριότητα
@ -806,13 +791,6 @@ access_token_deletion_cancel_action=Άκυρο
access_token_deletion_confirm_action=Διαγραφή access_token_deletion_confirm_action=Διαγραφή
access_token_deletion_desc=Η διαγραφή ενός διακριτικού θα ανακαλέσει οριστικά την πρόσβαση στο λογαριασμό σας για εφαρμογές που το χρησιμοποιούν. Συνέχεια; access_token_deletion_desc=Η διαγραφή ενός διακριτικού θα ανακαλέσει οριστικά την πρόσβαση στο λογαριασμό σας για εφαρμογές που το χρησιμοποιούν. Συνέχεια;
delete_token_success=Το διακριτικό έχει διαγραφεί. Οι εφαρμογές που το χρησιμοποιούν δεν έχουν πλέον πρόσβαση στο λογαριασμό σας. delete_token_success=Το διακριτικό έχει διαγραφεί. Οι εφαρμογές που το χρησιμοποιούν δεν έχουν πλέον πρόσβαση στο λογαριασμό σας.
repo_and_org_access=Πρόσβαση στο Αποθετήριο και Οργανισμό
permissions_public_only=Δημόσια μόνο
permissions_access_all=Όλα (δημόσια, ιδιωτικά, και περιορισμένα)
select_permissions=Επιλέξτε δικαιώματα
scoped_token_desc=Το επιλεγμένο διακριτικό περιορίζει την ταυτοποίηση μόνο στις αντίστοιχες διαδρομές <a %s>API</a>. Συμβουλευτείτε την τεκμηρίωση <a %s></a> για περισσότερες πληροφορίες.
at_least_one_permission=Πρέπει να επιλέξετε τουλάχιστον ένα δικαίωμα για να δημιουργήσετε ένα διακριτικό
permissions_list=Δικαιώματα:
manage_oauth2_applications=Διαχείριση Εφαρμογών Oauth2 manage_oauth2_applications=Διαχείριση Εφαρμογών Oauth2
edit_oauth2_application=Επεξεργασία Εφαρμογής Oauth2 edit_oauth2_application=Επεξεργασία Εφαρμογής Oauth2
@ -826,7 +804,6 @@ create_oauth2_application_success=Δημιουργήσατε επιτυχώς μ
update_oauth2_application_success=Ενημερώσατε επιτυχώς την εφαρμογή OAuth2. update_oauth2_application_success=Ενημερώσατε επιτυχώς την εφαρμογή OAuth2.
oauth2_application_name=Όνομα Εφαρμογής oauth2_application_name=Όνομα Εφαρμογής
oauth2_confidential_client=Εμπιστευτικός Πελάτης. Επιλέξτε το για εφαρμογές που διατηρούν το μυστικό κωδικό κρυφό, όπως πχ οι εφαρμογές ιστού. Μην επιλέγετε για εγγενείς εφαρμογές, συμπεριλαμβανομένων εφαρμογών επιφάνειας εργασίας και εφαρμογών για κινητά. oauth2_confidential_client=Εμπιστευτικός Πελάτης. Επιλέξτε το για εφαρμογές που διατηρούν το μυστικό κωδικό κρυφό, όπως πχ οι εφαρμογές ιστού. Μην επιλέγετε για εγγενείς εφαρμογές, συμπεριλαμβανομένων εφαρμογών επιφάνειας εργασίας και εφαρμογών για κινητά.
oauth2_redirect_uris=URI Ανακατεύθυνσης. Χρησιμοποιήστε μια νέα γραμμή για κάθε URI.
save_application=Αποθήκευση save_application=Αποθήκευση
oauth2_client_id=Ταυτότητα Πελάτη oauth2_client_id=Ταυτότητα Πελάτη
oauth2_client_secret=Μυστικό Πελάτη oauth2_client_secret=Μυστικό Πελάτη
@ -972,7 +949,6 @@ mirror_password_blank_placeholder=(Μη ορισμένο)
mirror_password_help=Αλλάξτε το όνομα χρήστη για να διαγράψετε έναν αποθηκευμένο κωδικό πρόσβασης. mirror_password_help=Αλλάξτε το όνομα χρήστη για να διαγράψετε έναν αποθηκευμένο κωδικό πρόσβασης.
watchers=Παρατηρητές watchers=Παρατηρητές
stargazers=Θαυμαστές stargazers=Θαυμαστές
stars_remove_warning=Αυτό θα αφαιρέσει όλα τα αστέρια από αυτό το αποθετήριο.
forks=Forks forks=Forks
reactions_more=και %d περισσότερα reactions_more=και %d περισσότερα
unit_disabled=Ο διαχειριστής του ιστότοπου έχει απενεργοποιήσει αυτήν την ενότητα αποθετηρίου. unit_disabled=Ο διαχειριστής του ιστότοπου έχει απενεργοποιήσει αυτήν την ενότητα αποθετηρίου.
@ -1016,7 +992,6 @@ template.one_item=Πρέπει να επιλέξετε τουλάχιστον έ
template.invalid=Πρέπει να επιλέξετε ένα πρότυπο αποθετήριο template.invalid=Πρέπει να επιλέξετε ένα πρότυπο αποθετήριο
archive.title=Αυτό το αποθετήριο αρχειοθετήθηκε. Μπορείτε να δείτε αρχεία και να το κλωνοποιήσετε, αλλά δεν μπορείτε να γράψετε ή να ανοίξετε ζητήματα/pull-requests. archive.title=Αυτό το αποθετήριο αρχειοθετήθηκε. Μπορείτε να δείτε αρχεία και να το κλωνοποιήσετε, αλλά δεν μπορείτε να γράψετε ή να ανοίξετε ζητήματα/pull-requests.
archive.title_date=Αυτό το αποθετήριο έχει αρχειοθετηθεί τη %s. Μπορείτε να προβάλετε αρχεία και να κλωνοποιήσετε, αλλά δεν μπορείτε να ωθήσετε ή να ανοίξετε ζητήματα και pull-requests.
archive.issue.nocomment=Αυτό το αποθετήριο αρχειοθετήθηκε. Δεν μπορείτε να σχολιάσετε σε ζητήματα. archive.issue.nocomment=Αυτό το αποθετήριο αρχειοθετήθηκε. Δεν μπορείτε να σχολιάσετε σε ζητήματα.
archive.pull.nocomment=Αυτό το repo αρχειοθετήθηκε. Δεν μπορείτε να σχολιάσετε στα pull requests. archive.pull.nocomment=Αυτό το repo αρχειοθετήθηκε. Δεν μπορείτε να σχολιάσετε στα pull requests.
@ -1058,7 +1033,6 @@ migrated_from_fake=Μεταφέρθηκε από %[1]s
migrate.migrate=Μεταφορά Από %s migrate.migrate=Μεταφορά Από %s
migrate.migrating=Γίνεται μεταφορά από <b>%s</b>... migrate.migrating=Γίνεται μεταφορά από <b>%s</b>...
migrate.migrating_failed=Η μετεγρατάσταση από <b>%s</b> απέτυχε. migrate.migrating_failed=Η μετεγρατάσταση από <b>%s</b> απέτυχε.
migrate.migrating_failed.error=Αποτυχία μεταφοράς: %s
migrate.migrating_failed_no_addr=Η μεταφορά απέτυχε. migrate.migrating_failed_no_addr=Η μεταφορά απέτυχε.
migrate.github.description=Μεταφορά δεδομένων από το github.com ή άλλους διακομιστές GitHub. migrate.github.description=Μεταφορά δεδομένων από το github.com ή άλλους διακομιστές GitHub.
migrate.git.description=Μεταφορά μόνο του αποθετηρίου από μια οποιαδήποτε υπηρεσία Git. migrate.git.description=Μεταφορά μόνο του αποθετηρίου από μια οποιαδήποτε υπηρεσία Git.
@ -1075,8 +1049,6 @@ migrate.migrating_labels=Μεταφορά Σημάτων
migrate.migrating_releases=Μεταφορά Κυκλοφοριών migrate.migrating_releases=Μεταφορά Κυκλοφοριών
migrate.migrating_issues=Μετανάστευση Θεμάτων migrate.migrating_issues=Μετανάστευση Θεμάτων
migrate.migrating_pulls=Μεταφορά Pull Requests migrate.migrating_pulls=Μεταφορά Pull Requests
migrate.cancel_migrating_title=Ακύρωση Μεταφοράς
migrate.cancel_migrating_confirm=Θέλετε να ακυρώσετε αυτή τη μεταφορά;
mirror_from=είδωλο του mirror_from=είδωλο του
forked_from=forked από forked_from=forked από
@ -1206,8 +1178,6 @@ editor.filename_is_invalid=Το όνομα αρχείου δεν είναι έγ
editor.branch_does_not_exist=Ο κλάδος "%s" δεν υπάρχει σε αυτό το αποθετήριο. editor.branch_does_not_exist=Ο κλάδος "%s" δεν υπάρχει σε αυτό το αποθετήριο.
editor.branch_already_exists=Ο κλάδος "%s" υπάρχει ήδη σε αυτό το αποθετήριο. editor.branch_already_exists=Ο κλάδος "%s" υπάρχει ήδη σε αυτό το αποθετήριο.
editor.directory_is_a_file=Το όνομα φακέλου "%s" χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το αποθετήριο. editor.directory_is_a_file=Το όνομα φακέλου "%s" χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το αποθετήριο.
editor.file_is_a_symlink=`Το "%s" είναι συμβολικός σύνδεσμος. Οι συμβολικοί σύνδεσμοι δεν μπορούν να επεξεργαστούν στην ενσωματωμένη εφαρμογή`
editor.filename_is_a_directory=Το όνομα αρχείου "%s" χρησιμοποιείται ήδη ως όνομα φακέλου σε αυτό το αποθετήριο.
editor.file_editing_no_longer_exists=Το αρχείο "%s" που επεξεργάζεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο. editor.file_editing_no_longer_exists=Το αρχείο "%s" που επεξεργάζεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
editor.file_deleting_no_longer_exists=Το αρχείο "%s" που διαγράφεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο. editor.file_deleting_no_longer_exists=Το αρχείο "%s" που διαγράφεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
editor.file_changed_while_editing=Τα περιεχόμενα του αρχείου άλλαξαν από τότε που ξεκίνησε η επεξεργασία. <a target="_blank" rel="noopener noreferrer" href="%s">Κάντε κλικ εδώ</a> για να τα δείτε ή <strong>Υποβολή Αλλαγών ξανά</strong> για να τα αντικαταστήσετε. editor.file_changed_while_editing=Τα περιεχόμενα του αρχείου άλλαξαν από τότε που ξεκίνησε η επεξεργασία. <a target="_blank" rel="noopener noreferrer" href="%s">Κάντε κλικ εδώ</a> για να τα δείτε ή <strong>Υποβολή Αλλαγών ξανά</strong> για να τα αντικαταστήσετε.
@ -1373,10 +1343,6 @@ issues.filter_label_exclude=`Χρησιμοποιήστε <code>alt</code> + <co
issues.filter_label_no_select=Όλα τα σήματα issues.filter_label_no_select=Όλα τα σήματα
issues.filter_label_select_no_label=Χωρίς Σήμα issues.filter_label_select_no_label=Χωρίς Σήμα
issues.filter_milestone=Ορόσημο issues.filter_milestone=Ορόσημο
issues.filter_milestone_all=Όλα τα ορόσημα
issues.filter_milestone_none=Χωρίς ορόσημα
issues.filter_milestone_open=Ανοιχτά ορόσημα
issues.filter_milestone_closed=Κλειστά ορόσημα
issues.filter_project=Έργο issues.filter_project=Έργο
issues.filter_project_all=Όλα τα έργα issues.filter_project_all=Όλα τα έργα
issues.filter_project_none=Χωρίς έργα issues.filter_project_none=Χωρίς έργα
@ -1436,8 +1402,6 @@ issues.context.edit=Επεξεργασία
issues.context.delete=Διαγραφή issues.context.delete=Διαγραφή
issues.no_content=Δεν υπάρχει ακόμα περιεχόμενο. issues.no_content=Δεν υπάρχει ακόμα περιεχόμενο.
issues.close=Κλείσιμο Ζητήματος issues.close=Κλείσιμο Ζητήματος
issues.comment_pull_merged_at=συγχώνευσε την υποβολή %[1]s στο %[2]s %[3]s
issues.comment_manually_pull_merged_at=συγχώνευσε χειροκίνητα την υποβολή %[1]s στο %[2]s %[3]s
issues.close_comment_issue=Σχόλιο και κλείσιμο issues.close_comment_issue=Σχόλιο και κλείσιμο
issues.reopen_issue=Ανοίξτε ξανά issues.reopen_issue=Ανοίξτε ξανά
issues.reopen_comment_issue=Σχόλιο και Άνοιγμα ξανά issues.reopen_comment_issue=Σχόλιο και Άνοιγμα ξανά
@ -1488,10 +1452,6 @@ issues.attachment.open_tab=`Κάντε κλικ για να δείτε το "%s"
issues.attachment.download=`Κάντε κλικ για να λάβετε το "%s"` issues.attachment.download=`Κάντε κλικ για να λάβετε το "%s"`
issues.subscribe=Εγγραφή issues.subscribe=Εγγραφή
issues.unsubscribe=Διαγραφή issues.unsubscribe=Διαγραφή
issues.unpin_issue=Άφεση Ζητήματος
issues.max_pinned=Δεν μπορείτε να διατηρήσετε περισσότερα ζητήματα
issues.pin_comment=διατήρησε αυτό %s
issues.unpin_comment=άφησε αυτό %s
issues.lock=Κλείδωμα συνομιλίας issues.lock=Κλείδωμα συνομιλίας
issues.unlock=Ξεκλείδωμα συνομιλίας issues.unlock=Ξεκλείδωμα συνομιλίας
issues.lock.unknown_reason=Αδυναμία κλειδώματος ενός ζητήματος με άγνωστο λόγο. issues.lock.unknown_reason=Αδυναμία κλειδώματος ενός ζητήματος με άγνωστο λόγο.
@ -1571,7 +1531,6 @@ issues.dependency.issue_closing_blockedby=Το κλείσιμο αυτού το
issues.dependency.issue_close_blocks=Αυτό το ζήτημα εμποδίζει το κλείσιμο των ακόλουθων ζητημάτων issues.dependency.issue_close_blocks=Αυτό το ζήτημα εμποδίζει το κλείσιμο των ακόλουθων ζητημάτων
issues.dependency.pr_close_blocks=Αυτό το pull request εμποδίζει το κλείσιμο των ακόλουθων ζητημάτων issues.dependency.pr_close_blocks=Αυτό το pull request εμποδίζει το κλείσιμο των ακόλουθων ζητημάτων
issues.dependency.issue_close_blocked=Πρέπει να κλείσετε όλα τα ζητήματα που εμποδίζουν αυτό το ζήτημα πριν το κλείσετε. issues.dependency.issue_close_blocked=Πρέπει να κλείσετε όλα τα ζητήματα που εμποδίζουν αυτό το ζήτημα πριν το κλείσετε.
issues.dependency.issue_batch_close_blocked=Δεν είναι δυνατό το ομαδικό κλείσιμο ζητημάτων που επιλέξατε, επειδή το ζήτημα #%d ακόμα έχει ανοιχτές εξαρτήσεις
issues.dependency.pr_close_blocked=Πρέπει να κλείσετε όλα τα ζητήματα που εμποδίζουν αυτό το pull request για να μπορέσετε να το συγχωνεύσετε. issues.dependency.pr_close_blocked=Πρέπει να κλείσετε όλα τα ζητήματα που εμποδίζουν αυτό το pull request για να μπορέσετε να το συγχωνεύσετε.
issues.dependency.blocks_short=Μπλοκάρει issues.dependency.blocks_short=Μπλοκάρει
issues.dependency.blocked_by_short=Εξαρτάται από issues.dependency.blocked_by_short=Εξαρτάται από
@ -1917,16 +1876,6 @@ settings.hooks=Webhooks
settings.githooks=Git Hooks settings.githooks=Git Hooks
settings.basic_settings=Βασικές Ρυθμίσεις settings.basic_settings=Βασικές Ρυθμίσεις
settings.mirror_settings=Ρυθμίσεις Ειδώλου settings.mirror_settings=Ρυθμίσεις Ειδώλου
settings.mirror_settings.docs=Ρυθμίστε το αποθετήριο σας ώστε να συγχρονίζονται αυτόματα οι υποβολές, ετικέτες και κλάδοι με ένα άλλο αποθετήριο.
settings.mirror_settings.docs.disabled_pull_mirror.instructions=Ρυθμίστε το έργο σας για να ωθούνται αυτόματα οι υποβολές, ετικέτες και κλάδοι σε ένα άλλο αποθετήριο. Τα είδωλα τύπου λήψης έχουν απενεργοποιηθεί από τον διαχειριστή σας.
settings.mirror_settings.docs.disabled_push_mirror.instructions=Ρυθμίστε το έργο σας να τραβά αυτόματα υποβολές, ετικέτες και κλάδους από ένα άλλο αποθετήριο.
settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=Αυτή τη στιγμή, αυτό μπορεί να γίνει μόνο στο μενού "Νέα Μεταφορά". Για περισσότερες πληροφορίες, συμβουλευτείτε το:
settings.mirror_settings.docs.disabled_push_mirror.info=Τα είδωλα ώθησης έχουν απενεργοποιηθεί από το διαχειριστή σας.
settings.mirror_settings.docs.no_new_mirrors=Το αποθετήριο σας αντιγράφει τις αλλαγές προς ή από ένα άλλο αποθετήριο. Λάβετε υπόψη ότι δεν μπορείτε να δημιουργήσετε νέα είδωλα αυτή τη στιγμή.
settings.mirror_settings.docs.can_still_use=Αν και δεν μπορείτε να τροποποιήσετε τα υπάρχοντα είδωλα ή να δημιουργήσετε νέα, μπορείτε να χρησιμοποιείται ακόμα το υπάρχων είδωλο.
settings.mirror_settings.docs.pull_mirror_instructions=Για να ορίσετε έναν είδωλο έλξης, παρακαλούμε συμβουλευθείτε:
settings.mirror_settings.docs.doc_link_title=Πώς μπορώ να αντιγράψω αποθετήρια;
settings.mirror_settings.docs.pulling_remote_title=Έλξη από ένα απομακρυσμένο αποθετήριο
settings.mirror_settings.mirrored_repository=Είδωλο αποθετηρίου settings.mirror_settings.mirrored_repository=Είδωλο αποθετηρίου
settings.mirror_settings.direction=Κατεύθυνση settings.mirror_settings.direction=Κατεύθυνση
settings.mirror_settings.direction.pull=Pull settings.mirror_settings.direction.pull=Pull
@ -1939,8 +1888,6 @@ settings.sync_mirror=Συγχρονισμός Τώρα
settings.mirror_sync_in_progress=Ο συγχρονισμός ειδώλου είναι σε εξέλιξη. Ελέγξτε ξανά σε λίγο. settings.mirror_sync_in_progress=Ο συγχρονισμός ειδώλου είναι σε εξέλιξη. Ελέγξτε ξανά σε λίγο.
settings.site=Ιστοσελίδα settings.site=Ιστοσελίδα
settings.update_settings=Ενημέρωση Ρυθμίσεων settings.update_settings=Ενημέρωση Ρυθμίσεων
settings.update_mirror_settings=Ενημέρωση Ρυθμίσεων Ειδώλου
settings.branches.switch_default_branch=Αλλαγή Προεπιλεγμένου Κλάδου
settings.branches.update_default_branch=Ενημέρωση Προεπιλεγμένου Κλάδου settings.branches.update_default_branch=Ενημέρωση Προεπιλεγμένου Κλάδου
settings.branches.add_new_rule=Προσθήκη Νέου Κανόνα settings.branches.add_new_rule=Προσθήκη Νέου Κανόνα
settings.advanced_settings=Ρυθμίσεις Για Προχωρημένους settings.advanced_settings=Ρυθμίσεις Για Προχωρημένους
@ -2039,7 +1986,6 @@ settings.delete_notices_2=- Αυτή η ενέργεια θα διαγράψει
settings.delete_notices_fork_1=- Τα Forks αυτού του αποθετηρίου θα γίνουν ανεξάρτητα μετά τη διαγραφή. settings.delete_notices_fork_1=- Τα Forks αυτού του αποθετηρίου θα γίνουν ανεξάρτητα μετά τη διαγραφή.
settings.deletion_success=Το αποθετήριο έχει διαγραφεί. settings.deletion_success=Το αποθετήριο έχει διαγραφεί.
settings.update_settings_success=Οι ρυθμίσεις του αποθετηρίου έχουν ενημερωθεί. settings.update_settings_success=Οι ρυθμίσεις του αποθετηρίου έχουν ενημερωθεί.
settings.update_settings_no_unit=Το αποθετήριο θα πρέπει να επιτρέπει τουλάχιστον κάποιο είδος αλληλεπίδρασης.
settings.confirm_delete=Διαγραφή Αποθετηρίου settings.confirm_delete=Διαγραφή Αποθετηρίου
settings.add_collaborator=Προσθήκη Συνεργάτη settings.add_collaborator=Προσθήκη Συνεργάτη
settings.add_collaborator_success=Έχει προστεθεί ο συνεργάτης. settings.add_collaborator_success=Έχει προστεθεί ο συνεργάτης.
@ -2137,10 +2083,6 @@ settings.event_pull_request_review=Pull Request Αξιολογήθηκε
settings.event_pull_request_review_desc=Το pull request εγκρίθηκε, απορρίφθηκε ή προστέθηκε αξιολόγηση. settings.event_pull_request_review_desc=Το pull request εγκρίθηκε, απορρίφθηκε ή προστέθηκε αξιολόγηση.
settings.event_pull_request_sync=Pull Request Συγχρονίστηκε settings.event_pull_request_sync=Pull Request Συγχρονίστηκε
settings.event_pull_request_sync_desc=Το pull request συγχρονίστηκε. settings.event_pull_request_sync_desc=Το pull request συγχρονίστηκε.
settings.event_pull_request_review_request=Αίτηση Αξιολόγησης του Pull Request
settings.event_pull_request_review_request_desc=Ζητήθηκε η αξιολόγηση του pull request ή η αίτηση αξιολόγησης αφαιρέθηκε.
settings.event_pull_request_approvals=Εγκρίσεις Pull Request
settings.event_pull_request_merge=Συγχώνευση Pull Request
settings.event_package=Πακέτο settings.event_package=Πακέτο
settings.event_package_desc=Το πακέτο δημιουργήθηκε ή διαγράφηκε σε ένα αποθετήριο. settings.event_package_desc=Το πακέτο δημιουργήθηκε ή διαγράφηκε σε ένα αποθετήριο.
settings.branch_filter=Φίλτρο κλάδου settings.branch_filter=Φίλτρο κλάδου
@ -2203,8 +2145,6 @@ settings.protect_disable_push=Απενεργοποίηση Ώθησης
settings.protect_disable_push_desc=Κανένα push δεν θα επιτρέπεται σε αυτόν τον κλάδο. settings.protect_disable_push_desc=Κανένα push δεν θα επιτρέπεται σε αυτόν τον κλάδο.
settings.protect_enable_push=Ενεργοποίηση Push settings.protect_enable_push=Ενεργοποίηση Push
settings.protect_enable_push_desc=Οποιοσδήποτε έχει πρόσβαση εγγραφής θα επιτρέπεται να κάνει push σε αυτόν τον κλάδο (αλλά όχι και να κάνει force push). settings.protect_enable_push_desc=Οποιοσδήποτε έχει πρόσβαση εγγραφής θα επιτρέπεται να κάνει push σε αυτόν τον κλάδο (αλλά όχι και να κάνει force push).
settings.protect_enable_merge=Ενεργοποίηση Συγχώνευσης
settings.protect_enable_merge_desc=Οποιοσδήποτε έχει πρόσβαση εγγραφής θα επιτρέπεται να συγχωνεύσει τα pull request σε αυτόν τον κλάδο.
settings.protect_whitelist_committers=Περιορισμός του Push στη Λίστα settings.protect_whitelist_committers=Περιορισμός του Push στη Λίστα
settings.protect_whitelist_committers_desc=Μόνο χρήστες ή ομάδες στη λίστα θα επιτρέπεται να κάνουν push σε αυτόν τον κλάδο (αλλά όχι να κάνουν force push). settings.protect_whitelist_committers_desc=Μόνο χρήστες ή ομάδες στη λίστα θα επιτρέπεται να κάνουν push σε αυτόν τον κλάδο (αλλά όχι να κάνουν force push).
settings.protect_whitelist_deploy_keys=Έγκριση κλειδιών διάθεσης με πρόσβαση εγγραφής για ώθηση. settings.protect_whitelist_deploy_keys=Έγκριση κλειδιών διάθεσης με πρόσβαση εγγραφής για ώθηση.
@ -2217,13 +2157,8 @@ settings.protect_merge_whitelist_committers_desc=Επιτρέψτε μόνο σ
settings.protect_merge_whitelist_users=Λίστα επιτρεπόμενων χρηστών για συγχώνευση: settings.protect_merge_whitelist_users=Λίστα επιτρεπόμενων χρηστών για συγχώνευση:
settings.protect_merge_whitelist_teams=Επιτρεπόμενες ομάδες για συγχώνευση: settings.protect_merge_whitelist_teams=Επιτρεπόμενες ομάδες για συγχώνευση:
settings.protect_check_status_contexts=Ενεργοποίηση Ελέγχου Κατάστασης settings.protect_check_status_contexts=Ενεργοποίηση Ελέγχου Κατάστασης
settings.protect_status_check_patterns=Μοτίβα ελέγχου κατάστασης:
settings.protect_status_check_patterns_desc=Ορίστε μοτίβα για να καθορίσετε ποιοι έλεγχοι κατάστασης πρέπει να περάσουν πριν οι κλάδοι να μπορούν να συγχωνευτούν σε έναν κλάδο που ταιριάζει με αυτόν τον κανόνα. Κάθε γραμμή καθορίζει ένα μοτίβο. Τα μοτίβα δεν μπορούν να είναι κενά.
settings.protect_check_status_contexts_desc=Απαιτείται έλεγχος κατάστασης για να περάσει το pull request πριν από τη συγχώνευση. Επιλέξτε ποιοι έλεγχοι κατάστασης πρέπει να περάσουν πριν κλάδοι μπορούν να συγχωνευτούν σε έναν κλάδο που ταιριάζει με αυτόν τον κανόνα. Όταν είναι ενεργοποιημένο, οι υποβολές πρέπει πρώτα να γίνονται push σε άλλο κλάδο, στη συνέχεια, να συγχωνεύονται ή γίνονται push απευθείας σε ένα κλάδο που ταιριάζει με αυτόν τον κανόνα, αφού έχουν ολοκληρωθεί οι έλεγχοι κατάστασης. Αν δεν επιλεχθεί κανένα πλαίσιο, η τελευταία υποβολή πρέπει να είναι επιτυχής ανεξάρτητα από το πλαίσιο. settings.protect_check_status_contexts_desc=Απαιτείται έλεγχος κατάστασης για να περάσει το pull request πριν από τη συγχώνευση. Επιλέξτε ποιοι έλεγχοι κατάστασης πρέπει να περάσουν πριν κλάδοι μπορούν να συγχωνευτούν σε έναν κλάδο που ταιριάζει με αυτόν τον κανόνα. Όταν είναι ενεργοποιημένο, οι υποβολές πρέπει πρώτα να γίνονται push σε άλλο κλάδο, στη συνέχεια, να συγχωνεύονται ή γίνονται push απευθείας σε ένα κλάδο που ταιριάζει με αυτόν τον κανόνα, αφού έχουν ολοκληρωθεί οι έλεγχοι κατάστασης. Αν δεν επιλεχθεί κανένα πλαίσιο, η τελευταία υποβολή πρέπει να είναι επιτυχής ανεξάρτητα από το πλαίσιο.
settings.protect_check_status_contexts_list=Έλεγχοι κατάστασης που βρέθηκαν την τελευταία εβδομάδα για αυτό το αποθετήριο settings.protect_check_status_contexts_list=Έλεγχοι κατάστασης που βρέθηκαν την τελευταία εβδομάδα για αυτό το αποθετήριο
settings.protect_status_check_matched=Ταιριάζει
settings.protect_invalid_status_check_pattern=Μη έγκυρο μοτίβο ελέγχου κατάστασης: "%s".
settings.protect_no_valid_status_check_patterns=Μη έγκυρα μοτίβα ελέγχου κατάστασης.
settings.protect_required_approvals=Απαιτούμενες εγκρίσεις: settings.protect_required_approvals=Απαιτούμενες εγκρίσεις:
settings.protect_required_approvals_desc=Επιτρέψτε μόνο να συγχωνεύσετε pull request με αρκετές θετικές κριτικές. settings.protect_required_approvals_desc=Επιτρέψτε μόνο να συγχωνεύσετε pull request με αρκετές θετικές κριτικές.
settings.protect_approvals_whitelist_enabled=Περιορισμός εγκρίσεων σε επιτρεπόμενους χρήστες ή ομάδες settings.protect_approvals_whitelist_enabled=Περιορισμός εγκρίσεων σε επιτρεπόμενους χρήστες ή ομάδες
@ -2235,7 +2170,6 @@ settings.dismiss_stale_approvals_desc=Όταν οι νέες υποβολές π
settings.require_signed_commits=Απαιτούνται Υπογεγραμμένες Υποβολές settings.require_signed_commits=Απαιτούνται Υπογεγραμμένες Υποβολές
settings.require_signed_commits_desc=Απόρριψη νέων υποβολών σε αυτόν τον κλάδο εάν είναι μη υπογεγραμμένες ή μη επαληθεύσιμες. settings.require_signed_commits_desc=Απόρριψη νέων υποβολών σε αυτόν τον κλάδο εάν είναι μη υπογεγραμμένες ή μη επαληθεύσιμες.
settings.protect_branch_name_pattern=Μοτίβο Προστατευμένου Ονόματος Κλάδου settings.protect_branch_name_pattern=Μοτίβο Προστατευμένου Ονόματος Κλάδου
settings.protect_patterns=Μοτίβα
settings.protect_protected_file_patterns=Μοτίβα προστατευμένων αρχείων (διαχωρισμένα με ερωτηματικό ';'): settings.protect_protected_file_patterns=Μοτίβα προστατευμένων αρχείων (διαχωρισμένα με ερωτηματικό ';'):
settings.protect_protected_file_patterns_desc=Τα προστατευόμενα αρχεία δεν επιτρέπεται να αλλάξουν άμεσα, ακόμη και αν ο χρήστης έχει δικαιώματα να προσθέσει, να επεξεργαστεί ή να διαγράψει αρχεία σε αυτόν τον κλάδο. Επιπλέων μοτίβα μπορούν να διαχωριστούν με ερωτηματικό (';'). Δείτε την τεκμηρίωση <a href='https://pkg.go.dev/github.com/gobwas/glob#Compile'>github.com/gobwas/glob</a> για τη σύνταξη του μοτίβου. Πχ: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>. settings.protect_protected_file_patterns_desc=Τα προστατευόμενα αρχεία δεν επιτρέπεται να αλλάξουν άμεσα, ακόμη και αν ο χρήστης έχει δικαιώματα να προσθέσει, να επεξεργαστεί ή να διαγράψει αρχεία σε αυτόν τον κλάδο. Επιπλέων μοτίβα μπορούν να διαχωριστούν με ερωτηματικό (';'). Δείτε την τεκμηρίωση <a href='https://pkg.go.dev/github.com/gobwas/glob#Compile'>github.com/gobwas/glob</a> για τη σύνταξη του μοτίβου. Πχ: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
settings.protect_unprotected_file_patterns=Μοτίβα μη προστατευμένων αρχείων (διαχωρισμένα με ερωτηματικό ';'): settings.protect_unprotected_file_patterns=Μοτίβα μη προστατευμένων αρχείων (διαχωρισμένα με ερωτηματικό ';'):
@ -2450,13 +2384,10 @@ branch.protected_deletion_failed=Ο κλάδος "%s" προστατεύεται
branch.default_deletion_failed=Ο κλάδος "%s" είναι ο προεπιλεγμένος κλάδος. Δεν μπορεί να διαγραφεί. branch.default_deletion_failed=Ο κλάδος "%s" είναι ο προεπιλεγμένος κλάδος. Δεν μπορεί να διαγραφεί.
branch.restore=`Επαναφορά του Κλάδου "%s"` branch.restore=`Επαναφορά του Κλάδου "%s"`
branch.download=`Λήψη του Κλάδου "%s"` branch.download=`Λήψη του Κλάδου "%s"`
branch.rename=`Μετονομασία Κλάδου "%s"`
branch.included_desc=Αυτός ο κλάδος είναι μέρος του προεπιλεγμένου κλάδου branch.included_desc=Αυτός ο κλάδος είναι μέρος του προεπιλεγμένου κλάδου
branch.included=Περιλαμβάνεται branch.included=Περιλαμβάνεται
branch.create_new_branch=Δημιουργία κλάδου από κλάδο: branch.create_new_branch=Δημιουργία κλάδου από κλάδο:
branch.confirm_create_branch=Δημιουργία κλάδου branch.confirm_create_branch=Δημιουργία κλάδου
branch.warning_rename_default_branch=Μετονομάζετε τον προεπιλεγμένο κλάδο.
branch.rename_branch_to=Μετονομασία του "%s" σε:
branch.confirm_rename_branch=Μετονομασία κλάδου branch.confirm_rename_branch=Μετονομασία κλάδου
branch.create_branch_operation=Δημιουργία κλάδου branch.create_branch_operation=Δημιουργία κλάδου
branch.new_branch=Δημιουργία νέου κλάδου branch.new_branch=Δημιουργία νέου κλάδου
@ -3015,7 +2946,6 @@ config.mailer_sendmail_timeout=Χρονικό Όριο Sendmail
config.mailer_use_dummy=Ψεύτικο config.mailer_use_dummy=Ψεύτικο
config.test_email_placeholder=Email (π.χ. test@example.com) config.test_email_placeholder=Email (π.χ. test@example.com)
config.send_test_mail=Αποστολή Δοκιμαστικού Email config.send_test_mail=Αποστολή Δοκιμαστικού Email
config.send_test_mail_submit=Αποστολή
config.test_mail_failed=Αποτυχία αποστολής ενός δοκιμαστικού email στο"%s": %v config.test_mail_failed=Αποτυχία αποστολής ενός δοκιμαστικού email στο"%s": %v
config.test_mail_sent=Στάλθηκε ένα δοκιμαστικό email στο "%s". config.test_mail_sent=Στάλθηκε ένα δοκιμαστικό email στο "%s".
@ -3055,16 +2985,13 @@ config.git_pull_timeout=Χρονικό Όριο Pull
config.git_gc_timeout=Χρονικό Όριο Λειτουργίας GC config.git_gc_timeout=Χρονικό Όριο Λειτουργίας GC
config.log_config=Ρύθμιση Καταγραφών config.log_config=Ρύθμιση Καταγραφών
config.logger_name_fmt=Καταγραφέας: %s
config.disabled_logger=Απενεργοποιημένο config.disabled_logger=Απενεργοποιημένο
config.access_log_mode=Λειτουργία Καταγραφών Πρόσβασης config.access_log_mode=Λειτουργία Καταγραφών Πρόσβασης
config.access_log_template=Πρότυπο Καταγραφής Προσβάσεων
config.xorm_log_sql=Καταγραφή SQL config.xorm_log_sql=Καταγραφή SQL
config.get_setting_failed=Αποτυχία λήψης ρύθμισης %s config.get_setting_failed=Αποτυχία λήψης ρύθμισης %s
config.set_setting_failed=Αποτυχία ορισμού της ρύθμισης %s config.set_setting_failed=Αποτυχία ορισμού της ρύθμισης %s
monitor.stats=Στατιστικά
monitor.cron=Προγραμματισμένες Εργασίες monitor.cron=Προγραμματισμένες Εργασίες
monitor.name=Όνομα monitor.name=Όνομα
@ -3074,8 +3001,6 @@ monitor.previous=Προηγούμενη Ώρα
monitor.execute_times=Εκτελέσεις monitor.execute_times=Εκτελέσεις
monitor.process=Εκτελούμενες Διεργασίες monitor.process=Εκτελούμενες Διεργασίες
monitor.stacktrace=Ιχνηλατήσεις Στοίβας monitor.stacktrace=Ιχνηλατήσεις Στοίβας
monitor.processes_count=%d Διεργασίες
monitor.download_diagnosis_report=Λήψη αναφοράς διάγνωσης
monitor.desc=Περιγραφή monitor.desc=Περιγραφή
monitor.start=Ώρα Έναρξης monitor.start=Ώρα Έναρξης
monitor.execute_time=Χρόνος Εκτέλεσης monitor.execute_time=Χρόνος Εκτέλεσης
@ -3096,14 +3021,11 @@ monitor.queue.numberinqueue=Πλήθος Ουράς
monitor.queue.review=Εξέταση Ρυθμίσεων monitor.queue.review=Εξέταση Ρυθμίσεων
monitor.queue.review_add=Εξέταση/Προσθήκη Εργατών monitor.queue.review_add=Εξέταση/Προσθήκη Εργατών
monitor.queue.settings.title=Ρυθμίσεις Δεξαμενής monitor.queue.settings.title=Ρυθμίσεις Δεξαμενής
monitor.queue.settings.desc=Οι δεξαμενές αυξάνονται δυναμικά όταν υπάρχει φραγή της ουράς των εργατών τους.
monitor.queue.settings.maxnumberworkers=Μέγιστος Αριθμός Εργατών monitor.queue.settings.maxnumberworkers=Μέγιστος Αριθμός Εργατών
monitor.queue.settings.maxnumberworkers.placeholder=Αυτή τη στιγμή %[1]d monitor.queue.settings.maxnumberworkers.placeholder=Αυτή τη στιγμή %[1]d
monitor.queue.settings.maxnumberworkers.error=Ο μέγιστος αριθμός εργατών πρέπει να είναι αριθμός monitor.queue.settings.maxnumberworkers.error=Ο μέγιστος αριθμός εργατών πρέπει να είναι αριθμός
monitor.queue.settings.submit=Ενημέρωση Ρυθμίσεων monitor.queue.settings.submit=Ενημέρωση Ρυθμίσεων
monitor.queue.settings.changed=Οι Ρυθμίσεις Ενημερώθηκαν monitor.queue.settings.changed=Οι Ρυθμίσεις Ενημερώθηκαν
monitor.queue.settings.remove_all_items=Αφαίρεση όλων
monitor.queue.settings.remove_all_items_done=Όλα τα αντικείμενα στην ουρά αφαιρέθηκαν.
notices.system_notice_list=Ειδοποιήσεις Συστήματος notices.system_notice_list=Ειδοποιήσεις Συστήματος
notices.view_detail_header=Προβολή Λεπτομερειών Ειδοποίησης notices.view_detail_header=Προβολή Λεπτομερειών Ειδοποίησης
@ -3238,15 +3160,9 @@ versions=Εκδόσεις
versions.view_all=Προβολή όλων versions.view_all=Προβολή όλων
dependency.id=ID dependency.id=ID
dependency.version=Έκδοση dependency.version=Έκδοση
alpine.registry=Ρυθμίστε αυτό το μητρώο προσθέτοντας το url στο αρχείο <code>/etc/apk/repositories</code>:
alpine.registry.key=Αποθηκεύστε το δημόσιο κλειδί RSA του μητρώου στο φάκελο <code>/etc/apk/keys/</code> για να επαληθεύσετε την υπογραφή ευρετηρίου:
alpine.registry.info=Επιλέξτε $branch και $repository από την παρακάτω λίστα.
alpine.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή: alpine.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή:
alpine.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Alpine, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="%s">στην τεκμηρίωση</a>.
alpine.repository=Πληροφορίες Αποθετηρίου
alpine.repository.branches=Κλάδοι alpine.repository.branches=Κλάδοι
alpine.repository.repositories=Αποθετήρια alpine.repository.repositories=Αποθετήρια
alpine.repository.architectures=Αρχιτεκτονικές
cargo.registry=Ρυθμίστε αυτό το μητρώο στις ρυθμίσεις του Cargo (για παράδειγμα <code>~/.cargo/config.toml</code>): cargo.registry=Ρυθμίστε αυτό το μητρώο στις ρυθμίσεις του Cargo (για παράδειγμα <code>~/.cargo/config.toml</code>):
cargo.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Cargo, εκτελέστε την ακόλουθη εντολή: cargo.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Cargo, εκτελέστε την ακόλουθη εντολή:
cargo.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Cargo, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/cargo/">στην τεκμηρίωση</a>. cargo.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Cargo, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/cargo/">στην τεκμηρίωση</a>.
@ -3279,21 +3195,11 @@ container.layers=Στρώματα Εικόνας
container.labels=Ετικέτες container.labels=Ετικέτες
container.labels.key=Κλειδί container.labels.key=Κλειδί
container.labels.value=Τιμή container.labels.value=Τιμή
cran.registry=Ρυθμίστε αυτό το μητρώο στο αρχείο <code>Rprofile.site</code>:
cran.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή: cran.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή:
cran.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο CRAN, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/cran/">στην τεκμηρίωση</a>.
debian.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών: debian.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών:
debian.registry.info=Επιλέξτε $distribution και $component από την παρακάτω λίστα.
debian.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή: debian.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή:
debian.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Debian, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="%s">στην τεκμηρίωση</a>.
debian.repository=Πληροφορίες Αποθετηρίου
debian.repository.distributions=Διανομές
debian.repository.components=Συστατικά
debian.repository.architectures=Αρχιτεκτονικές
generic.download=Λήψη πακέτου από τη γραμμή εντολών: generic.download=Λήψη πακέτου από τη γραμμή εντολών:
generic.documentation=Για περισσότερες πληροφορίες σχετικά με το γενικό μητρώο, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/generic">στην τεκμηρίωση</a>. generic.documentation=Για περισσότερες πληροφορίες σχετικά με το γενικό μητρώο, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/generic">στην τεκμηρίωση</a>.
go.install=Εγκαταστήστε το πακέτο από τη γραμμή εντολών:
go.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Go, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="%s">στην τεκμηρίωση</a>.
helm.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών: helm.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών:
helm.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή: helm.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή:
helm.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Helm, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/helm/">στην τεκμηρίωση</a>. helm.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Helm, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/helm/">στην τεκμηρίωση</a>.
@ -3322,7 +3228,6 @@ pypi.install=Για να εγκαταστήσετε το πακέτο χρησι
pypi.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο PyPI, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">στην τεκμηρίωση</a>. pypi.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο PyPI, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">στην τεκμηρίωση</a>.
rpm.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών: rpm.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών:
rpm.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή: rpm.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή:
rpm.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο RPM, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="%s">στην τεκμηρίωση</a>.
rubygems.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το gem, εκτελέστε την ακόλουθη εντολή: rubygems.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το gem, εκτελέστε την ακόλουθη εντολή:
rubygems.install2=ή προσθέστε το στο Gemfile: rubygems.install2=ή προσθέστε το στο Gemfile:
rubygems.dependencies.runtime=Εξαρτήσεις Εκτέλεσης rubygems.dependencies.runtime=Εξαρτήσεις Εκτέλεσης
@ -3395,7 +3300,6 @@ deletion=Αφαίρεση μυστικού
deletion.description=Η αφαίρεση ενός μυστικού είναι μόνιμη και δεν μπορεί να αναιρεθεί. Συνέχεια; deletion.description=Η αφαίρεση ενός μυστικού είναι μόνιμη και δεν μπορεί να αναιρεθεί. Συνέχεια;
deletion.success=Το μυστικό έχει αφαιρεθεί. deletion.success=Το μυστικό έχει αφαιρεθεί.
deletion.failed=Αποτυχία αφαίρεσης μυστικού. deletion.failed=Αποτυχία αφαίρεσης μυστικού.
management=Διαχείριση Μυστικών
[actions] [actions]
actions=Δράσεις actions=Δράσεις

View File

@ -41,7 +41,6 @@ func MustEnableProjects(ctx *context.Context) {
// Projects renders the home page of projects // Projects renders the home page of projects
func Projects(ctx *context.Context) { func Projects(ctx *context.Context) {
shared_user.PrepareContextForProfileBigAvatar(ctx)
ctx.Data["Title"] = ctx.Tr("repo.project_board") ctx.Data["Title"] = ctx.Tr("repo.project_board")
sortType := ctx.FormTrim("sort") sortType := ctx.FormTrim("sort")

View File

@ -4,109 +4,35 @@
package user package user
import ( import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
// prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu) func RenderUserHeader(ctx *context.Context) {
// It is designed to be fast and safe to be called multiple times in one request ctx.Data["IsProjectEnabled"] = true
func prepareContextForCommonProfile(ctx *context.Context) {
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["ContextUser"] = ctx.ContextUser
ctx.Data["EnableFeed"] = setting.Other.EnableFeed tab := ctx.FormString("tab")
ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink() ctx.Data["TabName"] = tab
} repo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
if err == nil && !repo.IsEmpty {
// PrepareContextForProfileBigAvatar set the context for big avatar view on the profile page gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
func PrepareContextForProfileBigAvatar(ctx *context.Context) {
prepareContextForCommonProfile(ctx)
ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
// Show OpenID URIs
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
if err != nil {
ctx.ServerError("GetUserOpenIDs", err)
return
}
ctx.Data["OpenIDs"] = openIDs
if len(ctx.ContextUser.Description) != 0 {
content, err := markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, ctx.ContextUser.Description)
if err != nil { if err != nil {
ctx.ServerError("RenderString", err) ctx.ServerError("OpenRepository", err)
return return
} }
ctx.Data["RenderedDescription"] = content defer gitRepo.Close()
} commit, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
if err != nil {
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) ctx.ServerError("GetBranchCommit", err)
orgs, err := organization.FindOrgs(organization.FindOrgOptions{ return
UserID: ctx.ContextUser.ID,
IncludePrivate: showPrivate,
})
if err != nil {
ctx.ServerError("FindOrgs", err)
return
}
ctx.Data["Orgs"] = orgs
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser)
if err != nil {
ctx.ServerError("GetUserBadges", err)
return
}
ctx.Data["Badges"] = badges
// in case the numbers are already provided by other functions, no need to query again (which is slow)
if _, ok := ctx.Data["NumFollowers"]; !ok {
_, ctx.Data["NumFollowers"], _ = user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{PageSize: 1, Page: 1})
}
if _, ok := ctx.Data["NumFollowing"]; !ok {
_, ctx.Data["NumFollowing"], _ = user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{PageSize: 1, Page: 1})
}
}
func FindUserProfileReadme(ctx *context.Context) (profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
profileDbRepo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
if err == nil && !profileDbRepo.IsEmpty {
if profileGitRepo, err = git.OpenRepository(ctx, profileDbRepo.RepoPath()); err != nil {
log.Error("FindUserProfileReadme failed to OpenRepository: %v", err)
} else {
if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil {
log.Error("FindUserProfileReadme failed to GetBranchCommit: %v", err)
} else {
profileReadmeBlob, _ = commit.GetBlobByPath("README.md")
}
} }
} blob, err := commit.GetBlobByPath("README.md")
return profileGitRepo, profileReadmeBlob, func() { if err == nil && blob != nil {
if profileGitRepo != nil { ctx.Data["ProfileReadme"] = true
_ = profileGitRepo.Close()
} }
} }
} }
func RenderUserHeader(ctx *context.Context) {
prepareContextForCommonProfile(ctx)
_, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx)
defer profileClose()
ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
}

View File

@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
code_indexer "code.gitea.io/gitea/modules/indexer/code" code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
shared_user "code.gitea.io/gitea/routers/web/shared/user"
) )
const ( const (
@ -24,9 +23,8 @@ func CodeSearch(ctx *context.Context) {
ctx.Redirect(ctx.ContextUser.HomeLink()) ctx.Redirect(ctx.ContextUser.HomeLink())
return return
} }
shared_user.PrepareContextForProfileBigAvatar(ctx)
shared_user.RenderUserHeader(ctx)
ctx.Data["IsProjectEnabled"] = true
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["Title"] = ctx.Tr("explore.code") ctx.Data["Title"] = ctx.Tr("explore.code")

View File

@ -857,7 +857,7 @@ func UsernameSubRoute(ctx *context.Context) {
context_service.UserAssignmentWeb()(ctx) context_service.UserAssignmentWeb()(ctx)
if !ctx.Written() { if !ctx.Written() {
ctx.Data["EnableFeed"] = setting.Other.EnableFeed ctx.Data["EnableFeed"] = setting.Other.EnableFeed
OwnerProfile(ctx) Profile(ctx)
} }
} }
} }

View File

@ -37,7 +37,6 @@ const (
// ListPackages displays a list of all packages of the context user // ListPackages displays a list of all packages of the context user
func ListPackages(ctx *context.Context) { func ListPackages(ctx *context.Context) {
shared_user.PrepareContextForProfileBigAvatar(ctx)
page := ctx.FormInt("page") page := ctx.FormInt("page")
if page <= 1 { if page <= 1 {
page = 1 page = 1
@ -260,7 +259,6 @@ func ViewPackageVersion(ctx *context.Context) {
// ListPackageVersions lists all versions of a package // ListPackageVersions lists all versions of a package
func ListPackageVersions(ctx *context.Context) { func ListPackageVersions(ctx *context.Context) {
shared_user.PrepareContextForProfileBigAvatar(ctx)
p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name")) p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name"))
if err != nil { if err != nil {
if err == packages_model.ErrPackageNotExist { if err == packages_model.ErrPackageNotExist {

View File

@ -11,22 +11,22 @@ import (
activities_model "code.gitea.io/gitea/models/activities" activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/web/feed" "code.gitea.io/gitea/routers/web/feed"
"code.gitea.io/gitea/routers/web/org" "code.gitea.io/gitea/routers/web/org"
shared_user "code.gitea.io/gitea/routers/web/shared/user"
) )
// OwnerProfile render profile page for a user or a organization (aka, repo owner) // Profile render user's profile page
func OwnerProfile(ctx *context.Context) { func Profile(ctx *context.Context) {
if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") { if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
feed.ShowUserFeedRSS(ctx) feed.ShowUserFeedRSS(ctx)
return return
@ -38,22 +38,36 @@ func OwnerProfile(ctx *context.Context) {
if ctx.ContextUser.IsOrganization() { if ctx.ContextUser.IsOrganization() {
org.Home(ctx) org.Home(ctx)
} else { return
userProfile(ctx)
} }
}
func userProfile(ctx *context.Context) {
// check view permissions // check view permissions
if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) {
ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name)) ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name))
return return
} }
// advertise feed via meta tag
ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink()
// Show OpenID URIs
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
if err != nil {
ctx.ServerError("GetUserOpenIDs", err)
return
}
var isFollowing bool
if ctx.Doer != nil {
isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
}
ctx.Data["Title"] = ctx.ContextUser.DisplayName() ctx.Data["Title"] = ctx.ContextUser.DisplayName()
ctx.Data["PageIsUserProfile"] = true ctx.Data["PageIsUserProfile"] = true
ctx.Data["ContextUser"] = ctx.ContextUser
ctx.Data["OpenIDs"] = openIDs
ctx.Data["IsFollowing"] = isFollowing
// prepare heatmap data
if setting.Service.EnableUserHeatmap { if setting.Service.EnableUserHeatmap {
data, err := activities_model.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) data, err := activities_model.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer)
if err != nil { if err != nil {
@ -64,28 +78,75 @@ func userProfile(ctx *context.Context) {
ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data) ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
} }
profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx) if len(ctx.ContextUser.Description) != 0 {
defer profileClose() content, err := markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, ctx.ContextUser.Description)
if err != nil {
ctx.ServerError("RenderString", err)
return
}
ctx.Data["RenderedDescription"] = content
}
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) repo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
prepareUserProfileTabData(ctx, showPrivate, profileGitRepo, profileReadmeBlob) if err == nil && !repo.IsEmpty {
// call PrepareContextForProfileBigAvatar later to avoid re-querying the NumFollowers & NumFollowing gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
shared_user.PrepareContextForProfileBigAvatar(ctx) if err != nil {
ctx.HTML(http.StatusOK, tplProfile) ctx.ServerError("OpenRepository", err)
} return
}
func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGitRepo *git.Repository, profileReadme *git.Blob) { defer gitRepo.Close()
// if there is a profile readme, default to "overview" page, otherwise, default to "repositories" page commit, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
tab := ctx.FormString("tab") if err != nil {
if tab == "" { ctx.ServerError("GetBranchCommit", err)
if profileReadme != nil { return
tab = "overview" }
} else { blob, err := commit.GetBlobByPath("README.md")
tab = "repositories" if err == nil {
bytes, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
if err != nil {
ctx.ServerError("GetBlobContent", err)
return
}
profileContent, err := markdown.RenderString(&markup.RenderContext{
Ctx: ctx,
GitRepo: gitRepo,
}, bytes)
if err != nil {
ctx.ServerError("RenderString", err)
return
}
ctx.Data["ProfileReadme"] = profileContent
} }
} }
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
orgs, err := organization.FindOrgs(organization.FindOrgOptions{
UserID: ctx.ContextUser.ID,
IncludePrivate: showPrivate,
})
if err != nil {
ctx.ServerError("FindOrgs", err)
return
}
ctx.Data["Orgs"] = orgs
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser)
if err != nil {
ctx.ServerError("GetUserBadges", err)
return
}
ctx.Data["Badges"] = badges
tab := ctx.FormString("tab")
ctx.Data["TabName"] = tab ctx.Data["TabName"] = tab
ctx.Data["HasProfileReadme"] = profileReadme != nil
page := ctx.FormInt("page") page := ctx.FormInt("page")
if page <= 0 { if page <= 0 {
@ -93,7 +154,12 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
} }
pagingNum := setting.UI.User.RepoPagingNum pagingNum := setting.UI.User.RepoPagingNum
if tab == "activity" {
pagingNum = setting.UI.FeedPagingNum
}
topicOnly := ctx.FormBool("topic") topicOnly := ctx.FormBool("topic")
var ( var (
repos []*repo_model.Repository repos []*repo_model.Repository
count int64 count int64
@ -162,7 +228,6 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
total = int(count) total = int(count)
case "activity": case "activity":
date := ctx.FormString("date") date := ctx.FormString("date")
pagingNum = setting.UI.FeedPagingNum
items, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ items, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
RequestedUser: ctx.ContextUser, RequestedUser: ctx.ContextUser,
Actor: ctx.Doer, Actor: ctx.Doer,
@ -206,6 +271,16 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
} }
total = int(count) total = int(count)
case "projects":
ctx.Data["OpenProjects"], _, err = project_model.FindProjects(ctx, project_model.SearchOptions{
Page: -1,
IsClosed: util.OptionalBoolFalse,
Type: project_model.TypeIndividual,
})
if err != nil {
ctx.ServerError("GetProjects", err)
return
}
case "watching": case "watching":
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{ ListOptions: db.ListOptions{
@ -228,17 +303,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
} }
total = int(count) total = int(count)
case "overview": default:
if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
log.Error("failed to GetBlobContent: %v", err)
} else {
if profileContent, err := markdown.RenderString(&markup.RenderContext{Ctx: ctx, GitRepo: profileGitRepo}, bytes); err != nil {
log.Error("failed to RenderString: %v", err)
} else {
ctx.Data["ProfileReadme"] = profileContent
}
}
default: // default to "repositories"
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{ ListOptions: db.ListOptions{
PageSize: pagingNum, PageSize: pagingNum,
@ -274,6 +339,13 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
pager.AddParam(ctx, "date", "Date") pager.AddParam(ctx, "date", "Date")
} }
ctx.Data["Page"] = pager ctx.Data["Page"] = pager
ctx.Data["IsProjectEnabled"] = true
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
ctx.HTML(http.StatusOK, tplProfile)
} }
// Action response for follow/unfollow user request // Action response for follow/unfollow user request

View File

@ -307,11 +307,6 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
return nil, false return nil, false
} }
log.Trace("SyncMirrors [repo: %-v]: syncing branches...", m.Repo)
if _, err = repo_module.SyncRepoBranchesWithRepo(ctx, m.Repo, gitRepo, 0); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to synchronize branches: %v", m.Repo, err)
}
log.Trace("SyncMirrors [repo: %-v]: syncing releases with tags...", m.Repo) log.Trace("SyncMirrors [repo: %-v]: syncing releases with tags...", m.Repo)
if err = repo_module.SyncReleasesWithTags(m.Repo, gitRepo); err != nil { if err = repo_module.SyncReleasesWithTags(m.Repo, gitRepo); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to synchronize tags to releases: %v", m.Repo, err) log.Error("SyncMirrors [repo: %-v]: failed to synchronize tags to releases: %v", m.Repo, err)

View File

@ -19,7 +19,7 @@ import (
// GarbageCollectLFSMetaObjectsOptions provides options for GarbageCollectLFSMetaObjects function // GarbageCollectLFSMetaObjectsOptions provides options for GarbageCollectLFSMetaObjects function
type GarbageCollectLFSMetaObjectsOptions struct { type GarbageCollectLFSMetaObjectsOptions struct {
LogDetail func(format string, v ...any) Logger log.Logger
AutoFix bool AutoFix bool
OlderThan time.Time OlderThan time.Time
UpdatedLessRecentlyThan time.Time UpdatedLessRecentlyThan time.Time
@ -32,12 +32,10 @@ func GarbageCollectLFSMetaObjects(ctx context.Context, opts GarbageCollectLFSMet
log.Trace("Doing: GarbageCollectLFSMetaObjects") log.Trace("Doing: GarbageCollectLFSMetaObjects")
defer log.Trace("Finished: GarbageCollectLFSMetaObjects") defer log.Trace("Finished: GarbageCollectLFSMetaObjects")
if opts.LogDetail == nil {
opts.LogDetail = log.Debug
}
if !setting.LFS.StartServer { if !setting.LFS.StartServer {
opts.LogDetail("LFS support is disabled") if opts.Logger != nil {
opts.Logger.Info("LFS support is disabled")
}
return nil return nil
} }
@ -56,17 +54,21 @@ func GarbageCollectLFSMetaObjects(ctx context.Context, opts GarbageCollectLFSMet
// GarbageCollectLFSMetaObjectsForRepo garbage collects LFS objects for a specific repository // GarbageCollectLFSMetaObjectsForRepo garbage collects LFS objects for a specific repository
func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.Repository, opts GarbageCollectLFSMetaObjectsOptions) error { func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.Repository, opts GarbageCollectLFSMetaObjectsOptions) error {
opts.LogDetail("Checking %-v", repo) if opts.Logger != nil {
opts.Logger.Info("Checking %-v", repo)
}
total, orphaned, collected, deleted := int64(0), 0, 0, 0 total, orphaned, collected, deleted := int64(0), 0, 0, 0
defer func() { if opts.Logger != nil {
if orphaned == 0 { defer func() {
opts.LogDetail("Found %d total LFSMetaObjects in %-v", total, repo) if orphaned == 0 {
} else if !opts.AutoFix { opts.Logger.Info("Found %d total LFSMetaObjects in %-v", total, repo)
opts.LogDetail("Found %d/%d orphaned LFSMetaObjects in %-v", orphaned, total, repo) } else if !opts.AutoFix {
} else { opts.Logger.Info("Found %d/%d orphaned LFSMetaObjects in %-v", orphaned, total, repo)
opts.LogDetail("Collected %d/%d orphaned/%d total LFSMetaObjects in %-v. %d removed from storage.", collected, orphaned, total, repo, deleted) } else {
} opts.Logger.Info("Collected %d/%d orphaned/%d total LFSMetaObjects in %-v. %d removed from storage.", collected, orphaned, total, repo, deleted)
}() }
}()
}
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
if err != nil { if err != nil {
@ -127,7 +129,9 @@ func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.R
}) })
if err == errStop { if err == errStop {
opts.LogDetail("Processing stopped at %d total LFSMetaObjects in %-v", total, repo) if opts.Logger != nil {
opts.Logger.Info("Processing stopped at %d total LFSMetaObjects in %-v", total, repo)
}
return nil return nil
} else if err != nil { } else if err != nil {
return err return err

View File

@ -1,17 +0,0 @@
{{template "code/searchform" .}}
<div class="divider"></div>
<div class="ui user list">
{{if .CodeIndexerUnavailable}}
<div class="ui error message">
<p>{{$.locale.Tr "explore.code_search_unavailable"}}</p>
</div>
{{else if .SearchResults}}
<h3>
{{.locale.Tr "explore.code_search_results" (.Keyword|Escape) | Str2html}}
</h3>
{{template "code/searchresults" .}}
{{else if .Keyword}}
<div>{{$.locale.Tr "explore.code_no_results"}}</div>
{{end}}
</div>
{{template "base/paginate" .}}

View File

@ -2,7 +2,24 @@
<div role="main" aria-label="{{.Title}}" class="page-content explore users"> <div role="main" aria-label="{{.Title}}" class="page-content explore users">
{{template "explore/navbar" .}} {{template "explore/navbar" .}}
<div class="ui container"> <div class="ui container">
{{template "code/searchcombo" .}} {{template "code/searchform" .}}
<div class="divider"></div>
<div class="ui user list">
{{if .CodeIndexerUnavailable}}
<div class="ui error message">
<p>{{$.locale.Tr "explore.code_search_unavailable"}}</p>
</div>
{{else if .SearchResults}}
<h3>
{{.locale.Tr "explore.code_search_results" (.Keyword|Escape) | Str2html}}
</h3>
{{template "code/searchresults" .}}
{{else if .Keyword}}
<div>{{$.locale.Tr "explore.code_no_results"}}</div>
{{end}}
</div>
{{template "base/paginate" .}}
</div> </div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,4 +1,4 @@
<div class="ui container"> <div class="ui tabs container">
<div class="ui secondary stackable pointing menu"> <div class="ui secondary stackable pointing menu">
<a class="{{if .PageIsViewRepositories}}active {{end}}item" href="{{$.Org.HomeLink}}"> <a class="{{if .PageIsViewRepositories}}active {{end}}item" href="{{$.Org.HomeLink}}">
{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}} {{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
@ -6,7 +6,7 @@
<div class="ui small label">{{.ContextUser.NumRepos}}</div> <div class="ui small label">{{.ContextUser.NumRepos}}</div>
{{end}} {{end}}
</a> </a>
{{if .CanReadProjects}} {{if and .IsProjectEnabled .CanReadProjects}}
<a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects"> <a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects">
{{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}} {{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}}
</a> </a>

View File

@ -1,27 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
{{if .ContextUser.IsOrganization}} <div role="main" aria-label="{{.Title}}" class="page-content repository packages">
<div role="main" aria-label="{{.Title}}" class="page-content repository packages"> {{template "user/overview/header" .}}
{{template "shared/user/org_profile_avatar" .}} {{template "projects/list" .}}
<div class="ui container"> </div>
{{template "user/overview/header" .}}
{{template "projects/list" .}}
</div>
</div>
{{else}}
<div role="main" aria-label="{{.Title}}" class="page-content user profile">
<div class="ui container">
<div class="ui stackable grid">
<div class="ui four wide column">
{{template "shared/user/profile_big_avatar" .}}
</div>
<div class="ui twelve wide column">
<div class="gt-mb-4">
{{template "user/overview/header" .}}
</div>
{{template "projects/list" .}}
</div>
</div>
</div>
</div>
{{end}}
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,9 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content organization projects edit-project new"> <div role="main" aria-label="{{.Title}}" class="page-content organization projects edit-project new">
{{template "shared/user/org_profile_avatar" .}}
<div class="ui container">
{{template "user/overview/header" .}} {{template "user/overview/header" .}}
{{template "projects/new" .}} {{template "projects/new" .}}
</div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,9 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository packages"> <div role="main" aria-label="{{.Title}}" class="page-content repository packages">
{{template "shared/user/org_profile_avatar" .}}
<div class="ui container">
{{template "user/overview/header" .}} {{template "user/overview/header" .}}
{{template "projects/view" .}} {{template "projects/view" .}}
</div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,8 +1,7 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository settings options"> <div role="main" aria-label="{{.Title}}" class="page-content repository settings options">
{{template "shared/user/org_profile_avatar" .}} {{template "user/overview/header" .}}
<div class="ui container"> <div class="ui container">
{{template "user/overview/header" .}}
{{template "base/alert" .}} {{template "base/alert" .}}
<p><a href="{{.PackageDescriptor.FullWebLink}}">{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</a> / <strong>{{.locale.Tr "repo.settings"}}</strong></p> <p><a href="{{.PackageDescriptor.FullWebLink}}">{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</a> / <strong>{{.locale.Tr "repo.settings"}}</strong></p>
<h4 class="ui top attached header"> <h4 class="ui top attached header">

View File

@ -1,3 +1,4 @@
<div class="ui container">
{{template "base/alert" .}} {{template "base/alert" .}}
<form class="ui form ignore-dirty"> <form class="ui form ignore-dirty">
<div class="ui fluid action input"> <div class="ui fluid action input">
@ -36,7 +37,7 @@
</li> </li>
{{else}} {{else}}
{{if not .HasPackages}} {{if not .HasPackages}}
<div class="gt-pt-5 empty center"> <div class="empty center">
{{svg "octicon-package" 48}} {{svg "octicon-package" 48}}
<h2>{{.locale.Tr "packages.empty"}}</h2> <h2>{{.locale.Tr "packages.empty"}}</h2>
{{if and .Repository .CanWritePackages}} {{if and .Repository .CanWritePackages}}
@ -51,3 +52,4 @@
{{end}} {{end}}
{{template "base/paginate" .}} {{template "base/paginate" .}}
</div> </div>
</div>

View File

@ -1,3 +1,4 @@
<div class="ui container">
<p><a href="{{.PackageDescriptor.PackageWebLink}}">{{.PackageDescriptor.Package.Name}}</a> / <strong>{{.locale.Tr "packages.versions"}}</strong></p> <p><a href="{{.PackageDescriptor.PackageWebLink}}">{{.PackageDescriptor.Package.Name}}</a> / <strong>{{.locale.Tr "packages.versions"}}</strong></p>
<form class="ui form ignore-dirty"> <form class="ui form ignore-dirty">
<div class="ui fluid action input"> <div class="ui fluid action input">
@ -35,3 +36,4 @@
{{end}} {{end}}
{{template "base/paginate" .}} {{template "base/paginate" .}}
</div> </div>
</div>

View File

@ -1,8 +1,7 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository view issue packages"> <div role="main" aria-label="{{.Title}}" class="page-content repository view issue packages">
{{template "shared/user/org_profile_avatar" .}} {{template "user/overview/header" .}}
<div class="ui container"> <div class="ui container">
{{template "user/overview/header" .}}
<div class="issue-title-header"> <div class="issue-title-header">
<div class="issue-title"> <div class="issue-title">
<h1>{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</h1> <h1>{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</h1>

View File

@ -1,6 +1,10 @@
<div role="main" aria-label="{{.Title}}" class="page-content repository projects">
<div class="ui container">
{{if .CanWriteProjects}} {{if .CanWriteProjects}}
<div class="gt-tr"> <div class="navbar">
<a class="ui small green button" href="{{$.Link}}/new">{{.locale.Tr "repo.projects.new"}}</a> <div class="ui right">
<a class="ui small green button" href="{{$.Link}}/new">{{.locale.Tr "repo.projects.new"}}</a>
</div>
</div> </div>
<div class="divider"></div> <div class="divider"></div>
{{end}} {{end}}
@ -71,6 +75,8 @@
{{template "base/paginate" .}} {{template "base/paginate" .}}
</div> </div>
</div>
</div>
{{if $.CanWriteProjects}} {{if $.CanWriteProjects}}
<div class="ui g-modal-confirm delete modal"> <div class="ui g-modal-confirm delete modal">

View File

@ -1,3 +1,4 @@
<div class="ui container">
<h2 class="ui dividing header"> <h2 class="ui dividing header">
{{if .PageIsEditProjects}} {{if .PageIsEditProjects}}
{{.locale.Tr "repo.projects.edit"}} {{.locale.Tr "repo.projects.edit"}}
@ -54,6 +55,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="ui container">
<div class="divider"></div> <div class="divider"></div>
<div class="ui left"> <div class="ui left">
<a class="ui cancel button" href="{{$.CancelLink}}"> <a class="ui cancel button" href="{{$.CancelLink}}">
@ -63,4 +65,6 @@
{{if .PageIsEditProjects}}{{.locale.Tr "repo.projects.modify"}}{{else}}{{.locale.Tr "repo.projects.create"}}{{end}} {{if .PageIsEditProjects}}{{.locale.Tr "repo.projects.modify"}}{{else}}{{.locale.Tr "repo.projects.create"}}{{end}}
</button> </button>
</div> </div>
</div>
</form> </form>
</div>

View File

@ -1,7 +1,20 @@
<div> {{if .DiffNotAvailable}}
<div class="diff-detail-box diff-box sticky gt-df gt-sb gt-ac gt-fw"> <div>
<div class="gt-df gt-ac gt-fw"> <div class="diff-detail-box diff-box sticky">
{{if not .DiffNotAvailable}} <div class="ui right">
{{template "repo/diff/whitespace_dropdown" .}}
{{template "repo/diff/options_dropdown" .}}
{{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}}
{{template "repo/diff/new_review" .}}
{{end}}
</div>
</div>
</div>
<h4>{{.locale.Tr "repo.diff.data_not_available"}}</h4>
{{else}}
<div>
<div class="diff-detail-box diff-box sticky gt-df gt-sb gt-ac gt-fw">
<div class="gt-df gt-ac gt-fw">
<button class="diff-toggle-file-tree-button gt-df gt-ac not-mobile" data-show-text="{{.locale.Tr "repo.diff.show_file_tree"}}" data-hide-text="{{.locale.Tr "repo.diff.hide_file_tree"}}"> <button class="diff-toggle-file-tree-button gt-df gt-ac not-mobile" data-show-text="{{.locale.Tr "repo.diff.show_file_tree"}}" data-hide-text="{{.locale.Tr "repo.diff.hide_file_tree"}}">
{{/* the icon meaning is reversed here, "octicon-sidebar-collapse" means show the file tree */}} {{/* the icon meaning is reversed here, "octicon-sidebar-collapse" means show the file tree */}}
{{svg "octicon-sidebar-collapse" 20 "icon gt-hidden"}} {{svg "octicon-sidebar-collapse" 20 "icon gt-hidden"}}
@ -18,25 +31,23 @@
<div class="diff-detail-stats gt-df gt-ac gt-fw"> <div class="diff-detail-stats gt-df gt-ac gt-fw">
{{svg "octicon-diff" 16 "gt-mr-2"}}{{.locale.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}} {{svg "octicon-diff" 16 "gt-mr-2"}}{{.locale.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}}
</div> </div>
{{end}} </div>
<div class="diff-detail-actions gt-df gt-ac gt-gap-2 gt-fw">
{{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}}
<div class="gt-df gt-ac gt-fc gt-whitespace-nowrap gt-mr-2">
<label for="viewed-files-summary" id="viewed-files-summary-label" data-text-changed-template="{{.locale.Tr "repo.pulls.viewed_files_label"}}">
{{.locale.Tr "repo.pulls.viewed_files_label" .Diff.NumViewedFiles .Diff.NumFiles}}
</label>
<progress id="viewed-files-summary" value="{{.Diff.NumViewedFiles}}" max="{{.Diff.NumFiles}}"></progress>
</div>
{{end}}
{{template "repo/diff/whitespace_dropdown" .}}
{{template "repo/diff/options_dropdown" .}}
{{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}}
{{template "repo/diff/new_review" .}}
{{end}}
</div>
</div> </div>
<div class="diff-detail-actions gt-df gt-ac gt-gap-2 gt-fw">
{{if and .PageIsPullFiles $.SignedUserID (not .IsArchived) (not .DiffNotAvailable)}}
<div class="gt-df gt-ac gt-fc gt-whitespace-nowrap gt-mr-2">
<label for="viewed-files-summary" id="viewed-files-summary-label" data-text-changed-template="{{.locale.Tr "repo.pulls.viewed_files_label"}}">
{{.locale.Tr "repo.pulls.viewed_files_label" .Diff.NumViewedFiles .Diff.NumFiles}}
</label>
<progress id="viewed-files-summary" value="{{.Diff.NumViewedFiles}}" max="{{.Diff.NumFiles}}"></progress>
</div>
{{end}}
{{template "repo/diff/whitespace_dropdown" .}}
{{template "repo/diff/options_dropdown" .}}
{{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}}
{{template "repo/diff/new_review" .}}
{{end}}
</div>
</div>
{{if not .DiffNotAvailable}}
<script id="diff-data-script" type="module"> <script id="diff-data-script" type="module">
const diffDataFiles = [{{range $i, $file := .Diff.Files}}{Name:"{{$file.Name}}",NameHash:"{{$file.NameHash}}",Type:{{$file.Type}},IsBin:{{$file.IsBin}},Addition:{{$file.Addition}},Deletion:{{$file.Deletion}},IsViewed:{{$file.IsViewed}}},{{end}}]; const diffDataFiles = [{{range $i, $file := .Diff.Files}}{Name:"{{$file.Name}}",NameHash:"{{$file.NameHash}}",Type:{{$file.Type}},IsBin:{{$file.IsBin}},Addition:{{$file.Addition}},Deletion:{{$file.Deletion}},IsViewed:{{$file.IsViewed}}},{{end}}];
const diffData = { const diffData = {
@ -63,160 +74,155 @@
window.config.pageData.diffFileInfo = diffFileInfo; window.config.pageData.diffFileInfo = diffFileInfo;
</script> </script>
<div id="diff-file-list"></div> <div id="diff-file-list"></div>
{{end}} <div id="diff-container">
<div id="diff-container"> <div id="diff-file-tree" class="gt-hidden"></div>
{{if .DiffNotAvailable}} <script>
<h4>{{.locale.Tr "repo.diff.data_not_available"}}</h4> if (diffTreeVisible) document.getElementById('diff-file-tree').classList.remove('gt-hidden');
{{else}} </script>
<div id="diff-file-tree" class="gt-hidden"></div> <div id="diff-file-boxes" class="sixteen wide column">
<script> {{range $i, $file := .Diff.Files}}
if (diffTreeVisible) document.getElementById('diff-file-tree').classList.remove('gt-hidden'); {{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
</script> {{$blobBase := call $.GetBlobByPathForCommit $.BeforeCommit $file.OldName}}
<div id="diff-file-boxes" class="sixteen wide column"> {{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}}
{{range $i, $file := .Diff.Files}} {{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}}
{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}} {{$isCsv := (call $.IsCsvFile $file)}}
{{$blobBase := call $.GetBlobByPathForCommit $.BeforeCommit $file.OldName}} {{$showFileViewToggle := or $isImage (and (not $file.IsIncomplete) $isCsv)}}
{{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}} {{$isExpandable := or (gt $file.Addition 0) (gt $file.Deletion 0) $file.IsBin}}
{{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}} {{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived)}}
{{$isCsv := (call $.IsCsvFile $file)}} <div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} gt-mt-3" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if or ($file.ShouldBeHidden) (not $isExpandable)}}data-folded="true"{{end}}>
{{$showFileViewToggle := or $isImage (and (not $file.IsIncomplete) $isCsv)}} <h4 class="diff-file-header sticky-2nd-row ui top attached normal header gt-df gt-ac gt-sb gt-fw">
{{$isExpandable := or (gt $file.Addition 0) (gt $file.Deletion 0) $file.IsBin}} <div class="diff-file-name gt-df gt-ac gt-gap-2 gt-fw">
{{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived)}} <button class="fold-file btn interact-bg gt-p-2{{if not $isExpandable}} gt-invisible{{end}}">
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} gt-mt-3" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if or ($file.ShouldBeHidden) (not $isExpandable)}}data-folded="true"{{end}}> {{if $file.ShouldBeHidden}}
<h4 class="diff-file-header sticky-2nd-row ui top attached normal header gt-df gt-ac gt-sb gt-fw"> {{svg "octicon-chevron-right" 18}}
<div class="diff-file-name gt-df gt-ac gt-gap-2 gt-fw"> {{else}}
<button class="fold-file btn interact-bg gt-p-2{{if not $isExpandable}} gt-invisible{{end}}"> {{svg "octicon-chevron-down" 18}}
{{if $file.ShouldBeHidden}} {{end}}
{{svg "octicon-chevron-right" 18}} </button>
{{else}} <div class="gt-font-semibold gt-df gt-ac gt-mono">
{{svg "octicon-chevron-down" 18}} {{if $file.IsBin}}
<span class="gt-ml-1 gt-mr-3">
{{$.locale.Tr "repo.diff.bin"}}
</span>
{{else}}
{{template "repo/diff/stats" dict "file" . "root" $}}
{{end}}
</div>
<span class="file gt-mono"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}</a>{{if .IsLFSFile}} ({{$.locale.Tr "repo.stored_lfs"}}){{end}}</span>
<button class="btn interact-fg gt-p-3" data-clipboard-text="{{$file.Name}}">{{svg "octicon-copy" 14}}</button>
{{if $file.IsGenerated}}
<span class="ui label">{{$.locale.Tr "repo.diff.generated"}}</span>
{{end}} {{end}}
</button> {{if $file.IsVendored}}
<div class="gt-font-semibold gt-df gt-ac gt-mono"> <span class="ui label">{{$.locale.Tr "repo.diff.vendored"}}</span>
{{if $file.IsBin}} {{end}}
<span class="gt-ml-1 gt-mr-3"> {{if and $file.Mode $file.OldMode}}
{{$.locale.Tr "repo.diff.bin"}} <span class="gt-ml-4 gt-mono">{{$file.OldMode}} &rarr; {{$file.Mode}}</span>
</span> {{else if $file.Mode}}
{{else}} <span class="gt-ml-4 gt-mono">{{$file.Mode}}</span>
{{template "repo/diff/stats" dict "file" . "root" $}}
{{end}} {{end}}
</div> </div>
<span class="file gt-mono"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}</a>{{if .IsLFSFile}} ({{$.locale.Tr "repo.stored_lfs"}}){{end}}</span> <div class="diff-file-header-actions gt-df gt-ac gt-gap-2 gt-fw">
<button class="btn interact-fg gt-p-3" data-clipboard-text="{{$file.Name}}">{{svg "octicon-copy" 14}}</button> {{if $showFileViewToggle}}
{{if $file.IsGenerated}} <div class="ui compact icon buttons">
<span class="ui label">{{$.locale.Tr "repo.diff.generated"}}</span> <button class="ui tiny basic button file-view-toggle" data-toggle-selector="#diff-source-{{$file.NameHash}}" data-tooltip-content="{{$.locale.Tr "repo.file_view_source"}}">{{svg "octicon-code"}}</button>
{{end}} <button class="ui tiny basic button file-view-toggle active" data-toggle-selector="#diff-rendered-{{$file.NameHash}}" data-tooltip-content="{{$.locale.Tr "repo.file_view_rendered"}}">{{svg "octicon-file"}}</button>
{{if $file.IsVendored}} </div>
<span class="ui label">{{$.locale.Tr "repo.diff.vendored"}}</span>
{{end}}
{{if and $file.Mode $file.OldMode}}
<span class="gt-ml-4 gt-mono">{{$file.OldMode}} &rarr; {{$file.Mode}}</span>
{{else if $file.Mode}}
<span class="gt-ml-4 gt-mono">{{$file.Mode}}</span>
{{end}}
</div>
<div class="diff-file-header-actions gt-df gt-ac gt-gap-2 gt-fw">
{{if $showFileViewToggle}}
<div class="ui compact icon buttons">
<button class="ui tiny basic button file-view-toggle" data-toggle-selector="#diff-source-{{$file.NameHash}}" data-tooltip-content="{{$.locale.Tr "repo.file_view_source"}}">{{svg "octicon-code"}}</button>
<button class="ui tiny basic button file-view-toggle active" data-toggle-selector="#diff-rendered-{{$file.NameHash}}" data-tooltip-content="{{$.locale.Tr "repo.file_view_rendered"}}">{{svg "octicon-file"}}</button>
</div>
{{end}}
{{if $file.IsProtected}}
<span class="ui basic label">{{$.locale.Tr "repo.diff.protected"}}</span>
{{end}}
{{if and $isReviewFile $file.HasChangedSinceLastReview}}
<span class="changed-since-last-review unselectable not-mobile">{{$.locale.Tr "repo.pulls.has_changed_since_last_review"}}</span>
{{end}}
{{if not (or $file.IsIncomplete $file.IsBin $file.IsSubmodule)}}
<button class="ui basic tiny button unescape-button not-mobile">{{$.locale.Tr "repo.unescape_control_characters"}}</button>
<button class="ui basic tiny button escape-button gt-hidden">{{$.locale.Tr "repo.escape_control_characters"}}</button>
{{end}}
{{if and (not $file.IsSubmodule) (not $.PageIsWiki)}}
{{if $file.IsDeleted}}
<a class="ui basic tiny button" rel="nofollow" href="{{$.BeforeSourcePath}}/{{PathEscapeSegments .Name}}">{{$.locale.Tr "repo.diff.view_file"}}</a>
{{else}}
<a class="ui basic tiny button" rel="nofollow" href="{{$.SourcePath}}/{{PathEscapeSegments .Name}}">{{$.locale.Tr "repo.diff.view_file"}}</a>
{{end}} {{end}}
{{end}} {{if $file.IsProtected}}
{{if $isReviewFile}} <span class="ui basic label">{{$.locale.Tr "repo.diff.protected"}}</span>
<label data-link="{{$.Issue.Link}}/viewed-files" data-headcommit="{{$.AfterCommitID}}" class="viewed-file-form unselectable{{if $file.IsViewed}} viewed-file-checked-form{{end}}"> {{end}}
<input type="checkbox" name="{{$file.GetDiffFileName}}" autocomplete="off"{{if $file.IsViewed}} checked{{end}}> {{$.locale.Tr "repo.pulls.has_viewed_file"}} {{if and $isReviewFile $file.HasChangedSinceLastReview}}
</label> <span class="changed-since-last-review unselectable not-mobile">{{$.locale.Tr "repo.pulls.has_changed_since_last_review"}}</span>
{{end}} {{end}}
</div> {{if not (or $file.IsIncomplete $file.IsBin $file.IsSubmodule)}}
</h4> <button class="ui basic tiny button unescape-button not-mobile">{{$.locale.Tr "repo.unescape_control_characters"}}</button>
<div class="diff-file-body ui attached unstackable table segment" {{if $file.IsViewed}}data-folded="true"{{end}}> <button class="ui basic tiny button escape-button gt-hidden">{{$.locale.Tr "repo.escape_control_characters"}}</button>
<div id="diff-source-{{$file.NameHash}}" class="file-body file-code unicode-escaped code-diff{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $showFileViewToggle}} gt-hidden{{end}}"> {{end}}
{{if or $file.IsIncomplete $file.IsBin}} {{if and (not $file.IsSubmodule) (not $.PageIsWiki)}}
<div class="diff-file-body binary" style="padding: 5px 10px;"> {{if $file.IsDeleted}}
{{if $file.IsIncomplete}} <a class="ui basic tiny button" rel="nofollow" href="{{$.BeforeSourcePath}}/{{PathEscapeSegments .Name}}">{{$.locale.Tr "repo.diff.view_file"}}</a>
{{if $file.IsIncompleteLineTooLong}} {{else}}
{{$.locale.Tr "repo.diff.file_suppressed_line_too_long"}} <a class="ui basic tiny button" rel="nofollow" href="{{$.SourcePath}}/{{PathEscapeSegments .Name}}">{{$.locale.Tr "repo.diff.view_file"}}</a>
{{end}}
{{end}}
{{if $isReviewFile}}
<label data-link="{{$.Issue.Link}}/viewed-files" data-headcommit="{{$.AfterCommitID}}" class="viewed-file-form unselectable{{if $file.IsViewed}} viewed-file-checked-form{{end}}">
<input type="checkbox" name="{{$file.GetDiffFileName}}" autocomplete="off"{{if $file.IsViewed}} checked{{end}}> {{$.locale.Tr "repo.pulls.has_viewed_file"}}
</label>
{{end}}
</div>
</h4>
<div class="diff-file-body ui attached unstackable table segment" {{if $file.IsViewed}}data-folded="true"{{end}}>
<div id="diff-source-{{$file.NameHash}}" class="file-body file-code unicode-escaped code-diff{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $showFileViewToggle}} gt-hidden{{end}}">
{{if or $file.IsIncomplete $file.IsBin}}
<div class="diff-file-body binary" style="padding: 5px 10px;">
{{if $file.IsIncomplete}}
{{if $file.IsIncompleteLineTooLong}}
{{$.locale.Tr "repo.diff.file_suppressed_line_too_long"}}
{{else}}
{{$.locale.Tr "repo.diff.file_suppressed"}}
<a class="ui basic tiny button diff-load-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{$.locale.Tr "repo.diff.load"}}</a>
{{end}}
{{else}} {{else}}
{{$.locale.Tr "repo.diff.file_suppressed"}} {{$.locale.Tr "repo.diff.bin_not_shown"}}
<a class="ui basic tiny button diff-load-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{$.locale.Tr "repo.diff.load"}}</a>
{{end}} {{end}}
{{else}} </div>
{{$.locale.Tr "repo.diff.bin_not_shown"}} {{else}}
{{end}} <table class="chroma" data-new-comment-url="{{$.Issue.Link}}/files/reviews/new_comment" data-path="{{$file.Name}}">
{{if $.IsSplitStyle}}
{{template "repo/diff/section_split" dict "file" . "root" $}}
{{else}}
{{template "repo/diff/section_unified" dict "file" . "root" $}}
{{end}}
</table>
{{end}}
</div>
{{if $showFileViewToggle}}
{{/* for image or CSV, it can have a horizontal scroll bar, there won't be review comment context menu (position absolute) which would be clipped by "overflow" */}}
<div id="diff-rendered-{{$file.NameHash}}" class="file-body file-code {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}} gt-overflow-x-scroll">
<table class="chroma gt-w-100">
{{if $isImage}}
{{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}}
{{else}}
{{template "repo/diff/csv_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}}
{{end}}
</table>
</div> </div>
{{else}}
<table class="chroma" data-new-comment-url="{{$.Issue.Link}}/files/reviews/new_comment" data-path="{{$file.Name}}">
{{if $.IsSplitStyle}}
{{template "repo/diff/section_split" dict "file" . "root" $}}
{{else}}
{{template "repo/diff/section_unified" dict "file" . "root" $}}
{{end}}
</table>
{{end}} {{end}}
</div> </div>
{{if $showFileViewToggle}}
{{/* for image or CSV, it can have a horizontal scroll bar, there won't be review comment context menu (position absolute) which would be clipped by "overflow" */}}
<div id="diff-rendered-{{$file.NameHash}}" class="file-body file-code {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}} gt-overflow-x-scroll">
<table class="chroma gt-w-100">
{{if $isImage}}
{{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}}
{{else}}
{{template "repo/diff/csv_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}}
{{end}}
</table>
</div>
{{end}}
</div> </div>
</div> {{end}}
{{end}}
{{if .Diff.IsIncomplete}} {{if .Diff.IsIncomplete}}
<div class="diff-file-box diff-box file-content gt-mt-3" id="diff-incomplete"> <div class="diff-file-box diff-box file-content gt-mt-3" id="diff-incomplete">
<h4 class="ui top attached normal header gt-df gt-ac gt-sb"> <h4 class="ui top attached normal header gt-df gt-ac gt-sb">
{{$.locale.Tr "repo.diff.too_many_files"}} {{$.locale.Tr "repo.diff.too_many_files"}}
<a class="ui basic tiny button" id="diff-show-more-files" data-href="{{$.Link}}?skip-to={{.Diff.End}}&file-only=true">{{.locale.Tr "repo.diff.show_more"}}</a> <a class="ui basic tiny button" id="diff-show-more-files" data-href="{{$.Link}}?skip-to={{.Diff.End}}&file-only=true">{{.locale.Tr "repo.diff.show_more"}}</a>
</h4> </h4>
</div> </div>
{{end}} {{end}}
</div>
{{end}}
</div>
{{if and (not $.Repository.IsArchived) (not .DiffNotAvailable)}}
<template id="issue-comment-editor-template">
<div class="ui comment form">
{{template "shared/combomarkdowneditor" (dict
"locale" $.locale
"MarkdownPreviewUrl" (print $.Repository.Link "/markup")
"MarkdownPreviewContext" $.RepoLink
"TextareaName" "content"
"DropzoneParentContainer" ".ui.form"
)}}
<div class="text right edit buttons">
<button class="ui basic primary cancel button" tabindex="3">{{.locale.Tr "repo.issues.cancel"}}</button>
<button class="ui green save button" tabindex="2">{{.locale.Tr "repo.issues.save"}}</button>
</div> </div>
</div> </div>
</template>
{{end}} {{if not $.Repository.IsArchived}}
{{if (not .DiffNotAvailable)}} <template id="issue-comment-editor-template">
<div class="ui comment form">
{{template "shared/combomarkdowneditor" (dict
"locale" $.locale
"MarkdownPreviewUrl" (print $.Repository.Link "/markup")
"MarkdownPreviewContext" $.RepoLink
"TextareaName" "content"
"DropzoneParentContainer" ".ui.form"
)}}
<div class="text right edit buttons">
<button class="ui basic primary cancel button" tabindex="3">{{.locale.Tr "repo.issues.cancel"}}</button>
<button class="ui green save button" tabindex="2">{{.locale.Tr "repo.issues.save"}}</button>
</div>
</div>
</template>
{{end}}
{{template "repo/issue/view_content/reference_issue_dialog" .}} {{template "repo/issue/view_content/reference_issue_dialog" .}}
{{end}} </div>
</div> {{end}}

View File

@ -1,8 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository packages"> <div role="main" aria-label="{{.Title}}" class="page-content repository packages">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container">
{{template "package/shared/list" .}} {{template "package/shared/list" .}}
</div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,8 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository projects edit-project new milestone"> <div role="main" aria-label="{{.Title}}" class="page-content repository projects edit-project new milestone">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container">
{{template "projects/new" .}} {{template "projects/new" .}}
</div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -9,7 +9,7 @@
{{$.locale.Tr "repo.pulls.tab_commits"}} {{$.locale.Tr "repo.pulls.tab_commits"}}
<span class="ui small label">{{if .NumCommits}}{{.NumCommits}}{{else}}-{{end}}</span> <span class="ui small label">{{if .NumCommits}}{{.NumCommits}}{{else}}-{{end}}</span>
</a> </a>
<a class="item {{if .PageIsPullFiles}}active{{end}}" href="{{.Issue.Link}}/files"> <a class="item {{if .PageIsPullFiles}}active{{end}}" {{if .NumFiles}}href="{{.Issue.Link}}/files"{{end}}>
{{svg "octicon-diff"}} {{svg "octicon-diff"}}
{{$.locale.Tr "repo.pulls.tab_files"}} {{$.locale.Tr "repo.pulls.tab_files"}}
<span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span> <span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span>

View File

@ -1,16 +0,0 @@
{{with .ContextUser}}
<div class="ui container">
<div class="ui vertically grid head">
<div class="column">
<div class="ui header">
{{avatar $.Context . 100}}
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
<span class="org-visibility">
{{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
{{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
</span>
</div>
</div>
</div>
</div>
{{end}}

View File

@ -1,116 +0,0 @@
<div class="ui card">
<div id="profile-avatar" class="content gt-df">
{{if eq .SignedUserID .ContextUser.ID}}
<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{.locale.Tr "user.change_avatar"}}">
{{/* the size doesn't take affect (and no need to take affect), image size(width) should be controlled by the parent container since this is not a flex layout*/}}
{{avatar $.Context .ContextUser 256}}
</a>
{{else}}
<span class="image">
{{avatar $.Context .ContextUser 256}}
</span>
{{end}}
</div>
<div class="content gt-word-break profile-avatar-name">
{{if .ContextUser.FullName}}<span class="header text center">{{.ContextUser.FullName}}</span>{{end}}
<span class="username text center">{{.ContextUser.Name}}</span>
{{if .EnableFeed}}
<a href="{{.ContextUser.HomeLink}}.rss"><i class="ui text grey gt-ml-3" data-tooltip-content="{{.locale.Tr "rss_feed"}}">{{svg "octicon-rss" 18}}</i></a>
{{end}}
<div class="gt-mt-3">
<a class="muted" href="{{.ContextUser.HomeLink}}?tab=followers">{{svg "octicon-person" 18 "gt-mr-2"}}{{.NumFollowers}} {{.locale.Tr "user.followers"}}</a> · <a class="muted" href="{{.ContextUser.HomeLink}}?tab=following">{{.NumFollowing}} {{.locale.Tr "user.following"}}</a>
</div>
</div>
<div class="extra content gt-word-break">
<ul>
{{if .ContextUser.Location}}
<li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li>
{{end}}
{{if (eq .SignedUserID .ContextUser.ID)}}
<li>
{{svg "octicon-mail"}}
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
<a href="{{AppSubUrl}}/user/settings#keep-email-private">
{{if .ShowUserEmail}}
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
{{svg "octicon-unlock"}}
</i>
{{else}}
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
{{svg "octicon-lock"}}
</i>
{{end}}
</a>
</li>
{{else}}
{{if .ShowUserEmail}}
<li>
{{svg "octicon-mail"}}
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
</li>
{{end}}
{{end}}
{{if .ContextUser.Website}}
<li>
{{svg "octicon-link"}}
<a target="_blank" rel="noopener noreferrer me" href="{{.ContextUser.Website}}">{{.ContextUser.Website}}</a>
</li>
{{end}}
{{if $.RenderedDescription}}
<li>
<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div>
</li>
{{end}}
{{range .OpenIDs}}
{{if .Show}}
<li>
{{svg "fontawesome-openid"}}
<a target="_blank" rel="noopener noreferrer" href="{{.URI}}">{{.URI}}</a>
</li>
{{end}}
{{end}}
<li>{{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li>
{{if and .Orgs .HasOrgsVisible}}
<li>
<ul class="user-orgs">
{{range .Orgs}}
{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
<li>
<a href="{{.HomeLink}}" data-tooltip-content="{{.Name}}">
{{avatar $.Context .}}
</a>
</li>
{{end}}
{{end}}
</ul>
</li>
{{end}}
{{if .Badges}}
<li>
<ul class="user-badges">
{{range .Badges}}
<li>
<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
</li>
{{end}}
</ul>
</li>
{{end}}
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
<li class="follow">
{{if $.IsFollowing}}
<form method="post" action="{{.Link}}?action=unfollow&redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui basic red button">{{svg "octicon-person"}} {{.locale.Tr "user.unfollow"}}</button>
</form>
{{else}}
<form method="post" action="{{.Link}}?action=follow&redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui basic green button">{{svg "octicon-person"}} {{.locale.Tr "user.follow"}}</button>
</form>
{{end}}
</li>
{{end}}
</ul>
</div>
</div>

View File

@ -1,25 +1,25 @@
{{template "base/head" .}} {{template "base/head" .}}
{{if .ContextUser.IsOrganization}} <div role="main" aria-label="{{.Title}}" class="page-content repository code-search">
<div role="main" aria-label="{{.Title}}" class="page-content repository"> {{template "user/overview/header" .}}
{{template "shared/user/org_profile_avatar" .}} <div class="ui container">
<div class="ui container"> {{template "code/searchform" .}}
{{template "user/overview/header" .}} <div class="divider"></div>
{{template "code/searchcombo" .}} <div class="ui user list">
</div> {{if .CodeIndexerUnavailable}}
</div> <div class="ui error message">
{{else}} <p>{{$.locale.Tr "explore.code_search_unavailable"}}</p>
<div role="main" aria-label="{{.Title}}" class="page-content user profile">
<div class="ui container">
<div class="ui stackable grid">
<div class="ui four wide column">
{{template "shared/user/profile_big_avatar" .}}
</div> </div>
<div class="ui twelve wide column"> {{else if .SearchResults}}
{{template "user/overview/header" .}} <h3>
{{template "code/searchcombo" .}} {{.locale.Tr "explore.code_search_results" (.Keyword|Escape) | Str2html}}
</div> </h3>
</div> {{template "code/searchresults" .}}
{{else if .Keyword}}
<div>{{$.locale.Tr "explore.code_no_results"}}</div>
{{end}}
</div> </div>
{{template "base/paginate" .}}
</div> </div>
{{end}} </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,69 +1,92 @@
<div class="ui secondary stackable pointing menu"> <!-- TODO: make template org and user can share -->
{{if .HasProfileReadme}} {{if or (.IsPackagesPage) (.PageIsViewProjects)}}
<a class='{{if eq .TabName "overview"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=overview"> {{with .ContextUser}}
{{svg "octicon-info"}} {{.locale.Tr "user.overview"}} <div class="ui container">
</a> <div class="ui vertically grid head">
{{end}} <div class="column">
<a class="{{if eq .TabName "repositories"}}active {{end}} item" href="{{.ContextUser.HomeLink}}?tab=repositories"> <div class="ui header">
{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}} {{avatar $.Context . 100}}
{{if .ContextUser.NumRepos}} <span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
<div class="ui small label">{{.ContextUser.NumRepos}}</div> <span class="org-visibility">
{{end}} {{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
</a> {{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
{{if or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects)}} </span>
<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item"> </div>
{{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}}
</a>
{{end}}
{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
</a>
{{end}}
{{if and .IsRepoIndexerEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadCode))}}
<a href="{{.ContextUser.HomeLink}}/-/code" class="{{if .IsCodePage}}active {{end}}item">
{{svg "octicon-code"}} {{.locale.Tr "user.code"}}
</a>
{{end}}
{{if .ContextUser.IsOrganization}}
{{if .IsOrganizationMember}}
<a class="item" href="{{$.OrgLink}}/members">
{{svg "octicon-person"}}&nbsp;{{$.locale.Tr "org.members"}}
{{if .NumMembers}}
<div class="ui small label">{{.NumMembers}}</div>
{{end}}
</a>
<a class="item" href="{{$.OrgLink}}/teams">
{{svg "octicon-people"}}&nbsp;{{$.locale.Tr "org.teams"}}
{{if .NumTeams}}
<div class="ui small label">{{.NumTeams}}</div>
{{end}}
</a>
{{end}}
{{if .IsOrganizationOwner}}
<div class="right menu">
<a class="item" href="{{.OrgLink}}/settings">
{{svg "octicon-tools"}} {{.locale.Tr "repo.settings"}}
</a>
</div> </div>
{{end}} </div>
{{else}} </div>
<a class='{{if eq .TabName "activity"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=activity">
{{svg "octicon-rss"}} {{.locale.Tr "user.activity"}}
</a>
{{if not .DisableStars}}
<a class='{{if eq .TabName "stars"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=stars">
{{svg "octicon-star"}} {{.locale.Tr "user.starred"}}
{{if .ContextUser.NumStars}}
<div class="ui small label">{{.ContextUser.NumStars}}</div>
{{end}}
</a>
{{else}}
<a class='{{if eq .TabName "watching"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=watching">
{{svg "octicon-eye"}} {{.locale.Tr "user.watched"}}
</a>
{{end}}
{{end}} {{end}}
{{end}}
<div class="ui tabs container">
<div class="ui secondary stackable pointing menu">
{{if .ProfileReadme}}
<a class='{{if or (eq .TabName "overview") (and (eq .TabName "") (not .IsPackagesPage) (not .PageIsViewProjects))}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=overview">
{{svg "octicon-info"}} {{.locale.Tr "user.overview"}}
</a>
{{end}}
<a class="{{if or (eq .TabName "repositories") (and (eq .TabName "") (not .IsPackagesPage) (not .PageIsViewProjects) (not .ProfileReadme))}}active {{end}} item" href="{{.ContextUser.HomeLink}}?tab=repositories">
{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
{{if .ContextUser.NumRepos}}
<div class="ui small label">{{.ContextUser.NumRepos}}</div>
{{end}}
</a>
{{if and .IsProjectEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects))}}
<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
{{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}}
</a>
{{end}}
{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
</a>
{{end}}
{{if and .IsRepoIndexerEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadCode))}}
<a href="{{.ContextUser.HomeLink}}/-/code" class="{{if .IsCodePage}}active {{end}}item">
{{svg "octicon-code"}} {{.locale.Tr "user.code"}}
</a>
{{end}}
{{if .ContextUser.IsOrganization}}
{{if .IsOrganizationMember}}
<a class="item" href="{{$.OrgLink}}/members">
{{svg "octicon-person"}}&nbsp;{{$.locale.Tr "org.members"}}
{{if .NumMembers}}
<div class="ui small label">{{.NumMembers}}</div>
{{end}}
</a>
<a class="item" href="{{$.OrgLink}}/teams">
{{svg "octicon-people"}}&nbsp;{{$.locale.Tr "org.teams"}}
{{if .NumTeams}}
<div class="ui small label">{{.NumTeams}}</div>
{{end}}
</a>
{{end}}
{{if .IsOrganizationOwner}}
<div class="right menu">
<a class="item" href="{{.OrgLink}}/settings">
{{svg "octicon-tools"}} {{.locale.Tr "repo.settings"}}
</a>
</div>
{{end}}
{{else}}
<a class='{{if eq .TabName "activity"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=activity">
{{svg "octicon-rss"}} {{.locale.Tr "user.activity"}}
</a>
{{if not .DisableStars}}
<a class='{{if eq .TabName "stars"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=stars">
{{svg "octicon-star"}} {{.locale.Tr "user.starred"}}
{{if .ContextUser.NumStars}}
<div class="ui small label">{{.ContextUser.NumStars}}</div>
{{end}}
</a>
{{else}}
<a class='{{if eq .TabName "watching"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=watching">
{{svg "octicon-eye"}} {{.locale.Tr "user.watched"}}
</a>
{{end}}
{{end}}
</div>
</div> </div>

View File

@ -1,27 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
{{if .ContextUser.IsOrganization}} <div role="main" aria-label="{{.Title}}" class="page-content repository packages">
<div role="main" aria-label="{{.Title}}" class="page-content repository packages"> {{template "user/overview/header" .}}
{{template "shared/user/org_profile_avatar" .}} {{template "package/shared/versionlist" .}}
<div class="ui container">
{{template "user/overview/header" .}}
{{template "package/shared/versionlist" .}}
</div>
</div>
{{else}}
<div role="main" aria-label="{{.Title}}" class="page-content user profile packages">
<div class="ui container">
<div class="ui stackable grid">
<div class="ui four wide column">
{{template "shared/user/profile_big_avatar" .}}
</div>
<div class="ui twelve wide column">
<div class="gt-mb-4">
{{template "user/overview/header" .}}
</div>
{{template "package/shared/versionlist" .}}
</div>
</div>
</div>
</div> </div>
{{end}}
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -1,27 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
{{if .ContextUser.IsOrganization}} <div role="main" aria-label="{{.Title}}" class="page-content repository packages">
<div role="main" aria-label="{{.Title}}" class="page-content repository packages"> {{template "user/overview/header" .}}
{{template "shared/user/org_profile_avatar" .}} {{template "package/shared/list" .}}
<div class="ui container"> </div>
{{template "user/overview/header" .}}
{{template "package/shared/list" .}}
</div>
</div>
{{else}}
<div role="main" aria-label="{{.Title}}" class="page-content user profile packages">
<div class="ui container">
<div class="ui stackable grid">
<div class="ui four wide column">
{{template "shared/user/profile_big_avatar" .}}
</div>
<div class="ui twelve wide column">
<div class="gt-mb-4">
{{template "user/overview/header" .}}
</div>
{{template "package/shared/list" .}}
</div>
</div>
</div>
</div>
{{end}}
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -3,10 +3,125 @@
<div class="ui container"> <div class="ui container">
<div class="ui stackable grid"> <div class="ui stackable grid">
<div class="ui four wide column"> <div class="ui four wide column">
{{template "shared/user/profile_big_avatar" .}} <div class="ui card">
<div id="profile-avatar" class="content gt-df">
{{if eq .SignedUserID .ContextUser.ID}}
<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{.locale.Tr "user.change_avatar"}}">
{{/* the size doesn't take affect (and no need to take affect), image size(width) should be controlled by the parent container since this is not a flex layout*/}}
{{avatar $.Context .ContextUser 256}}
</a>
{{else}}
<span class="image">
{{avatar $.Context .ContextUser 256}}
</span>
{{end}}
</div>
<div class="content gt-word-break profile-avatar-name">
{{if .ContextUser.FullName}}<span class="header text center">{{.ContextUser.FullName}}</span>{{end}}
<span class="username text center">{{.ContextUser.Name}}</span>
{{if .EnableFeed}}
<a href="{{.ContextUser.HomeLink}}.rss"><i class="ui text grey gt-ml-3" data-tooltip-content="{{.locale.Tr "rss_feed"}}">{{svg "octicon-rss" 18}}</i></a>
{{end}}
<div class="gt-mt-3">
<a class="muted" href="{{.ContextUser.HomeLink}}?tab=followers">{{svg "octicon-person" 18 "gt-mr-2"}}{{.NumFollowers}} {{.locale.Tr "user.followers"}}</a> · <a class="muted" href="{{.ContextUser.HomeLink}}?tab=following">{{.NumFollowing}} {{.locale.Tr "user.following"}}</a>
</div>
</div>
<div class="extra content gt-word-break">
<ul>
{{if .ContextUser.Location}}
<li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li>
{{end}}
{{if (eq .SignedUserID .ContextUser.ID)}}
<li>
{{svg "octicon-mail"}}
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
<a href="{{AppSubUrl}}/user/settings#privacy-user-settings">
{{if .ShowUserEmail}}
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
{{svg "octicon-unlock"}}
</i>
{{else}}
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
{{svg "octicon-lock"}}
</i>
{{end}}
</a>
</li>
{{else}}
{{if .ShowUserEmail}}
<li>
{{svg "octicon-mail"}}
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
</li>
{{end}}
{{end}}
{{if .ContextUser.Website}}
<li>
{{svg "octicon-link"}}
<a target="_blank" rel="noopener noreferrer me" href="{{.ContextUser.Website}}">{{.ContextUser.Website}}</a>
</li>
{{end}}
{{if $.RenderedDescription}}
<li>
<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div>
</li>
{{end}}
{{range .OpenIDs}}
{{if .Show}}
<li>
{{svg "fontawesome-openid"}}
<a target="_blank" rel="noopener noreferrer" href="{{.URI}}">{{.URI}}</a>
</li>
{{end}}
{{end}}
<li>{{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li>
{{if and .Orgs .HasOrgsVisible}}
<li>
<ul class="user-orgs">
{{range .Orgs}}
{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
<li>
<a href="{{.HomeLink}}" data-tooltip-content="{{.Name}}">
{{avatar $.Context .}}
</a>
</li>
{{end}}
{{end}}
</ul>
</li>
{{end}}
{{if .Badges}}
<li>
<ul class="user-badges">
{{range .Badges}}
<li>
<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
</li>
{{end}}
</ul>
</li>
{{end}}
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
<li class="follow">
{{if $.IsFollowing}}
<form method="post" action="{{.Link}}?action=unfollow&redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui basic red button">{{svg "octicon-person"}} {{.locale.Tr "user.unfollow"}}</button>
</form>
{{else}}
<form method="post" action="{{.Link}}?action=follow&redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui basic green button">{{svg "octicon-person"}} {{.locale.Tr "user.follow"}}</button>
</form>
{{end}}
</li>
{{end}}
</ul>
</div>
</div>
</div> </div>
<div class="ui twelve wide column"> <div class="ui twelve wide column">
<div class="gt-mb-4"> <div class="gt-mb-4 gt-df">
{{template "user/overview/header" .}} {{template "user/overview/header" .}}
</div> </div>
@ -30,12 +145,12 @@
{{template "repo/user_cards" .}} {{template "repo/user_cards" .}}
{{else if eq .TabName "followers"}} {{else if eq .TabName "followers"}}
{{template "repo/user_cards" .}} {{template "repo/user_cards" .}}
{{else if eq .TabName "overview"}} {{else if or (eq .TabName "repositories") (not .ProfileReadme)}}
<div id="readme_profile" class="markup">{{.ProfileReadme | Str2html}}</div>
{{else}}
{{template "explore/repo_search" .}} {{template "explore/repo_search" .}}
{{template "explore/repo_list" .}} {{template "explore/repo_list" .}}
{{template "base/paginate" .}} {{template "base/paginate" .}}
{{else if .ProfileReadme}}
<div id="readme_profile" class="render-content markup"> {{$.ProfileReadme|Str2html}} </div>
{{end}} {{end}}
</div> </div>
</div> </div>

View File

@ -11,7 +11,6 @@ Gitea's private styles use `g-` prefix.
.gt-ab { align-items: baseline !important; } .gt-ab { align-items: baseline !important; }
.gt-tc { text-align: center !important; } .gt-tc { text-align: center !important; }
.gt-tl { text-align: left !important; } .gt-tl { text-align: left !important; }
.gt-tr { text-align: right !important; } /* TODO: rename these to "gt-text-right", etc. there are only a few */
.gt-jc { justify-content: center !important; } .gt-jc { justify-content: center !important; }
.gt-js { justify-content: flex-start !important; } .gt-js { justify-content: flex-start !important; }
.gt-je { justify-content: flex-end !important; } .gt-je { justify-content: flex-end !important; }

View File

@ -1313,9 +1313,10 @@
padding: 5px 10px; padding: 5px 10px;
} }
.repository #commits-table td:not(.message) { .repository #commits-table thead th:first-of-type {
white-space: nowrap; padding-left: 15px;
} }
.repository #commits-table thead .sha { .repository #commits-table thead .sha {
width: 200px; width: 200px;
} }
@ -2683,7 +2684,6 @@ tbody.commit-list {
/* in the commit list, messages can wrap so we can use inline */ /* in the commit list, messages can wrap so we can use inline */
.commit-list .message-wrapper { .commit-list .message-wrapper {
display: inline; display: inline;
overflow-wrap: anywhere;
} }
/* but in the repo-files-table we cannot */ /* but in the repo-files-table we cannot */
@ -3244,6 +3244,17 @@ tbody.commit-list {
.commit-table th.sha { .commit-table th.sha {
display: none !important; display: none !important;
} }
.commit-table .commit-list span.message-wrapper {
max-width: none;
}
.commit-table .commit-list tr td:first-child,
.commit-table .commit-list tr td:last-child {
white-space: nowrap;
}
.commit-table .commit-list td.author {
display: block;
width: calc(100% + 0.5rem);
}
.commit-table .commit-list .copy-commit-sha { .commit-table .commit-list .copy-commit-sha {
display: none !important; display: none !important;
} }