Code style update; Project cleanup
parent
e6f5ac6fe4
commit
2f247cfb40
|
@ -17,7 +17,7 @@ namespace MongoAuth
|
|||
var returnArray = new byte[byteCount];
|
||||
|
||||
byte curByte = 0,
|
||||
bitsRemaining = 8;
|
||||
bitsRemaining = 8;
|
||||
|
||||
int arrayIndex = 0;
|
||||
|
||||
|
@ -62,7 +62,7 @@ namespace MongoAuth
|
|||
var returnArray = new char[charCount];
|
||||
|
||||
byte nextChar = 0,
|
||||
bitsRemaining = 5;
|
||||
bitsRemaining = 5;
|
||||
int arrayIndex = 0;
|
||||
|
||||
foreach (byte b in input)
|
||||
|
@ -86,7 +86,9 @@ namespace MongoAuth
|
|||
{
|
||||
returnArray[arrayIndex++] = ValueToChar(nextChar);
|
||||
while (arrayIndex != charCount)
|
||||
{
|
||||
returnArray[arrayIndex++] = '='; //padding
|
||||
}
|
||||
}
|
||||
|
||||
return new string(returnArray);
|
||||
|
@ -101,11 +103,13 @@ namespace MongoAuth
|
|||
{
|
||||
return value - 65;
|
||||
}
|
||||
|
||||
//50-55 == numbers 2-7
|
||||
if (value < 56 && value > 49)
|
||||
{
|
||||
return value - 24;
|
||||
}
|
||||
|
||||
//97-122 == lowercase letters
|
||||
if (value < 123 && value > 96)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace MongoAuth
|
|||
{
|
||||
port = 27017; // mongo default port
|
||||
}
|
||||
|
||||
Port = port;
|
||||
|
||||
Database = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["data:MongoDB"])
|
||||
|
|
|
@ -59,13 +59,14 @@ namespace MongoAuth
|
|||
|
||||
_enablePasswordReset = TryReadBool(config["enablePasswordReset"], _enablePasswordReset);
|
||||
_maxInvalidPasswordAttempts = TryReadInt(config["maxInvalidPasswordAttempts"], _maxInvalidPasswordAttempts);
|
||||
_minRequiredNonAlphanumericCharacters = TryReadInt(config["minRequiredNonAlphanumericCharacters"], _minRequiredNonAlphanumericCharacters);
|
||||
_minRequiredNonAlphanumericCharacters = TryReadInt(config["minRequiredNonAlphanumericCharacters"],
|
||||
_minRequiredNonAlphanumericCharacters);
|
||||
_minRequriedPasswordLength = TryReadInt(config["minRequriedPasswordLength"], _minRequriedPasswordLength);
|
||||
_passwordAttemptWindow = TryReadInt(config["passwordAttemptWindow"], _passwordAttemptWindow);
|
||||
_requiresUniqueEmail = TryReadBool(config["requiresUniqueEmail"], _requiresUniqueEmail);
|
||||
|
||||
|
||||
MongoClientSettings settings = new MongoClientSettings
|
||||
var settings = new MongoClientSettings
|
||||
{
|
||||
Server = new MongoServerAddress(DatabaseConfig.Host, DatabaseConfig.Port)
|
||||
};
|
||||
|
@ -77,22 +78,24 @@ namespace MongoAuth
|
|||
DatabaseConfig.Password);
|
||||
}
|
||||
|
||||
MongoClient dbClient = new MongoClient(settings);
|
||||
var dbClient = new MongoClient(settings);
|
||||
|
||||
_memberCollection = dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(MEMBER_COLLECTION_NAME);
|
||||
_memberCollection = dbClient.GetDatabase(DatabaseConfig.Database)
|
||||
.GetCollection<MongoMember>(MEMBER_COLLECTION_NAME);
|
||||
|
||||
#pragma warning disable 4014
|
||||
#pragma warning disable 4014
|
||||
SetupIndexes();
|
||||
#pragma warning restore 4014
|
||||
#pragma warning restore 4014
|
||||
}
|
||||
|
||||
public async Task SetupIndexes()
|
||||
{
|
||||
List<BsonDocument> indexes = await (await _memberCollection.Indexes.ListAsync()).ToListAsync();
|
||||
var indexes = await (await _memberCollection.Indexes.ListAsync()).ToListAsync();
|
||||
|
||||
if (indexes.All(i => i["name"] != "_idx_username"))
|
||||
{
|
||||
await _memberCollection.Indexes.CreateOneAsync(Builders<MongoMember>.IndexKeys.Ascending(b => b.UserName),
|
||||
await _memberCollection.Indexes.CreateOneAsync(
|
||||
Builders<MongoMember>.IndexKeys.Ascending(b => b.UserName),
|
||||
new CreateIndexOptions
|
||||
{
|
||||
Name = "_idx_username",
|
||||
|
@ -102,7 +105,8 @@ namespace MongoAuth
|
|||
|
||||
if (indexes.All(i => i["name"] != "_idx_email"))
|
||||
{
|
||||
await _memberCollection.Indexes.CreateOneAsync(Builders<MongoMember>.IndexKeys.Ascending(b => b.EmailAddress),
|
||||
await _memberCollection.Indexes.CreateOneAsync(
|
||||
Builders<MongoMember>.IndexKeys.Ascending(b => b.EmailAddress),
|
||||
new CreateIndexOptions
|
||||
{
|
||||
Name = "_idx_email",
|
||||
|
@ -117,7 +121,8 @@ namespace MongoAuth
|
|||
|
||||
if (isAuthenticated)
|
||||
{
|
||||
Task<MongoMember> task = _memberCollection.Find(m => m.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
var task = _memberCollection.Find(m => m.UserName.ToLower() == username.ToLower())
|
||||
.SingleOrDefaultAsync();
|
||||
task.Wait();
|
||||
MongoMember mm = task.Result;
|
||||
|
||||
|
@ -127,12 +132,12 @@ namespace MongoAuth
|
|||
}
|
||||
|
||||
var salt = new byte[24];
|
||||
byte[] hash = CalculateHash(newPassword, ref salt);
|
||||
var hash = CalculateHash(newPassword, ref salt);
|
||||
|
||||
mm.PassSalt = salt;
|
||||
mm.PassHash = hash;
|
||||
|
||||
Task<ReplaceOneResult> replaceTask = _memberCollection.ReplaceOneAsync(m => m.Id == mm.Id, mm);
|
||||
var replaceTask = _memberCollection.ReplaceOneAsync(m => m.Id == mm.Id, mm);
|
||||
replaceTask.Wait();
|
||||
|
||||
return replaceTask.IsCompleted;
|
||||
|
@ -141,12 +146,12 @@ namespace MongoAuth
|
|||
return false;
|
||||
}
|
||||
|
||||
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override bool ChangePasswordQuestionAndAnswer(string username, string password,
|
||||
string newPasswordQuestion, string newPasswordAnswer) => throw new NotImplementedException();
|
||||
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
public override MembershipUser CreateUser(string username, string password, string email,
|
||||
string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey,
|
||||
out MembershipCreateStatus status)
|
||||
{
|
||||
if (password.Length < MinRequiredPasswordLength)
|
||||
{
|
||||
|
@ -156,8 +161,8 @@ namespace MongoAuth
|
|||
|
||||
MembershipUser mu = null;
|
||||
|
||||
Task<long> dupeUsers = _memberCollection.Find(m => m.UserName.ToLower() == username.ToLower()).CountAsync();
|
||||
Task<long> dupeEmails = _memberCollection.Find(m => m.EmailAddress.ToLower() == email.ToLower()).CountAsync();
|
||||
var dupeUsers = _memberCollection.Find(m => m.UserName.ToLower() == username.ToLower()).CountAsync();
|
||||
var dupeEmails = _memberCollection.Find(m => m.EmailAddress.ToLower() == email.ToLower()).CountAsync();
|
||||
dupeUsers.Wait();
|
||||
dupeEmails.Wait();
|
||||
|
||||
|
@ -172,9 +177,9 @@ namespace MongoAuth
|
|||
else
|
||||
{
|
||||
var salt = new byte[24];
|
||||
byte[] hash = CalculateHash(password, ref salt);
|
||||
var hash = CalculateHash(password, ref salt);
|
||||
|
||||
MongoMember mm = new MongoMember
|
||||
var mm = new MongoMember
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserName = username,
|
||||
|
@ -195,7 +200,19 @@ namespace MongoAuth
|
|||
if (insertTask.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
status = MembershipCreateStatus.Success;
|
||||
mu = new MembershipUser(Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, mm.CreationDate, mm.LastLoginDate, mm.LastActivityDate, DateTime.MinValue, mm.LastLockoutDate);
|
||||
mu = new MembershipUser(Name,
|
||||
mm.UserName,
|
||||
mm.Id,
|
||||
mm.EmailAddress,
|
||||
"",
|
||||
"",
|
||||
mm.IsApproved,
|
||||
mm.IsLockedOut,
|
||||
mm.CreationDate,
|
||||
mm.LastLoginDate,
|
||||
mm.LastActivityDate,
|
||||
DateTime.MinValue,
|
||||
mm.LastLockoutDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -208,7 +225,7 @@ namespace MongoAuth
|
|||
|
||||
public override bool DeleteUser(string username, bool deleteAllRelatedData)
|
||||
{
|
||||
Task<DeleteResult> task = _memberCollection.DeleteOneAsync(m => m.UserName.ToLower() == username.ToLower());
|
||||
var task = _memberCollection.DeleteOneAsync(m => m.UserName.ToLower() == username.ToLower());
|
||||
task.Wait();
|
||||
|
||||
return task.Result.IsAcknowledged && task.Result.DeletedCount == 1;
|
||||
|
@ -216,94 +233,119 @@ namespace MongoAuth
|
|||
|
||||
public bool DeleteUser(Guid id)
|
||||
{
|
||||
Task<DeleteResult> task = _memberCollection.DeleteOneAsync(m => m.Id == id);
|
||||
var task = _memberCollection.DeleteOneAsync(m => m.Id == id);
|
||||
task.Wait();
|
||||
|
||||
return task.Result.IsAcknowledged && task.Result.DeletedCount == 1;
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,
|
||||
out int totalRecords) => throw new NotImplementedException();
|
||||
|
||||
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,
|
||||
out int totalRecords) => throw new NotImplementedException();
|
||||
|
||||
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
MembershipUserCollection muc = new MembershipUserCollection();
|
||||
var muc = new MembershipUserCollection();
|
||||
|
||||
IFindFluent<MongoMember, MongoMember> users = _memberCollection.Find(new BsonDocument()).Sort(Builders<MongoMember>.Sort.Ascending(m => m.UserName));
|
||||
var users = _memberCollection.Find(new BsonDocument())
|
||||
.Sort(Builders<MongoMember>.Sort.Ascending(m => m.UserName));
|
||||
|
||||
Task<long> totalRecordsTask = users.CountAsync();
|
||||
var totalRecordsTask = users.CountAsync();
|
||||
totalRecordsTask.Wait();
|
||||
totalRecords = Convert.ToInt32(totalRecordsTask.Result);
|
||||
|
||||
users = users.Skip(pageIndex * pageSize).Limit(pageSize);
|
||||
Task<List<MongoMember>> pageItemsTask = users.ToListAsync();
|
||||
var pageItemsTask = users.ToListAsync();
|
||||
pageItemsTask.Wait();
|
||||
|
||||
foreach (MongoMember mm in pageItemsTask.Result)
|
||||
{
|
||||
muc.Add(new MembershipUser(Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, FixupDatesFromMongo(mm.CreationDate), FixupDatesFromMongo(mm.LastLoginDate), FixupDatesFromMongo(mm.LastActivityDate), DateTime.MinValue, FixupDatesFromMongo(mm.LastLockoutDate)));
|
||||
muc.Add(new MembershipUser(Name,
|
||||
mm.UserName,
|
||||
mm.Id,
|
||||
mm.EmailAddress,
|
||||
"",
|
||||
"",
|
||||
mm.IsApproved,
|
||||
mm.IsLockedOut,
|
||||
FixupDatesFromMongo(mm.CreationDate),
|
||||
FixupDatesFromMongo(mm.LastLoginDate),
|
||||
FixupDatesFromMongo(mm.LastActivityDate),
|
||||
DateTime.MinValue,
|
||||
FixupDatesFromMongo(mm.LastLockoutDate)));
|
||||
}
|
||||
|
||||
return muc;
|
||||
}
|
||||
|
||||
public override int GetNumberOfUsersOnline()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override int GetNumberOfUsersOnline() => throw new NotImplementedException();
|
||||
|
||||
public override string GetPassword(string username, string answer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override string GetPassword(string username, string answer) => throw new NotImplementedException();
|
||||
|
||||
public override MembershipUser GetUser(string username, bool userIsOnline)
|
||||
{
|
||||
Task<MongoMember> task = _memberCollection.Find(f => f.UserName.ToLower() == username.ToLower()).FirstOrDefaultAsync();
|
||||
var task = _memberCollection.Find(f => f.UserName.ToLower() == username.ToLower()).FirstOrDefaultAsync();
|
||||
task.Wait();
|
||||
|
||||
MongoMember mm = task.Result;
|
||||
|
||||
return mm == null
|
||||
? null
|
||||
: new MembershipUser(Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, FixupDatesFromMongo(mm.CreationDate), FixupDatesFromMongo(mm.LastLoginDate), FixupDatesFromMongo(mm.LastActivityDate), DateTime.MinValue, FixupDatesFromMongo(mm.LastLockoutDate));
|
||||
: new MembershipUser(Name,
|
||||
mm.UserName,
|
||||
mm.Id,
|
||||
mm.EmailAddress,
|
||||
"",
|
||||
"",
|
||||
mm.IsApproved,
|
||||
mm.IsLockedOut,
|
||||
FixupDatesFromMongo(mm.CreationDate),
|
||||
FixupDatesFromMongo(mm.LastLoginDate),
|
||||
FixupDatesFromMongo(mm.LastActivityDate),
|
||||
DateTime.MinValue,
|
||||
FixupDatesFromMongo(mm.LastLockoutDate));
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
|
||||
{
|
||||
Task<MongoMember> task = _memberCollection.Find(f => f.Id == (Guid)providerUserKey).FirstOrDefaultAsync();
|
||||
var task = _memberCollection.Find(f => f.Id == (Guid)providerUserKey).FirstOrDefaultAsync();
|
||||
task.Wait();
|
||||
|
||||
MongoMember mm = task.Result;
|
||||
|
||||
return mm == null
|
||||
? null
|
||||
: new MembershipUser(Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, FixupDatesFromMongo(mm.CreationDate), FixupDatesFromMongo(mm.LastLoginDate), FixupDatesFromMongo(mm.LastActivityDate), DateTime.MinValue, FixupDatesFromMongo(mm.LastLockoutDate));
|
||||
: new MembershipUser(Name,
|
||||
mm.UserName,
|
||||
mm.Id,
|
||||
mm.EmailAddress,
|
||||
"",
|
||||
"",
|
||||
mm.IsApproved,
|
||||
mm.IsLockedOut,
|
||||
FixupDatesFromMongo(mm.CreationDate),
|
||||
FixupDatesFromMongo(mm.LastLoginDate),
|
||||
FixupDatesFromMongo(mm.LastActivityDate),
|
||||
DateTime.MinValue,
|
||||
FixupDatesFromMongo(mm.LastLockoutDate));
|
||||
}
|
||||
|
||||
public override string GetUserNameByEmail(string email)
|
||||
{
|
||||
Task<MongoMember> task = _memberCollection.Find(f => f.EmailAddress.ToLower() == email.ToLower()).FirstOrDefaultAsync();
|
||||
var task = _memberCollection.Find(f => f.EmailAddress.ToLower() == email.ToLower()).FirstOrDefaultAsync();
|
||||
task.Wait();
|
||||
|
||||
return task.Result.UserName;
|
||||
}
|
||||
|
||||
public override string ResetPassword(string username, string answer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override string ResetPassword(string username, string answer) => throw new NotImplementedException();
|
||||
|
||||
public void ChangeApproval(Guid id, bool newStatus)
|
||||
{
|
||||
Task<UpdateResult> task = _memberCollection.UpdateOneAsync(Builders<MongoMember>.Filter.Eq(u => u.Id, id), Builders<MongoMember>.Update.Set(u => u.IsApproved, newStatus));
|
||||
var task = _memberCollection.UpdateOneAsync(Builders<MongoMember>.Filter.Eq(u => u.Id, id),
|
||||
Builders<MongoMember>.Update.Set(u => u.IsApproved, newStatus));
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
|
@ -324,13 +366,16 @@ namespace MongoAuth
|
|||
updateDefinition.Add(Builders<MongoMember>.Update.Set(u => u.LastLockoutDate, DateTime.MinValue));
|
||||
}
|
||||
|
||||
Task<UpdateResult> task = _memberCollection.UpdateOneAsync(Builders<MongoMember>.Filter.Eq(u => u.Id, id), Builders<MongoMember>.Update.Combine(updateDefinition));
|
||||
var task = _memberCollection.UpdateOneAsync(Builders<MongoMember>.Filter.Eq(u => u.Id, id),
|
||||
Builders<MongoMember>.Update.Combine(updateDefinition));
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
public override bool UnlockUser(string userName)
|
||||
{
|
||||
Task<UpdateResult> task = _memberCollection.UpdateOneAsync(Builders<MongoMember>.Filter.Eq(m => m.UserName.ToLower(), userName.ToLower()), Builders<MongoMember>.Update.Set(m => m.IsLockedOut, false));
|
||||
var task = _memberCollection.UpdateOneAsync(
|
||||
Builders<MongoMember>.Filter.Eq(m => m.UserName.ToLower(), userName.ToLower()),
|
||||
Builders<MongoMember>.Update.Set(m => m.IsLockedOut, false));
|
||||
task.Wait();
|
||||
|
||||
return task.Result.IsAcknowledged && task.Result.ModifiedCount == 1;
|
||||
|
@ -343,7 +388,7 @@ namespace MongoAuth
|
|||
|
||||
public override bool ValidateUser(string username, string password)
|
||||
{
|
||||
Task<MongoMember> task = _memberCollection.Find(f => f.UserName.ToLower() == username.ToLower()).FirstOrDefaultAsync();
|
||||
var task = _memberCollection.Find(f => f.UserName.ToLower() == username.ToLower()).FirstOrDefaultAsync();
|
||||
task.Wait();
|
||||
MongoMember mm = task.Result;
|
||||
|
||||
|
@ -353,8 +398,8 @@ namespace MongoAuth
|
|||
return false;
|
||||
}
|
||||
|
||||
byte[] salt = mm.PassSalt;
|
||||
byte[] hash = CalculateHash(password, ref salt);
|
||||
var salt = mm.PassSalt;
|
||||
var hash = CalculateHash(password, ref salt);
|
||||
|
||||
bool isFail = false;
|
||||
|
||||
|
@ -397,7 +442,7 @@ namespace MongoAuth
|
|||
mm.LockoutWindowAttempts = 0;
|
||||
}
|
||||
|
||||
Task<ReplaceOneResult> updTask = _memberCollection.ReplaceOneAsync(Builders<MongoMember>.Filter.Eq(u => u.Id, mm.Id), mm);
|
||||
var updTask = _memberCollection.ReplaceOneAsync(Builders<MongoMember>.Filter.Eq(u => u.Id, mm.Id), mm);
|
||||
updTask.Wait();
|
||||
|
||||
return !isFail;
|
||||
|
@ -405,7 +450,8 @@ namespace MongoAuth
|
|||
|
||||
public async Task<string> GenerateValidationHash(Guid id)
|
||||
{
|
||||
MongoMember mm = await _memberCollection.Find(Builders<MongoMember>.Filter.Eq(u => u.Id, id)).FirstOrDefaultAsync();
|
||||
MongoMember mm = await _memberCollection.Find(Builders<MongoMember>.Filter.Eq(u => u.Id, id))
|
||||
.FirstOrDefaultAsync();
|
||||
if (mm == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -413,8 +459,9 @@ namespace MongoAuth
|
|||
|
||||
using (SHA256 sha = SHA256.Create())
|
||||
{
|
||||
string content = $"{mm.Id}.{Convert.ToBase64String(mm.PassSalt)}.{ConfigurationManager.AppSettings["data:SecretKey"]}";
|
||||
byte[] hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(content));
|
||||
string content =
|
||||
$"{mm.Id}.{Convert.ToBase64String(mm.PassSalt)}.{ConfigurationManager.AppSettings["data:SecretKey"]}";
|
||||
var hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(content));
|
||||
|
||||
return Base32Encoding.ToString(hashBytes);
|
||||
}
|
||||
|
@ -422,7 +469,8 @@ namespace MongoAuth
|
|||
|
||||
public async Task<bool> ValidateUserFromHash(Guid id, string validate)
|
||||
{
|
||||
MongoMember mm = await _memberCollection.Find(Builders<MongoMember>.Filter.Eq(u => u.Id, id)).FirstOrDefaultAsync();
|
||||
MongoMember mm = await _memberCollection.Find(Builders<MongoMember>.Filter.Eq(u => u.Id, id))
|
||||
.FirstOrDefaultAsync();
|
||||
if (mm == null)
|
||||
{
|
||||
return false;
|
||||
|
@ -430,8 +478,9 @@ namespace MongoAuth
|
|||
|
||||
using (SHA256 sha = SHA256.Create())
|
||||
{
|
||||
string content = $"{mm.Id}.{Convert.ToBase64String(mm.PassSalt)}.{ConfigurationManager.AppSettings["data:SecretKey"]}";
|
||||
byte[] hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(content));
|
||||
string content =
|
||||
$"{mm.Id}.{Convert.ToBase64String(mm.PassSalt)}.{ConfigurationManager.AppSettings["data:SecretKey"]}";
|
||||
var hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(content));
|
||||
|
||||
string expected = Base32Encoding.ToString(hashBytes);
|
||||
bool success = string.Equals(expected, validate, StringComparison.InvariantCultureIgnoreCase);
|
||||
|
@ -449,19 +498,19 @@ namespace MongoAuth
|
|||
{
|
||||
if (!salt.Any(v => v != 0))
|
||||
{
|
||||
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
|
||||
var rng = new RNGCryptoServiceProvider();
|
||||
rng.GetBytes(salt);
|
||||
}
|
||||
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||
var passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||
|
||||
var hashPlaintext = new byte[salt.Length + passwordBytes.Length];
|
||||
|
||||
passwordBytes.CopyTo(hashPlaintext, 0);
|
||||
salt.CopyTo(hashPlaintext, passwordBytes.Length);
|
||||
|
||||
SHA512CryptoServiceProvider sha = new SHA512CryptoServiceProvider();
|
||||
byte[] hash = sha.ComputeHash(hashPlaintext);
|
||||
var sha = new SHA512CryptoServiceProvider();
|
||||
var hash = sha.ComputeHash(hashPlaintext);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace MongoAuth
|
|||
|
||||
public override string ApplicationName
|
||||
{
|
||||
get { return ""; }
|
||||
get => "";
|
||||
set { }
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace MongoAuth
|
|||
{
|
||||
base.Initialize(name, config);
|
||||
|
||||
MongoClientSettings settings = new MongoClientSettings
|
||||
var settings = new MongoClientSettings
|
||||
{
|
||||
Server = new MongoServerAddress(DatabaseConfig.Host, DatabaseConfig.Port)
|
||||
};
|
||||
|
@ -42,21 +42,23 @@ namespace MongoAuth
|
|||
DatabaseConfig.Password);
|
||||
}
|
||||
|
||||
MongoClient dbClient = new MongoClient(settings);
|
||||
var dbClient = new MongoClient(settings);
|
||||
|
||||
_roleCollection = dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(ROLE_COLLECTION_NAME);
|
||||
_memberCollection = dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(MEMBER_COLLECTION_NAME);
|
||||
_roleCollection = dbClient.GetDatabase(DatabaseConfig.Database)
|
||||
.GetCollection<MongoRole>(ROLE_COLLECTION_NAME);
|
||||
_memberCollection = dbClient.GetDatabase(DatabaseConfig.Database)
|
||||
.GetCollection<MongoMember>(MEMBER_COLLECTION_NAME);
|
||||
}
|
||||
|
||||
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
Task<List<MongoRole>> roleTask = _roleCollection.Find(r => roleNames.Contains(r.RoleName)).ToListAsync();
|
||||
var roleTask = _roleCollection.Find(r => roleNames.Contains(r.RoleName)).ToListAsync();
|
||||
roleTask.Wait();
|
||||
List<MongoRole> roles = roleTask.Result;
|
||||
var roles = roleTask.Result;
|
||||
|
||||
Task<List<MongoMember>> userTask = _memberCollection.Find(u => usernames.Contains(u.UserName)).ToListAsync();
|
||||
var userTask = _memberCollection.Find(u => usernames.Contains(u.UserName)).ToListAsync();
|
||||
userTask.Wait();
|
||||
List<MongoMember> users = userTask.Result;
|
||||
var users = userTask.Result;
|
||||
|
||||
for (int i = 0; i < roles.Count; i++)
|
||||
{
|
||||
|
@ -67,29 +69,30 @@ namespace MongoAuth
|
|||
newUsers.AddRange(roles[i].Users);
|
||||
}
|
||||
|
||||
IEnumerable<Guid> usersToAdd = from u in users
|
||||
where newUsers.All(v => v != u.Id)
|
||||
select u.Id;
|
||||
var usersToAdd = from u in users
|
||||
where newUsers.All(v => v != u.Id)
|
||||
select u.Id;
|
||||
|
||||
newUsers.AddRange(usersToAdd);
|
||||
|
||||
roles[i].Users = newUsers.ToArray();
|
||||
|
||||
Task<ReplaceOneResult> update = _roleCollection.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, roles[i].Id), roles[i]);
|
||||
var update =
|
||||
_roleCollection.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, roles[i].Id), roles[i]);
|
||||
update.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public override void CreateRole(string roleName)
|
||||
{
|
||||
Task<MongoRole> role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
var role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
if (role.Result != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MongoRole mr = new MongoRole
|
||||
var mr = new MongoRole
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
RoleName = roleName
|
||||
|
@ -101,7 +104,7 @@ namespace MongoAuth
|
|||
|
||||
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
|
||||
{
|
||||
Task<MongoRole> role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
var role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
if (role.Result != null
|
||||
|
@ -111,7 +114,7 @@ namespace MongoAuth
|
|||
throw new ProviderException(Resources.RoleNotEmpty);
|
||||
}
|
||||
|
||||
Task<DeleteResult> task = _roleCollection.DeleteOneAsync(r => r.RoleName == roleName);
|
||||
var task = _roleCollection.DeleteOneAsync(r => r.RoleName == roleName);
|
||||
task.Wait();
|
||||
|
||||
return true;
|
||||
|
@ -119,7 +122,7 @@ namespace MongoAuth
|
|||
|
||||
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
|
||||
{
|
||||
Task<MongoRole> role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
var role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
if (role.Result == null)
|
||||
|
@ -127,7 +130,9 @@ namespace MongoAuth
|
|||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
Task<List<MongoMember>> users = _memberCollection.Find(u => role.Result.Users.Contains(u.Id) && u.UserName.ToLower().Contains(usernameToMatch.ToLower())).ToListAsync();
|
||||
var users = _memberCollection.Find(u
|
||||
=> role.Result.Users.Contains(u.Id) && u.UserName.ToLower().Contains(usernameToMatch.ToLower()))
|
||||
.ToListAsync();
|
||||
users.Wait();
|
||||
|
||||
return users.Result.Select(r => r.UserName).ToArray();
|
||||
|
@ -135,7 +140,7 @@ namespace MongoAuth
|
|||
|
||||
public override string[] GetAllRoles()
|
||||
{
|
||||
Task<List<MongoRole>> roles = _roleCollection.Find(new BsonDocument()).ToListAsync();
|
||||
var roles = _roleCollection.Find(new BsonDocument()).ToListAsync();
|
||||
roles.Wait();
|
||||
|
||||
return roles.Result.Select(r => r.RoleName).ToArray();
|
||||
|
@ -143,7 +148,7 @@ namespace MongoAuth
|
|||
|
||||
public override string[] GetRolesForUser(string username)
|
||||
{
|
||||
Task<MongoMember> user = _memberCollection.Find(u => u.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
var user = _memberCollection.Find(u => u.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
user.Wait();
|
||||
|
||||
if (user.Result == null)
|
||||
|
@ -151,7 +156,7 @@ namespace MongoAuth
|
|||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
Task<List<MongoRole>> role = _roleCollection.Find(r => r.Users != null && r.Users.Contains(user.Result.Id)).ToListAsync();
|
||||
var role = _roleCollection.Find(r => r.Users != null && r.Users.Contains(user.Result.Id)).ToListAsync();
|
||||
role.Wait();
|
||||
|
||||
return role.Result.Select(r => r.RoleName).ToArray();
|
||||
|
@ -159,7 +164,7 @@ namespace MongoAuth
|
|||
|
||||
public override string[] GetUsersInRole(string roleName)
|
||||
{
|
||||
Task<MongoRole> role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
var role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
if (role.Result == null)
|
||||
|
@ -167,7 +172,7 @@ namespace MongoAuth
|
|||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
Task<List<MongoMember>> users = _memberCollection.Find(u => role.Result.Users.Contains(u.Id)).ToListAsync();
|
||||
var users = _memberCollection.Find(u => role.Result.Users.Contains(u.Id)).ToListAsync();
|
||||
users.Wait();
|
||||
|
||||
return users.Result.Select(u => u.UserName).ToArray();
|
||||
|
@ -175,8 +180,8 @@ namespace MongoAuth
|
|||
|
||||
public override bool IsUserInRole(string username, string roleName)
|
||||
{
|
||||
Task<MongoMember> user = _memberCollection.Find(u => u.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
Task<MongoRole> role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
var user = _memberCollection.Find(u => u.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
var role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
user.Wait();
|
||||
role.Wait();
|
||||
|
||||
|
@ -191,28 +196,28 @@ namespace MongoAuth
|
|||
|
||||
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
Task<List<MongoRole>> roleTask = _roleCollection.Find(r => roleNames.Contains(r.RoleName)).ToListAsync();
|
||||
var roleTask = _roleCollection.Find(r => roleNames.Contains(r.RoleName)).ToListAsync();
|
||||
roleTask.Wait();
|
||||
List<MongoRole> roles = roleTask.Result;
|
||||
var roles = roleTask.Result;
|
||||
|
||||
Task<List<MongoMember>> userTask = _memberCollection.Find(u => usernames.Contains(u.UserName)).ToListAsync();
|
||||
var userTask = _memberCollection.Find(u => usernames.Contains(u.UserName)).ToListAsync();
|
||||
userTask.Wait();
|
||||
List<MongoMember> users = userTask.Result;
|
||||
var users = userTask.Result;
|
||||
|
||||
foreach (MongoRole t in roles)
|
||||
{
|
||||
t.Users = (from u in t.Users
|
||||
where users.All(v => v.Id != u)
|
||||
select u).ToArray();
|
||||
where users.All(v => v.Id != u)
|
||||
select u).ToArray();
|
||||
|
||||
Task<ReplaceOneResult> update = _roleCollection.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, t.Id), t);
|
||||
var update = _roleCollection.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, t.Id), t);
|
||||
update.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RoleExists(string roleName)
|
||||
{
|
||||
Task<MongoRole> role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
var role = _roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
return role.Result != null;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
@ -33,4 +32,4 @@ using System.Runtime.InteropServices;
|
|||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,19 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
|
||||
</startup>
|
||||
</configuration>
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<packages>
|
||||
<package id="DnsClient" version="1.0.7" targetFramework="net47" />
|
||||
<package id="MongoDB.Bson" version="2.5.0" targetFramework="net47" />
|
||||
|
|
|
@ -12,7 +12,9 @@ namespace BuildFeed.Model.Api
|
|||
|
||||
public string LabUrl { get; set; }
|
||||
|
||||
public bool IsLeaked => SourceType == TypeOfSource.PublicRelease || SourceType == TypeOfSource.InternalLeak || SourceType == TypeOfSource.UpdateGDR;
|
||||
public bool IsLeaked => SourceType == TypeOfSource.PublicRelease
|
||||
|| SourceType == TypeOfSource.InternalLeak
|
||||
|| SourceType == TypeOfSource.UpdateGDR;
|
||||
|
||||
public DateTime Added { get; set; }
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ namespace BuildFeed.Model
|
|||
|
||||
public string LabUrl { get; private set; }
|
||||
|
||||
public bool IsLeaked => SourceType == TypeOfSource.PublicRelease ||
|
||||
SourceType == TypeOfSource.InternalLeak ||
|
||||
SourceType == TypeOfSource.UpdateGDR;
|
||||
public bool IsLeaked => SourceType == TypeOfSource.PublicRelease
|
||||
|| SourceType == TypeOfSource.InternalLeak
|
||||
|| SourceType == TypeOfSource.UpdateGDR;
|
||||
|
||||
public string FullBuildString { get; private set; }
|
||||
|
||||
|
|
|
@ -20,7 +20,10 @@ namespace BuildFeed.Model
|
|||
}
|
||||
|
||||
var valuesWithoutNone = new ProjectFamily[values.Length - 1];
|
||||
for (int i = 0, j = values.Length - 1; j > 0; j--, i++)
|
||||
for (int i = 0,
|
||||
j = values.Length - 1;
|
||||
j > 0;
|
||||
j--, i++)
|
||||
{
|
||||
valuesWithoutNone[i] = (ProjectFamily)values.GetValue(j);
|
||||
}
|
||||
|
|
|
@ -11,76 +11,83 @@ namespace BuildFeed.Model
|
|||
{
|
||||
public async Task<FrontBuildGroup[]> SelectAllGroups(int limit = -1, int skip = 0)
|
||||
{
|
||||
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument
|
||||
{
|
||||
new BsonElement("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildGroup.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(Build.MinorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Build), $"${nameof(Build.Number)}"),
|
||||
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(Build.Revision)}")
|
||||
}),
|
||||
new BsonElement("date", new BsonDocument("$max", $"${nameof(Build.BuildTime)}")),
|
||||
new BsonElement("count", new BsonDocument("$sum", 1))
|
||||
}).Sort(new BsonDocument
|
||||
{
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Major)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Minor)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Build)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Revision)}", -1)
|
||||
}).Skip(skip);
|
||||
var query = _buildCollection.Aggregate()
|
||||
.Group(new BsonDocument
|
||||
{
|
||||
new BsonElement("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildGroup.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(Build.MinorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Build), $"${nameof(Build.Number)}"),
|
||||
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(Build.Revision)}")
|
||||
}),
|
||||
new BsonElement("date", new BsonDocument("$max", $"${nameof(Build.BuildTime)}")),
|
||||
new BsonElement("count", new BsonDocument("$sum", 1))
|
||||
})
|
||||
.Sort(new BsonDocument
|
||||
{
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Major)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Minor)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Build)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildGroup.Revision)}", -1)
|
||||
})
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
query = query.Limit(limit);
|
||||
}
|
||||
|
||||
List<BsonDocument> grouping = await query.ToListAsync();
|
||||
var grouping = await query.ToListAsync();
|
||||
|
||||
return (from g in grouping
|
||||
select new FrontBuildGroup
|
||||
select new FrontBuildGroup
|
||||
{
|
||||
Key = new BuildGroup
|
||||
{
|
||||
Key = new BuildGroup
|
||||
{
|
||||
Major = (uint)g["_id"].AsBsonDocument[nameof(BuildGroup.Major)].AsInt32,
|
||||
Minor = (uint)g["_id"].AsBsonDocument[nameof(BuildGroup.Minor)].AsInt32,
|
||||
Build = (uint)g["_id"].AsBsonDocument[nameof(BuildGroup.Build)].AsInt32,
|
||||
Revision = (uint?)g["_id"].AsBsonDocument[nameof(BuildGroup.Revision)].AsNullableInt32
|
||||
},
|
||||
LastBuild = g["date"].ToNullableUniversalTime(),
|
||||
BuildCount = g["count"].AsInt32
|
||||
}).ToArray();
|
||||
Major = (uint)g["_id"].AsBsonDocument[nameof(BuildGroup.Major)].AsInt32,
|
||||
Minor = (uint)g["_id"].AsBsonDocument[nameof(BuildGroup.Minor)].AsInt32,
|
||||
Build = (uint)g["_id"].AsBsonDocument[nameof(BuildGroup.Build)].AsInt32,
|
||||
Revision = (uint?)g["_id"].AsBsonDocument[nameof(BuildGroup.Revision)].AsNullableInt32
|
||||
},
|
||||
LastBuild = g["date"].ToNullableUniversalTime(),
|
||||
BuildCount = g["count"].AsInt32
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
public async Task<long> SelectAllGroupsCount()
|
||||
{
|
||||
List<BsonDocument> grouping = await _buildCollection.Aggregate().Group(new BsonDocument
|
||||
{
|
||||
new BsonElement("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildGroup.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(Build.MinorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Build), $"${nameof(Build.Number)}"),
|
||||
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(Build.Revision)}")
|
||||
})
|
||||
}).ToListAsync();
|
||||
var grouping = await _buildCollection.Aggregate()
|
||||
.Group(new BsonDocument
|
||||
{
|
||||
new BsonElement("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildGroup.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(Build.MinorVersion)}"),
|
||||
new BsonElement(nameof(BuildGroup.Build), $"${nameof(Build.Number)}"),
|
||||
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(Build.Revision)}")
|
||||
})
|
||||
})
|
||||
.ToListAsync();
|
||||
return grouping.Count;
|
||||
}
|
||||
|
||||
public async Task<List<Build>> SelectGroup(BuildGroup group, int limit = -1, int skip = 0)
|
||||
{
|
||||
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), group.Major),
|
||||
new BsonElement(nameof(Build.MinorVersion), group.Minor),
|
||||
new BsonElement(nameof(Build.Number), group.Build),
|
||||
new BsonElement(nameof(Build.Revision), group.Revision)
|
||||
}).Sort(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.BuildTime), 1)
|
||||
}).Skip(skip);
|
||||
var query = _buildCollection.Find(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), group.Major),
|
||||
new BsonElement(nameof(Build.MinorVersion), group.Minor),
|
||||
new BsonElement(nameof(Build.Number), group.Build),
|
||||
new BsonElement(nameof(Build.Revision), group.Revision)
|
||||
})
|
||||
.Sort(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.BuildTime), 1)
|
||||
})
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
|
|
|
@ -11,40 +11,51 @@ namespace BuildFeed.Model
|
|||
{
|
||||
public async Task<string[]> SelectAllLabs(int limit = -1, int skip = 0)
|
||||
{
|
||||
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id", $"${nameof(Build.Lab)}")).Sort(new BsonDocument("_id", 1)).Skip(skip);
|
||||
var query = _buildCollection.Aggregate()
|
||||
.Group(new BsonDocument("_id", $"${nameof(Build.Lab)}"))
|
||||
.Sort(new BsonDocument("_id", 1))
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
query = query.Limit(limit);
|
||||
}
|
||||
|
||||
List<BsonDocument> grouping = await query.ToListAsync();
|
||||
var grouping = await query.ToListAsync();
|
||||
|
||||
return (from g in grouping
|
||||
where !g["_id"].IsBsonNull
|
||||
select g["_id"].AsString).ToArray();
|
||||
where !g["_id"].IsBsonNull
|
||||
select g["_id"].AsString).ToArray();
|
||||
}
|
||||
|
||||
public async Task<string[]> SelectLabsForVersion(int major, int minor)
|
||||
{
|
||||
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Match(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), major),
|
||||
new BsonElement(nameof(Build.MinorVersion), minor)
|
||||
}).Group(new BsonDocument("_id", $"${nameof(Build.Lab)}")).Sort(new BsonDocument("_id", 1));
|
||||
var query = _buildCollection.Aggregate()
|
||||
.Match(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), major),
|
||||
new BsonElement(nameof(Build.MinorVersion), minor)
|
||||
})
|
||||
.Group(new BsonDocument("_id", $"${nameof(Build.Lab)}"))
|
||||
.Sort(new BsonDocument("_id", 1));
|
||||
|
||||
List<BsonDocument> grouping = await query.ToListAsync();
|
||||
var grouping = await query.ToListAsync();
|
||||
|
||||
return (from g in grouping
|
||||
where !g["_id"].IsBsonNull
|
||||
select g["_id"].AsString).ToArray();
|
||||
where !g["_id"].IsBsonNull
|
||||
select g["_id"].AsString).ToArray();
|
||||
}
|
||||
|
||||
public async Task<List<string>> SearchLabs(string search)
|
||||
{
|
||||
List<Tuple<string>> result = await _buildCollection.Aggregate().Match(b => b.Lab != null).Match(b => b.Lab != "").Match(b => b.Lab.ToLower().Contains(search.ToLower())).Group(b => b.Lab.ToLower(),
|
||||
// incoming bullshit hack
|
||||
bg => new Tuple<string>(bg.Key)).ToListAsync();
|
||||
var result = await _buildCollection.Aggregate()
|
||||
.Match(b => b.Lab != null)
|
||||
.Match(b => b.Lab != "")
|
||||
.Match(b => b.Lab.ToLower().Contains(search.ToLower()))
|
||||
.Group(b => b.Lab.ToLower(),
|
||||
// incoming bullshit hack
|
||||
bg => new Tuple<string>(bg.Key))
|
||||
.ToListAsync();
|
||||
|
||||
// work ourselves out of aforementioned bullshit hack
|
||||
return result.Select(b => b.Item1).ToList();
|
||||
|
@ -52,16 +63,20 @@ namespace BuildFeed.Model
|
|||
|
||||
public async Task<long> SelectAllLabsCount()
|
||||
{
|
||||
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id", new BsonDocument(nameof(Build.Lab), $"${nameof(Build.Lab)}"))).Sort(new BsonDocument("_id", 1));
|
||||
var query = _buildCollection.Aggregate()
|
||||
.Group(new BsonDocument("_id", new BsonDocument(nameof(Build.Lab), $"${nameof(Build.Lab)}")))
|
||||
.Sort(new BsonDocument("_id", 1));
|
||||
|
||||
List<BsonDocument> grouping = await query.ToListAsync();
|
||||
var grouping = await query.ToListAsync();
|
||||
|
||||
return grouping.Count;
|
||||
}
|
||||
|
||||
public async Task<List<Build>> SelectLab(string lab, int limit = -1, int skip = 0)
|
||||
{
|
||||
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument(nameof(Build.LabUrl), lab)).Sort(sortByCompileDate).Skip(skip);
|
||||
var query = _buildCollection.Find(new BsonDocument(nameof(Build.LabUrl), lab))
|
||||
.Sort(sortByCompileDate)
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
|
@ -71,6 +86,7 @@ namespace BuildFeed.Model
|
|||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<long> SelectLabCount(string lab) => await _buildCollection.CountAsync(new BsonDocument(nameof(Build.LabUrl), lab));
|
||||
public async Task<long> SelectLabCount(string lab)
|
||||
=> await _buildCollection.CountAsync(new BsonDocument(nameof(Build.LabUrl), lab));
|
||||
}
|
||||
}
|
|
@ -8,13 +8,16 @@ namespace BuildFeed.Model
|
|||
{
|
||||
public partial class BuildRepository
|
||||
{
|
||||
public Task<TypeOfSource[]> SelectAllSources(int limit = -1, int skip = 0) => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) as TypeOfSource[]);
|
||||
public Task<TypeOfSource[]> SelectAllSources(int limit = -1, int skip = 0)
|
||||
=> Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) as TypeOfSource[]);
|
||||
|
||||
public Task<long> SelectAllSourcesCount() => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)).LongLength);
|
||||
|
||||
public async Task<List<Build>> SelectSource(TypeOfSource source, int limit = -1, int skip = 0)
|
||||
{
|
||||
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument(nameof(Build.SourceType), source)).Sort(sortByOrder).Skip(skip);
|
||||
var query = _buildCollection.Find(new BsonDocument(nameof(Build.SourceType), source))
|
||||
.Sort(sortByOrder)
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
|
@ -24,6 +27,7 @@ namespace BuildFeed.Model
|
|||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<long> SelectSourceCount(TypeOfSource source) => await _buildCollection.CountAsync(new BsonDocument(nameof(Build.SourceType), source));
|
||||
public async Task<long> SelectSourceCount(TypeOfSource source)
|
||||
=> await _buildCollection.CountAsync(new BsonDocument(nameof(Build.SourceType), source));
|
||||
}
|
||||
}
|
|
@ -10,50 +10,57 @@ namespace BuildFeed.Model
|
|||
{
|
||||
public async Task<BuildVersion[]> SelectAllVersions(int limit = -1, int skip = 0)
|
||||
{
|
||||
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id",
|
||||
new BsonDocument
|
||||
var query = _buildCollection.Aggregate()
|
||||
.Group(new BsonDocument("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildVersion.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(Build.MinorVersion)}")
|
||||
}))
|
||||
.Sort(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildVersion.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(Build.MinorVersion)}")
|
||||
})).Sort(new BsonDocument
|
||||
{
|
||||
new BsonElement($"_id.{nameof(BuildVersion.Major)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildVersion.Minor)}", -1)
|
||||
}).Skip(skip);
|
||||
new BsonElement($"_id.{nameof(BuildVersion.Major)}", -1),
|
||||
new BsonElement($"_id.{nameof(BuildVersion.Minor)}", -1)
|
||||
})
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
query = query.Limit(limit);
|
||||
}
|
||||
|
||||
List<BsonDocument> grouping = await query.ToListAsync();
|
||||
var grouping = await query.ToListAsync();
|
||||
|
||||
return (from g in grouping
|
||||
select new BuildVersion
|
||||
{
|
||||
Major = (uint)g["_id"].AsBsonDocument[nameof(BuildVersion.Major)].AsInt32,
|
||||
Minor = (uint)g["_id"].AsBsonDocument[nameof(BuildVersion.Minor)].AsInt32
|
||||
}).ToArray();
|
||||
select new BuildVersion
|
||||
{
|
||||
Major = (uint)g["_id"].AsBsonDocument[nameof(BuildVersion.Major)].AsInt32,
|
||||
Minor = (uint)g["_id"].AsBsonDocument[nameof(BuildVersion.Minor)].AsInt32
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
public async Task<long> SelectAllVersionsCount()
|
||||
{
|
||||
List<BsonDocument> query = await _buildCollection.Aggregate().Group(new BsonDocument("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildVersion.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(Build.MinorVersion)}")
|
||||
})).ToListAsync();
|
||||
var query = await _buildCollection.Aggregate()
|
||||
.Group(new BsonDocument("_id",
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(BuildVersion.Major), $"${nameof(Build.MajorVersion)}"),
|
||||
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(Build.MinorVersion)}")
|
||||
}))
|
||||
.ToListAsync();
|
||||
return query.Count;
|
||||
}
|
||||
|
||||
public async Task<List<Build>> SelectVersion(uint major, uint minor, int limit = -1, int skip = 0)
|
||||
{
|
||||
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), major),
|
||||
new BsonElement(nameof(Build.MinorVersion), minor)
|
||||
}).Sort(sortByOrder).Skip(skip);
|
||||
var query = _buildCollection.Find(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), major),
|
||||
new BsonElement(nameof(Build.MinorVersion), minor)
|
||||
})
|
||||
.Sort(sortByOrder)
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
|
@ -63,10 +70,11 @@ namespace BuildFeed.Model
|
|||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<long> SelectVersionCount(uint major, uint minor) => await _buildCollection.CountAsync(new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), major),
|
||||
new BsonElement(nameof(Build.MinorVersion), minor)
|
||||
});
|
||||
public async Task<long> SelectVersionCount(uint major, uint minor) => await _buildCollection.CountAsync(
|
||||
new BsonDocument
|
||||
{
|
||||
new BsonElement(nameof(Build.MajorVersion), major),
|
||||
new BsonElement(nameof(Build.MinorVersion), minor)
|
||||
});
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ namespace BuildFeed.Model
|
|||
{
|
||||
public async Task<int[]> SelectAllYears(int limit = -1, int skip = 0)
|
||||
{
|
||||
IAggregateFluent<BsonDocument> query =
|
||||
var query =
|
||||
_buildCollection.Aggregate()
|
||||
.Match(Builders<Build>.Filter.Ne(b => b.BuildTime, null))
|
||||
.Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(Build.BuildTime)}")))
|
||||
|
@ -23,25 +23,33 @@ namespace BuildFeed.Model
|
|||
query = query.Limit(limit);
|
||||
}
|
||||
|
||||
List<BsonDocument> grouping = await query.ToListAsync();
|
||||
var grouping = await query.ToListAsync();
|
||||
|
||||
return (from g in grouping
|
||||
where !g["_id"].IsBsonNull
|
||||
select g["_id"].AsInt32).ToArray();
|
||||
where !g["_id"].IsBsonNull
|
||||
select g["_id"].AsInt32).ToArray();
|
||||
}
|
||||
|
||||
public async Task<long> SelectAllYearsCount()
|
||||
{
|
||||
List<BsonDocument> query = await _buildCollection.Aggregate().Match(Builders<Build>.Filter.Ne(b => b.BuildTime, null)).Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(Build.BuildTime)}"))).ToListAsync();
|
||||
var query = await _buildCollection.Aggregate()
|
||||
.Match(Builders<Build>.Filter.Ne(b => b.BuildTime, null))
|
||||
.Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(Build.BuildTime)}")))
|
||||
.ToListAsync();
|
||||
|
||||
return query.Count;
|
||||
}
|
||||
|
||||
public async Task<List<Build>> SelectYear(int year, int limit = -1, int skip = 0)
|
||||
{
|
||||
IFindFluent<Build, Build> query =
|
||||
_buildCollection.Find(Builders<Build>.Filter.And(Builders<Build>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
|
||||
Builders<Build>.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc)))).Sort(sortByCompileDate).Skip(skip);
|
||||
var query =
|
||||
_buildCollection.Find(Builders<Build>.Filter.And(
|
||||
Builders<Build>.Filter.Gte(b => b.BuildTime,
|
||||
new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
|
||||
Builders<Build>.Filter.Lte(b => b.BuildTime,
|
||||
new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc))))
|
||||
.Sort(sortByCompileDate)
|
||||
.Skip(skip);
|
||||
|
||||
if (limit > 0)
|
||||
{
|
||||
|
@ -51,10 +59,10 @@ namespace BuildFeed.Model
|
|||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<long> SelectYearCount(int year)
|
||||
=>
|
||||
await
|
||||
_buildCollection.CountAsync(Builders<Build>.Filter.And(Builders<Build>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
|
||||
Builders<Build>.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc))));
|
||||
public async Task<long> SelectYearCount(int year) => await
|
||||
_buildCollection.CountAsync(Builders<Build>.Filter.And(
|
||||
Builders<Build>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
|
||||
Builders<Build>.Filter.Lte(b => b.BuildTime,
|
||||
new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc))));
|
||||
}
|
||||
}
|
|
@ -230,16 +230,16 @@ namespace BuildFeed.Model
|
|||
},
|
||||
|
||||
Items = from i in g["items"].AsBsonArray
|
||||
select new FrontPageBuild
|
||||
{
|
||||
Id = i[nameof(Build.Id)].AsGuid,
|
||||
MajorVersion = (uint)i[nameof(Build.MajorVersion)].AsInt32,
|
||||
MinorVersion = (uint)i[nameof(Build.MinorVersion)].AsInt32,
|
||||
Number = (uint)i[nameof(Build.Number)].AsInt32,
|
||||
Revision = (uint?)i[nameof(Build.Revision)].AsNullableInt32,
|
||||
Lab = i[nameof(Build.Lab)].AsString,
|
||||
BuildTime = i[nameof(Build.BuildTime)].ToNullableUniversalTime()
|
||||
}
|
||||
select new FrontPageBuild
|
||||
{
|
||||
Id = i[nameof(Build.Id)].AsGuid,
|
||||
MajorVersion = (uint)i[nameof(Build.MajorVersion)].AsInt32,
|
||||
MinorVersion = (uint)i[nameof(Build.MinorVersion)].AsInt32,
|
||||
Number = (uint)i[nameof(Build.Number)].AsInt32,
|
||||
Revision = (uint?)i[nameof(Build.Revision)].AsNullableInt32,
|
||||
Lab = i[nameof(Build.Lab)].AsString,
|
||||
BuildTime = i[nameof(Build.BuildTime)].ToNullableUniversalTime()
|
||||
}
|
||||
}).ToArray();
|
||||
|
||||
IEnumerable<ProjectFamily> listOfFamilies =
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace BuildFeed.Model
|
|||
{
|
||||
port = 27017; // mongo default port
|
||||
}
|
||||
|
||||
Port = port;
|
||||
|
||||
Database = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["data:MongoDB"])
|
||||
|
@ -33,10 +34,10 @@ namespace BuildFeed.Model
|
|||
|
||||
public static void SetupIndexes()
|
||||
{
|
||||
BuildRepository b = new BuildRepository();
|
||||
#pragma warning disable 4014
|
||||
var b = new BuildRepository();
|
||||
#pragma warning disable 4014
|
||||
b.SetupIndexes();
|
||||
#pragma warning restore 4014
|
||||
#pragma warning restore 4014
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
|
||||
</startup>
|
||||
</configuration>
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<packages>
|
||||
<package id="AutoMapper" version="6.2.2" targetFramework="net47" />
|
||||
<package id="DnsClient" version="1.0.7" targetFramework="net47" />
|
||||
|
|
|
@ -0,0 +1,302 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/IdentifierHighlightingEnabled/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Built-in: Full Cleanup</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/LOCAL_FUNCTION_BODY/@EntryValue">ExpressionBody</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue">ExpressionBody</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PREPROCESSOR_IF/@EntryValue">USUAL_INDENT</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PREPROCESSOR_OTHER/@EntryValue">USUAL_INDENT</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EMBEDDED_ARRANGEMENT/@EntryValue">False</s:Boolean>
|
||||
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/NESTED_TERNARY_STYLE/@EntryValue">EXPANDED</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_EXPR_ACCESSOR_ON_SINGLE_LINE/@EntryValue">ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_EXPR_METHOD_ON_SINGLE_LINE/@EntryValue">ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_EXPR_PROPERTY_ON_SINGLE_LINE/@EntryValue">ALWAYS</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_TYPE_CONSTRAINTS_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_WHILE_ON_NEW_LINE/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_CASE_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARRAY_INITIALIZER_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_ARROW_WITH_EXPRESSIONS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_EXTENDS_COLON/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_FIRST_TYPE_PARAMETER_CONSTRAINT/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_BINARY_EXPRESSIONS/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINQ_EXPRESSIONS/@EntryValue">CHOP_ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_DECLARATION_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_TYPE_PARAMEER_CONSTRAINTS_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_OBJECT_AND_COLLECTION_INITIALIZER_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_TERNARY_EXPR_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CssFormatter/BRACE_STYLE/@EntryValue">NEXT_LINE</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CssFormatter/PROPERTIES_STYLE/@EntryValue">SEPARATE_LINES</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CssFormatter/SELECTOR_STYLE/@EntryValue">SEPARATE_LINES</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/NormalizeTagNames/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/TagAttributeIndenting/@EntryValue">OneStep</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/TagAttributesFormat/@EntryValue">OnSingleLine</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/TagSpaceBeforeHeaderEnd1/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/ALIGN_UNION_TYPE_USAGE/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/CONTROL_STATEMENTS_BRACES/@EntryValue">NEXT_LINE</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/FORCE_CONTROL_STATEMENTS_BRACES/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/FUNCTION_BRACES/@EntryValue">NEXT_LINE</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/FUNCTION_IN_INVOCATION_BRACES/@EntryValue">NEXT_LINE</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/PLACE_FINALLY_ON_NEW_LINE/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/SINGLE_STATEMENT_FUNCTION_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/TYPES_BRACES/@EntryValue">NEXT_LINE</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/WRAP_ENUM_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
||||
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
||||
<TypePattern DisplayName="Non-reorderable types">
|
||||
<TypePattern.Match>
|
||||
<Or>
|
||||
<And>
|
||||
<Kind Is="Interface" />
|
||||
<Or>
|
||||
<HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
|
||||
<HasAttribute Name="System.Runtime.InteropServices.ComImport" />
|
||||
</Or>
|
||||
</And>
|
||||
<Kind Is="Struct" />
|
||||
<HasAttribute Name="JetBrains.Annotations.NoReorderAttribute" />
|
||||
<HasAttribute Name="JetBrains.Annotations.NoReorder" />
|
||||
</Or>
|
||||
</TypePattern.Match>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasMember>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
|
||||
</And>
|
||||
</HasMember>
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constructor" />
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<ImplementsInterface Name="System.IDisposable" />
|
||||
</And>
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Kind Order="Constructor" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry Priority="100" DisplayName="Test Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="Xunit.FactAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<Or>
|
||||
<HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
|
||||
</Or>
|
||||
</And>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry Priority="100" DisplayName="Test Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="NUnit.Framework.TestAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="Default Pattern">
|
||||
<Entry Priority="100" DisplayName="Public Delegates">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Access Is="Public" />
|
||||
<Kind Is="Delegate" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry Priority="100" DisplayName="Public Enums">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Access Is="Public" />
|
||||
<Kind Is="Enum" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Static Fields and Constants">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constant" />
|
||||
<And>
|
||||
<Kind Is="Field" />
|
||||
<Static />
|
||||
</And>
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Kind Order="Constant Field" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Fields">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Field" />
|
||||
<Not>
|
||||
<Static />
|
||||
</Not>
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Properties, Indexers">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Property" />
|
||||
<Kind Is="Indexer" />
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry DisplayName="Constructors">
|
||||
<Entry.Match>
|
||||
<Kind Is="Constructor" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Interface Implementations">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Member" />
|
||||
<ImplementsInterface />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry DisplayName="Nested Types">
|
||||
<Entry.Match>
|
||||
<Kind Is="Type" />
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
</Patterns></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVarWhenEvident</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCLASS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCONSTRUCTOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FGLOBAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLABEL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FCONSTRUCTOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FOBJECT_005FPROPERTY_005FOF_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FCLASS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FINTERFACE/@EntryIndexedValue"><Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMIXED_005FENUM/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FEXPORTED/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FLOCAL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FALIAS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FHTML_005FCONTROL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FNAME/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FPREFIX/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/RazorCodeStyle/PreferQualifiedReference/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/TypeScriptCodeStyle/ExplicitPublicModifier/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/TypeScriptCodeStyle/ImportReferenceStyle/@EntryValue">ECMAScript6</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/TypeScriptCodeStyle/NoImplicitAny/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EJavaScript_002ECodeStyle_002ESettingsUpgrade_002EJsParsFormattingSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EJavaScript_002ECodeStyle_002ESettingsUpgrade_002EJsWrapperSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EJavaScript_002ECodeStyle_002ETypeScript_002ESettingsUpgrade_002ETsModuleAliasesSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
|
@ -3,156 +3,162 @@
|
|||
@using BuildFeed.Code
|
||||
@helper PaginationBlock(int currentPage, int totalPages, string view, RouteValueDictionary rd)
|
||||
{
|
||||
string multiView = view + "Page";
|
||||
string multiView = view + "Page";
|
||||
|
||||
if (totalPages > 1)
|
||||
{
|
||||
<ul class="pagination">
|
||||
@if (currentPage == 2)
|
||||
{
|
||||
RouteValueDictionary rvd = new RouteValueDictionary(rd);
|
||||
rvd.Remove("page");
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(view, rvd)">
|
||||
<i class="fa fa-angle-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(view, rvd)">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
else if (currentPage > 2)
|
||||
{
|
||||
RouteValueDictionary firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(view, firstRvd)">
|
||||
<i class="fa fa-angle-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
RouteValueDictionary rvd = new RouteValueDictionary(rd)
|
||||
if (totalPages > 1)
|
||||
{
|
||||
<ul class="pagination">
|
||||
@if (currentPage == 2)
|
||||
{
|
||||
["page"] = currentPage - 1
|
||||
};
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(multiView, rvd)">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-double-left"></i>
|
||||
</span>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
|
||||
|
||||
@{
|
||||
RouteValueDictionary rvdIndex = new RouteValueDictionary(rd);
|
||||
rvdIndex.Remove("page");
|
||||
IEnumerable<int> pages;
|
||||
}
|
||||
|
||||
@if (totalPages == 1)
|
||||
{
|
||||
RouteValueDictionary firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
pages = Array.Empty<int>();
|
||||
|
||||
<li @( 1 == currentPage ? "class=active" : "")>
|
||||
@MvcIntrinsics.Html.ActionLink(1.ToString(), view, firstRvd)
|
||||
</li>
|
||||
}
|
||||
else if (totalPages <= 7 && totalPages >= 2)
|
||||
{
|
||||
RouteValueDictionary firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
pages = Enumerable.Range(2, totalPages - 1);
|
||||
|
||||
<li @( 1 == currentPage ? "class=active" : "")>
|
||||
@MvcIntrinsics.Html.ActionLink(1.ToString(), view, firstRvd)
|
||||
</li>
|
||||
}
|
||||
else if (currentPage <= 4)
|
||||
{
|
||||
RouteValueDictionary firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
pages = Enumerable.Range(2, 6);
|
||||
|
||||
<li @( 1 == currentPage ? "class=active" : "")>
|
||||
@MvcIntrinsics.Html.ActionLink(1.ToString(), view, firstRvd)
|
||||
</li>
|
||||
}
|
||||
else if (currentPage >= totalPages - 2)
|
||||
{
|
||||
pages = Enumerable.Range(totalPages - 6, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
pages = Enumerable.Range(currentPage - 3, 7);
|
||||
}
|
||||
|
||||
@foreach (int i in pages)
|
||||
{
|
||||
RouteValueDictionary rvd = new RouteValueDictionary(rd)
|
||||
var rvd = new RouteValueDictionary(rd);
|
||||
rvd.Remove("page");
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(view, rvd)">
|
||||
<i class="fa fa-angle-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(view, rvd)">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
else if (currentPage > 2)
|
||||
{
|
||||
["page"] = i
|
||||
};
|
||||
var firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(view, firstRvd)">
|
||||
<i class="fa fa-angle-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li @( i == currentPage
|
||||
? "class=active"
|
||||
: "")>
|
||||
@MvcIntrinsics.Html.ActionLink(i.ToString(), multiView, rvd)</li>
|
||||
}
|
||||
|
||||
|
||||
@if (currentPage < totalPages)
|
||||
{
|
||||
RouteValueDictionary rvd = new RouteValueDictionary(rd)
|
||||
var rvd = new RouteValueDictionary(rd)
|
||||
{
|
||||
["page"] = currentPage - 1
|
||||
};
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(multiView, rvd)">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
["page"] = currentPage + 1
|
||||
};
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-double-left"></i>
|
||||
</span>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(multiView, rvd)">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
RouteValueDictionary lastRvd = new RouteValueDictionary(rd)
|
||||
@{
|
||||
var rvdIndex = new RouteValueDictionary(rd);
|
||||
rvdIndex.Remove("page");
|
||||
IEnumerable<int> pages;
|
||||
}
|
||||
|
||||
@if (totalPages == 1)
|
||||
{
|
||||
["page"] = totalPages
|
||||
};
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(multiView, lastRvd)">
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</span>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
var firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
pages = Array.Empty<int>();
|
||||
|
||||
<li @( 1 == currentPage
|
||||
? "class=active"
|
||||
: "")>
|
||||
@MvcIntrinsics.Html.ActionLink(1.ToString(), view, firstRvd)
|
||||
</li>
|
||||
}
|
||||
else if (totalPages <= 7 && totalPages >= 2)
|
||||
{
|
||||
var firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
pages = Enumerable.Range(2, totalPages - 1);
|
||||
|
||||
<li @( 1 == currentPage
|
||||
? "class=active"
|
||||
: "")>
|
||||
@MvcIntrinsics.Html.ActionLink(1.ToString(), view, firstRvd)
|
||||
</li>
|
||||
}
|
||||
else if (currentPage <= 4)
|
||||
{
|
||||
var firstRvd = new RouteValueDictionary(rd);
|
||||
firstRvd.Remove("page");
|
||||
pages = Enumerable.Range(2, 6);
|
||||
|
||||
<li @( 1 == currentPage
|
||||
? "class=active"
|
||||
: "")>
|
||||
@MvcIntrinsics.Html.ActionLink(1.ToString(), view, firstRvd)
|
||||
</li>
|
||||
}
|
||||
else if (currentPage >= totalPages - 2)
|
||||
{
|
||||
pages = Enumerable.Range(totalPages - 6, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
pages = Enumerable.Range(currentPage - 3, 7);
|
||||
}
|
||||
|
||||
@foreach (int i in pages)
|
||||
{
|
||||
var rvd = new RouteValueDictionary(rd)
|
||||
{
|
||||
["page"] = i
|
||||
};
|
||||
|
||||
<li @( i == currentPage
|
||||
? "class=active"
|
||||
: "")>
|
||||
@MvcIntrinsics.Html.ActionLink(i.ToString(), multiView, rvd)</li>
|
||||
}
|
||||
|
||||
|
||||
@if (currentPage < totalPages)
|
||||
{
|
||||
var rvd = new RouteValueDictionary(rd)
|
||||
{
|
||||
["page"] = currentPage + 1
|
||||
};
|
||||
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(multiView, rvd)">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
var lastRvd = new RouteValueDictionary(rd)
|
||||
{
|
||||
["page"] = totalPages
|
||||
};
|
||||
<li>
|
||||
<a href="@MvcIntrinsics.Url.Action(multiView, lastRvd)">
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</span>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<span>
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
}
|
|
@ -1,27 +1,22 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Security;
|
||||
using BuildFeed.Controllers;
|
||||
using BuildFeed.Model;
|
||||
|
||||
namespace BuildFeed.Admin.Controllers
|
||||
{
|
||||
[Authorize(Roles = "Administrators")]
|
||||
[RouteArea("admin")]
|
||||
[RoutePrefix("")]
|
||||
public class RootController : BaseController
|
||||
{
|
||||
[Authorize(Roles = "Administrators")]
|
||||
[Route("")]
|
||||
public ActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
public ActionResult Index() => View();
|
||||
|
||||
[Authorize(Roles = "Administrators")]
|
||||
[Route("regen-cache")]
|
||||
public async Task<ActionResult> RegenerateCache()
|
||||
{
|
||||
BuildRepository bRepo = new BuildRepository();
|
||||
var bRepo = new BuildRepository();
|
||||
await bRepo.RegenerateCachedProperties();
|
||||
|
||||
return RedirectToAction(nameof(Index));
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
@{
|
||||
ViewBag.Title = $"Administration | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"Administration | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>Administration</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
@Html.ActionLink("Manage users", nameof(UsersController.Index), "Users")
|
||||
<ul>
|
||||
<li>@Html.ActionLink("View administrators", nameof(UsersController.Admins), "Users")</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
@Html.ActionLink("Manage metadata", nameof(MetaController.Index), "Meta")
|
||||
</li>
|
||||
<li>
|
||||
@Html.ActionLink("Manage users", nameof(UsersController.Index), "Users")
|
||||
<ul>
|
||||
<li>@Html.ActionLink("View administrators", nameof(UsersController.Admins), "Users")</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
@Html.ActionLink("Manage metadata", nameof(MetaController.Index), "Meta")
|
||||
</li>
|
||||
<li>
|
||||
@Html.ActionLink("Regenerate cached properties", nameof(RootController.RegenerateCache), "Root")
|
||||
</li>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
using BuildFeed.Areas.admin.Models.ViewModel;
|
||||
using BuildFeed.Admin.Models.ViewModel;
|
||||
using BuildFeed.Controllers;
|
||||
using BuildFeed.Model;
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Security;
|
||||
|
@ -19,7 +18,7 @@ namespace BuildFeed.Admin.Controllers
|
|||
[Route("admins")]
|
||||
public ActionResult Admins()
|
||||
{
|
||||
List<MembershipUser> admins = Roles.GetUsersInRole("Administrators").Select(Membership.GetUser).ToList();
|
||||
var admins = Roles.GetUsersInRole("Administrators").Select(Membership.GetUser).ToList();
|
||||
|
||||
return View(admins.OrderByDescending(m => m.UserName));
|
||||
}
|
||||
|
@ -27,7 +26,7 @@ namespace BuildFeed.Admin.Controllers
|
|||
[Route("approve/{id:guid}")]
|
||||
public ActionResult Approve(Guid id)
|
||||
{
|
||||
MongoMembershipProvider provider = Membership.Provider as MongoMembershipProvider;
|
||||
var provider = Membership.Provider as MongoMembershipProvider;
|
||||
provider?.ChangeApproval(id, true);
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
@ -35,7 +34,7 @@ namespace BuildFeed.Admin.Controllers
|
|||
[Route("unapprove/{id:guid}")]
|
||||
public ActionResult Unapprove(Guid id)
|
||||
{
|
||||
MongoMembershipProvider provider = Membership.Provider as MongoMembershipProvider;
|
||||
var provider = Membership.Provider as MongoMembershipProvider;
|
||||
provider?.ChangeApproval(id, false);
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
@ -43,7 +42,7 @@ namespace BuildFeed.Admin.Controllers
|
|||
[Route("lock/{id:guid}")]
|
||||
public ActionResult Lock(Guid id)
|
||||
{
|
||||
MongoMembershipProvider provider = Membership.Provider as MongoMembershipProvider;
|
||||
var provider = Membership.Provider as MongoMembershipProvider;
|
||||
provider?.ChangeLockStatus(id, true);
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
@ -51,7 +50,7 @@ namespace BuildFeed.Admin.Controllers
|
|||
[Route("unlock/{id:guid}")]
|
||||
public ActionResult Unlock(Guid id)
|
||||
{
|
||||
MongoMembershipProvider provider = Membership.Provider as MongoMembershipProvider;
|
||||
var provider = Membership.Provider as MongoMembershipProvider;
|
||||
provider?.ChangeLockStatus(id, false);
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
@ -59,7 +58,7 @@ namespace BuildFeed.Admin.Controllers
|
|||
[Route("delete/{id:guid}")]
|
||||
public ActionResult Delete(Guid id)
|
||||
{
|
||||
MongoMembershipProvider provider = Membership.Provider as MongoMembershipProvider;
|
||||
var provider = Membership.Provider as MongoMembershipProvider;
|
||||
provider?.DeleteUser(id);
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using System.Linq;
|
||||
using BuildFeed.Model;
|
||||
|
||||
namespace BuildFeed.Areas.admin.Models.ViewModel
|
||||
namespace BuildFeed.Admin.Models.ViewModel
|
||||
{
|
||||
public class MetaListing
|
||||
{
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
@{
|
||||
Layout = "~/Views/shared/_default.cshtml";
|
||||
Layout = "~/Views/shared/_default.cshtml";
|
||||
}
|
|
@ -1,6 +1,12 @@
|
|||
@model BuildFeed.Model.MetaItemModel
|
||||
@using BuildFeed.Model
|
||||
@model MetaItemModel
|
||||
@{
|
||||
ViewBag.Title = $"Add metadata for {Model.Id.Value} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"Add metadata for {Model.Id.Value} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
<link href="~/Scripts/trumbowyg/ui/trumbowyg.min.css" rel="stylesheet" type="text/css" />
|
||||
}
|
||||
|
||||
<h1>@($"Add metadata for {Model.Id.Value}")</h1>
|
||||
|
@ -8,97 +14,94 @@
|
|||
|
||||
@using (Html.BeginForm())
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
@Html.HiddenFor(model => model.Id.Type)
|
||||
@Html.HiddenFor(model => model.Id.Value)
|
||||
@Html.HiddenFor(model => model.Id.Type)
|
||||
@Html.HiddenFor(model => model.Id.Value)
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.MetaDescription)
|
||||
<div class="wide-group">
|
||||
@Html.TextAreaFor(model => model.MetaDescription, new
|
||||
{
|
||||
rows = "4"
|
||||
})
|
||||
<div>
|
||||
<span id="meta-count">0</span> characters
|
||||
@Html.ValidationMessageFor(model => model.MetaDescription)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.MetaDescription)
|
||||
<div class="wide-group">
|
||||
@Html.TextAreaFor(model => model.MetaDescription, new
|
||||
{
|
||||
rows = "4"
|
||||
})
|
||||
<div>
|
||||
<span id="meta-count">0</span> characters
|
||||
@Html.ValidationMessageFor(model => model.MetaDescription)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.PageContent)
|
||||
<div class="wide-group">
|
||||
@Html.TextAreaFor(model => model.PageContent)
|
||||
<div>
|
||||
@Html.ValidationMessageFor(model => model.PageContent)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.PageContent)
|
||||
<div class="wide-group">
|
||||
@Html.TextAreaFor(model => model.PageContent)
|
||||
<div>
|
||||
@Html.ValidationMessageFor(model => model.PageContent)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="Add metadata" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="Add metadata" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="~/Scripts/trumbowyg/trumbowyg.min.js" type="text/javascript"></script>
|
||||
<link href="~/Scripts/trumbowyg/ui/trumbowyg.min.css" rel="stylesheet" type="text/css" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="~/Scripts/trumbowyg/trumbowyg.min.js" type="text/javascript"></script>
|
||||
|
||||
<script src="~/Scripts/jquery.validate.js" type="text/javascript"></script>
|
||||
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js" integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js" integrity="sha256-g1QKGxqsp+x5JkuN/JjHl96je2wztgS5Wo4h4c7gm9M=" crossorigin="anonymous"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function updateMetaCount()
|
||||
{
|
||||
var count = document.getElementById("@Html.IdFor(model => model.MetaDescription)").value.length;
|
||||
$("#meta-count").text(count.toFixed(0));
|
||||
if (count === 0)
|
||||
{
|
||||
$("#meta-count").attr("class", "");
|
||||
}
|
||||
else if (count < 160)
|
||||
{
|
||||
$("#meta-count").attr("class", "text-success");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#meta-count").attr("class", "text-danger");
|
||||
}
|
||||
}
|
||||
|
||||
$(function()
|
||||
{
|
||||
var btnsGrps = $.trumbowyg.btnsGrps;
|
||||
|
||||
$("#@Html.IdFor(model => model.PageContent)")
|
||||
.trumbowyg({
|
||||
autogrow: true,
|
||||
btns: [
|
||||
['strong', 'em'],
|
||||
'|', 'link',
|
||||
'|', 'btnGrp-lists',
|
||||
'|', 'btnGrp-justify',
|
||||
'|', 'viewHTML',
|
||||
'|'
|
||||
]
|
||||
});
|
||||
|
||||
$(".trumbowyg").addClass("trumbowyg-black");
|
||||
|
||||
$("#@Html.IdFor(model => model.MetaDescription)")
|
||||
.keyup(function()
|
||||
<script type="text/javascript">
|
||||
function updateMetaCount()
|
||||
{
|
||||
var count = document.getElementById("@Html.IdFor(model => model.MetaDescription)").value.length;
|
||||
$("#meta-count").text(count.toFixed(0));
|
||||
if (count === 0)
|
||||
{
|
||||
updateMetaCount();
|
||||
});
|
||||
$("#meta-count").attr("class", "");
|
||||
}
|
||||
else if (count < 160)
|
||||
{
|
||||
$("#meta-count").attr("class", "text-success");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#meta-count").attr("class", "text-danger");
|
||||
}
|
||||
}
|
||||
|
||||
updateMetaCount();
|
||||
});
|
||||
</script>
|
||||
$(function()
|
||||
{
|
||||
$.trumbowyg.svgPath = "/Scripts/trumbowyg/ui/icons.svg";
|
||||
|
||||
$("#@Html.IdFor(model => model.PageContent)")
|
||||
.trumbowyg({
|
||||
autogrow: true,
|
||||
btns: [
|
||||
['strong', 'em'],
|
||||
'|', 'link',
|
||||
'|', ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
|
||||
'|', ['unorderedList', 'orderedList'],
|
||||
'|', 'viewHTML',
|
||||
'|'
|
||||
]
|
||||
});
|
||||
|
||||
$("#@Html.IdFor(model => model.MetaDescription)")
|
||||
.keyup(function()
|
||||
{
|
||||
updateMetaCount();
|
||||
});
|
||||
|
||||
updateMetaCount();
|
||||
});
|
||||
</script>
|
||||
}
|
|
@ -1,81 +1,82 @@
|
|||
@using BuildFeed.Model
|
||||
@model BuildFeed.Areas.admin.Models.ViewModel.MetaListing
|
||||
@using BuildFeed.Admin.Models.ViewModel
|
||||
@using BuildFeed.Model
|
||||
@model MetaListing
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"Manage metadata | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"Manage metadata | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>Manage metadata</h1>
|
||||
<ul>
|
||||
<li>@Html.ActionLink("Return to admin panel", nameof(RootController.Index), "Root")</li>
|
||||
<li>@Html.ActionLink("Return to admin panel", nameof(RootController.Index), "Root")</li>
|
||||
</ul>
|
||||
<h3>Current items</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th style="width: 50px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (IGrouping<MetaType, MetaItemModel> group in Model.CurrentItems)
|
||||
{
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>@group.Key</h4>
|
||||
</td>
|
||||
</tr>
|
||||
foreach (MetaItemModel item in group)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Id.Value</td>
|
||||
<td>
|
||||
@Html.ActionLink("Edit", nameof(MetaController.Edit), new
|
||||
{
|
||||
type = item.Id.Type,
|
||||
value = item.Id.Value
|
||||
}, new
|
||||
{
|
||||
@class = "button",
|
||||
style = "width:50px"
|
||||
})</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th style="width: 50px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var group in Model.CurrentItems)
|
||||
{
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>@group.Key</h4>
|
||||
</td>
|
||||
</tr>
|
||||
foreach (MetaItemModel item in group)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Id.Value</td>
|
||||
<td>
|
||||
@Html.ActionLink("Edit", nameof(MetaController.Edit), new
|
||||
{
|
||||
type = item.Id.Type,
|
||||
value = item.Id.Value
|
||||
}, new
|
||||
{
|
||||
@class = "button",
|
||||
style = "width:50px"
|
||||
})</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Add new items</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th style="width: 50px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (IGrouping<MetaType, MetaItemModel> group in Model.NewItems)
|
||||
{
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>@group.Key</h4>
|
||||
</td>
|
||||
</tr>
|
||||
foreach (MetaItemModel item in group)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Id.Value</td>
|
||||
<td>
|
||||
@Html.ActionLink("Create", nameof(MetaController.Create), new
|
||||
{
|
||||
type = item.Id.Type,
|
||||
value = item.Id.Value
|
||||
}, new
|
||||
{
|
||||
@class = "button",
|
||||
style = "width:50px"
|
||||
})</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th style="width: 50px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var group in Model.NewItems)
|
||||
{
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>@group.Key</h4>
|
||||
</td>
|
||||
</tr>
|
||||
foreach (MetaItemModel item in group)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Id.Value</td>
|
||||
<td>
|
||||
@Html.ActionLink("Create", nameof(MetaController.Create), new
|
||||
{
|
||||
type = item.Id.Type,
|
||||
value = item.Id.Value
|
||||
}, new
|
||||
{
|
||||
@class = "button",
|
||||
style = "width:50px"
|
||||
})</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
|
@ -2,46 +2,46 @@
|
|||
@model IEnumerable<MembershipUser>
|
||||
|
||||
@{
|
||||
ViewBag.Title = "View administrators | BuildFeed";
|
||||
ViewBag.Title = "View administrators | BuildFeed";
|
||||
}
|
||||
|
||||
<h1>View administrators</h1>
|
||||
|
||||
<ul>
|
||||
<li>@Html.ActionLink("Manage users", "Index")</li>
|
||||
<li>@Html.ActionLink("Return to admin panel", "Index", "Root")</li>
|
||||
<li>@Html.ActionLink("Manage users", "Index")</li>
|
||||
<li>@Html.ActionLink("Return to admin panel", "Index", "Root")</li>
|
||||
</ul>
|
||||
|
||||
<table class="table table-striped table-bordered table-admin">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Username
|
||||
</th>
|
||||
<th>
|
||||
Email Address
|
||||
</th>
|
||||
<th>
|
||||
Last Login Time
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (MembershipUser mu in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@mu.UserName
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:@mu.Email">@mu.Email</a>
|
||||
</td>
|
||||
<td>
|
||||
@(mu.LastLoginDate == default(DateTime)
|
||||
? "Never"
|
||||
: mu.LastLoginDate.Humanize())
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Username
|
||||
</th>
|
||||
<th>
|
||||
Email Address
|
||||
</th>
|
||||
<th>
|
||||
Last Login Time
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (MembershipUser mu in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@mu.UserName
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:@mu.Email">@mu.Email</a>
|
||||
</td>
|
||||
<td>
|
||||
@(mu.LastLoginDate == default(DateTime)
|
||||
? "Never"
|
||||
: mu.LastLoginDate.Humanize())
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
|
@ -2,108 +2,108 @@
|
|||
@model IEnumerable<MembershipUser>
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"Manage users | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"Manage users | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>Manage users</h1>
|
||||
|
||||
<ul>
|
||||
<li>@Html.ActionLink("View administrators", "Admins")</li>
|
||||
<li>@Html.ActionLink("Clean-up old unapproved users", "Cleanup")</li>
|
||||
<li>@Html.ActionLink("Return to admin panel", "Index", "Root")</li>
|
||||
<li>@Html.ActionLink("View administrators", "Admins")</li>
|
||||
<li>@Html.ActionLink("Clean-up old unapproved users", "Cleanup")</li>
|
||||
<li>@Html.ActionLink("Return to admin panel", "Index", "Root")</li>
|
||||
</ul>
|
||||
|
||||
<table id="user-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Username
|
||||
</th>
|
||||
<th>
|
||||
Email Address
|
||||
</th>
|
||||
<th>
|
||||
Registration Time
|
||||
</th>
|
||||
<th>
|
||||
Last Login Time
|
||||
</th>
|
||||
<th>
|
||||
Last Lockout Time
|
||||
</th>
|
||||
<th style="width: 100px;"></th>
|
||||
<th style="width: 100px;"></th>
|
||||
<th style="width: 100px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (MembershipUser mu in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@mu.UserName
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:@mu.Email" title="@mu.Email">@mu.Email</a>
|
||||
</td>
|
||||
<td>
|
||||
@mu.CreationDate.Humanize()
|
||||
</td>
|
||||
<td>
|
||||
@(mu.LastLoginDate == DateTime.MinValue
|
||||
? "Never"
|
||||
: mu.LastLoginDate.Humanize())
|
||||
</td>
|
||||
<td>
|
||||
@(mu.LastLockoutDate == DateTime.MinValue
|
||||
? "Never"
|
||||
: mu.LastLockoutDate.Humanize())
|
||||
</td>
|
||||
<td class="text-right">
|
||||
@(mu.IsApproved
|
||||
? Html.ActionLink("Unapprove", nameof(UsersController.Unapprove), new
|
||||
{
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Username
|
||||
</th>
|
||||
<th>
|
||||
Email Address
|
||||
</th>
|
||||
<th>
|
||||
Registration Time
|
||||
</th>
|
||||
<th>
|
||||
Last Login Time
|
||||
</th>
|
||||
<th>
|
||||
Last Lockout Time
|
||||
</th>
|
||||
<th style="width: 100px;"></th>
|
||||
<th style="width: 100px;"></th>
|
||||
<th style="width: 100px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (MembershipUser mu in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@mu.UserName
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:@mu.Email" title="@mu.Email">@mu.Email</a>
|
||||
</td>
|
||||
<td>
|
||||
@mu.CreationDate.Humanize()
|
||||
</td>
|
||||
<td>
|
||||
@(mu.LastLoginDate == DateTime.MinValue
|
||||
? "Never"
|
||||
: mu.LastLoginDate.Humanize())
|
||||
</td>
|
||||
<td>
|
||||
@(mu.LastLockoutDate == DateTime.MinValue
|
||||
? "Never"
|
||||
: mu.LastLockoutDate.Humanize())
|
||||
</td>
|
||||
<td class="text-right">
|
||||
@(mu.IsApproved
|
||||
? Html.ActionLink("Unapprove", nameof(UsersController.Unapprove), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button"
|
||||
})
|
||||
: Html.ActionLink("Approve", nameof(UsersController.Approve), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button add-button"
|
||||
}))
|
||||
</td>
|
||||
<td class="text-right">
|
||||
@(!mu.IsLockedOut
|
||||
? Html.ActionLink("Lock", nameof(UsersController.Lock), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button"
|
||||
})
|
||||
: Html.ActionLink("Unlock", nameof(UsersController.Unlock), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button add-button"
|
||||
}))
|
||||
</td>
|
||||
<td>
|
||||
@Html.ActionLink("Delete", nameof(UsersController.Delete), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button"
|
||||
})
|
||||
: Html.ActionLink("Approve", nameof(UsersController.Approve), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button add-button"
|
||||
}))
|
||||
</td>
|
||||
<td class="text-right">
|
||||
@(!mu.IsLockedOut
|
||||
? Html.ActionLink("Lock", nameof(UsersController.Lock), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button"
|
||||
})
|
||||
: Html.ActionLink("Unlock", nameof(UsersController.Unlock), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button add-button"
|
||||
}))
|
||||
</td>
|
||||
<td>
|
||||
@Html.ActionLink("Delete", nameof(UsersController.Delete), new
|
||||
{
|
||||
id = mu.ProviderUserKey
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button",
|
||||
onclick = @"return !(confirm(""Are you sure you want to delete this user?"") === false);"
|
||||
})
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button",
|
||||
onclick = @"return !(confirm(""Are you sure you want to delete this user?"") === false);"
|
||||
})
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,36 +1,36 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="BuildFeed" />
|
||||
<add namespace="BuildFeed.Local" />
|
||||
<add namespace="BuildFeed.Admin.Controllers" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="BuildFeed" />
|
||||
<add namespace="BuildFeed.Local" />
|
||||
<add namespace="BuildFeed.Admin.Controllers" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler" />
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler" />
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -1,6 +1,6 @@
|
|||
using System.Web.Mvc;
|
||||
|
||||
namespace BuildFeed.Areas.admin
|
||||
namespace BuildFeed.Admin
|
||||
{
|
||||
public class AdminAreaRegistration : AreaRegistration
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<users>
|
||||
<user>77FAD24B9B2579631630796D246267C3</user>
|
||||
<user>77FAD24B9B2579631630796D246267C3</user>
|
||||
</users>
|
|
@ -372,16 +372,6 @@
|
|||
<Content Include="res\css\inc\_variables.scss" />
|
||||
<Content Include="res\css\inc\_nord.scss" />
|
||||
<Content Include="res\css\winter.scss" />
|
||||
<None Include="Scripts\jquery-3.3.1.intellisense.js" />
|
||||
<Content Include="Scripts\jquery-3.3.1.js" />
|
||||
<Content Include="Scripts\jquery-3.3.1.min.js" />
|
||||
<Content Include="Scripts\jquery-3.3.1.slim.js" />
|
||||
<Content Include="Scripts\jquery-3.3.1.slim.min.js" />
|
||||
<None Include="Scripts\jquery.validate-vsdoc.js" />
|
||||
<Content Include="Scripts\jquery.validate.js" />
|
||||
<Content Include="Scripts\jquery.validate.min.js" />
|
||||
<Content Include="Scripts\jquery.validate.unobtrusive.js" />
|
||||
<Content Include="Scripts\jquery.validate.unobtrusive.min.js" />
|
||||
<Content Include="Scripts\trumbowyg\langs\ar.min.js" />
|
||||
<Content Include="Scripts\trumbowyg\langs\bg.min.js" />
|
||||
<Content Include="Scripts\trumbowyg\langs\by.min.js" />
|
||||
|
@ -482,8 +472,6 @@
|
|||
<Content Include="Views\front\AddBulk.cshtml" />
|
||||
<Content Include="Views\account\validate-success.cshtml" />
|
||||
<Content Include="Views\account\validate-failure.cshtml" />
|
||||
<Content Include="Scripts\jquery-3.3.1.slim.min.map" />
|
||||
<Content Include="Scripts\jquery-3.3.1.min.map" />
|
||||
<None Include="tsconfig.json" />
|
||||
<Content Include="Views\front\ViewFamily.cshtml" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BuildFeed.Code
|
|||
var returnArray = new byte[byteCount];
|
||||
|
||||
byte curByte = 0,
|
||||
bitsRemaining = 8;
|
||||
bitsRemaining = 8;
|
||||
|
||||
int arrayIndex = 0;
|
||||
|
||||
|
@ -62,7 +62,7 @@ namespace BuildFeed.Code
|
|||
var returnArray = new char[charCount];
|
||||
|
||||
byte nextChar = 0,
|
||||
bitsRemaining = 5;
|
||||
bitsRemaining = 5;
|
||||
int arrayIndex = 0;
|
||||
|
||||
foreach (byte b in input)
|
||||
|
@ -103,11 +103,13 @@ namespace BuildFeed.Code
|
|||
{
|
||||
return value - 65;
|
||||
}
|
||||
|
||||
//50-55 == numbers 2-7
|
||||
if (value < 56 && value > 49)
|
||||
{
|
||||
return value - 24;
|
||||
}
|
||||
|
||||
//97-122 == lowercase letters
|
||||
if (value < 123 && value > 96)
|
||||
{
|
||||
|
|
|
@ -10,11 +10,18 @@ namespace BuildFeed.Code
|
|||
{
|
||||
ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
||||
|
||||
bool success = DateTime.TryParse(value.AttemptedValue, CultureInfo.CurrentUICulture.DateTimeFormat, DateTimeStyles.AllowWhiteSpaces, out DateTime retValue);
|
||||
bool success = DateTime.TryParse(value.AttemptedValue,
|
||||
CultureInfo.CurrentUICulture.DateTimeFormat,
|
||||
DateTimeStyles.AllowWhiteSpaces,
|
||||
out DateTime retValue);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
success = DateTime.TryParseExact(value.AttemptedValue, "yyMMdd-HHmm", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out retValue);
|
||||
success = DateTime.TryParseExact(value.AttemptedValue,
|
||||
"yyMMdd-HHmm",
|
||||
CultureInfo.InvariantCulture,
|
||||
DateTimeStyles.AllowWhiteSpaces,
|
||||
out retValue);
|
||||
}
|
||||
|
||||
return success
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace BuildFeed.Code
|
|||
public static IHtmlString CheckboxListForEnum<T>(this HtmlHelper html, string id, T currentItem)
|
||||
where T : struct
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (T enumItem in Enum.GetValues(typeof(T)).Cast<T>())
|
||||
{
|
||||
|
@ -26,16 +26,17 @@ namespace BuildFeed.Code
|
|||
continue;
|
||||
}
|
||||
|
||||
TagBuilder wrapper = new TagBuilder("div");
|
||||
var wrapper = new TagBuilder("div");
|
||||
wrapper.Attributes.Add("class", "checkbox");
|
||||
|
||||
TagBuilder label = new TagBuilder("label");
|
||||
var label = new TagBuilder("label");
|
||||
|
||||
TagBuilder input = new TagBuilder("input");
|
||||
var input = new TagBuilder("input");
|
||||
if ((enumValue & currentValue) != 0)
|
||||
{
|
||||
input.MergeAttribute("checked", "checked");
|
||||
}
|
||||
|
||||
input.MergeAttribute("type", "checkbox");
|
||||
input.MergeAttribute("value", enumValue.ToString());
|
||||
input.MergeAttribute("name", id);
|
||||
|
|
|
@ -9,12 +9,12 @@ namespace BuildFeed.Code
|
|||
{
|
||||
public static async Task SendRegistrationEmail(MembershipUser mu, string validationLink)
|
||||
{
|
||||
using (MailMessage mm = new MailMessage(EMAIL_FROM, mu.Email))
|
||||
using (var mm = new MailMessage(EMAIL_FROM, mu.Email))
|
||||
{
|
||||
mm.Subject = string.Format(VariantTerms.Email_Registration_Subject, InvariantTerms.SiteName);
|
||||
mm.Body = string.Format(VariantTerms.Email_Registration_Body, InvariantTerms.SiteName, validationLink);
|
||||
|
||||
using (SmtpClient sc = new SmtpClient())
|
||||
using (var sc = new SmtpClient())
|
||||
{
|
||||
await sc.SendMailAsync(mm);
|
||||
}
|
||||
|
|
|
@ -19,48 +19,50 @@ namespace BuildFeed.Code
|
|||
AppId = Guid.Parse(ConfigurationManager.AppSettings["push:AppId"]),
|
||||
IncludedSegments = new List<string>
|
||||
{
|
||||
#if DEBUG
|
||||
#if DEBUG
|
||||
"Testers"
|
||||
#else
|
||||
#else
|
||||
"All"
|
||||
#endif
|
||||
#endif
|
||||
},
|
||||
Headings =
|
||||
{
|
||||
{LanguageCodes.Arabic, GetNewBuildTitleForLanguage("ar")},
|
||||
{LanguageCodes.Czech, GetNewBuildTitleForLanguage("cs")},
|
||||
{LanguageCodes.German, GetNewBuildTitleForLanguage("de")},
|
||||
{LanguageCodes.Greek, GetNewBuildTitleForLanguage("el")},
|
||||
{LanguageCodes.English, GetNewBuildTitleForLanguage("en")},
|
||||
{LanguageCodes.Spanish, GetNewBuildTitleForLanguage("es")},
|
||||
{LanguageCodes.Persian, GetNewBuildTitleForLanguage("fa")},
|
||||
{LanguageCodes.Finnish, GetNewBuildTitleForLanguage("fi")},
|
||||
{LanguageCodes.French, GetNewBuildTitleForLanguage("fr")},
|
||||
{LanguageCodes.Hebrew, GetNewBuildTitleForLanguage("he")},
|
||||
{LanguageCodes.Croatian, GetNewBuildTitleForLanguage("hr")},
|
||||
{LanguageCodes.Hungarian, GetNewBuildTitleForLanguage("hu")},
|
||||
{LanguageCodes.Indonesian, GetNewBuildTitleForLanguage("id")},
|
||||
{LanguageCodes.Italian, GetNewBuildTitleForLanguage("it")},
|
||||
{LanguageCodes.Japanese, GetNewBuildTitleForLanguage("ja")},
|
||||
{LanguageCodes.Korean, GetNewBuildTitleForLanguage("ko")},
|
||||
{LanguageCodes.Lithuanian, GetNewBuildTitleForLanguage("lt")},
|
||||
{LanguageCodes.Dutch, GetNewBuildTitleForLanguage("nl")},
|
||||
{LanguageCodes.Polish, GetNewBuildTitleForLanguage("pl")},
|
||||
{LanguageCodes.Portuguese, GetNewBuildTitleForLanguage("pt")}, // Portuguese translation has notification translation ready, Brazil is used more, but not available right now.
|
||||
{LanguageCodes.Romanian, GetNewBuildTitleForLanguage("ro")},
|
||||
{LanguageCodes.Russian, GetNewBuildTitleForLanguage("ru")},
|
||||
{LanguageCodes.Slovak, GetNewBuildTitleForLanguage("sk")},
|
||||
{ LanguageCodes.Arabic, GetNewBuildTitleForLanguage("ar") },
|
||||
{ LanguageCodes.Czech, GetNewBuildTitleForLanguage("cs") },
|
||||
{ LanguageCodes.German, GetNewBuildTitleForLanguage("de") },
|
||||
{ LanguageCodes.Greek, GetNewBuildTitleForLanguage("el") },
|
||||
{ LanguageCodes.English, GetNewBuildTitleForLanguage("en") },
|
||||
{ LanguageCodes.Spanish, GetNewBuildTitleForLanguage("es") },
|
||||
{ LanguageCodes.Persian, GetNewBuildTitleForLanguage("fa") },
|
||||
{ LanguageCodes.Finnish, GetNewBuildTitleForLanguage("fi") },
|
||||
{ LanguageCodes.French, GetNewBuildTitleForLanguage("fr") },
|
||||
{ LanguageCodes.Hebrew, GetNewBuildTitleForLanguage("he") },
|
||||
{ LanguageCodes.Croatian, GetNewBuildTitleForLanguage("hr") },
|
||||
{ LanguageCodes.Hungarian, GetNewBuildTitleForLanguage("hu") },
|
||||
{ LanguageCodes.Indonesian, GetNewBuildTitleForLanguage("id") },
|
||||
{ LanguageCodes.Italian, GetNewBuildTitleForLanguage("it") },
|
||||
{ LanguageCodes.Japanese, GetNewBuildTitleForLanguage("ja") },
|
||||
{ LanguageCodes.Korean, GetNewBuildTitleForLanguage("ko") },
|
||||
{ LanguageCodes.Lithuanian, GetNewBuildTitleForLanguage("lt") },
|
||||
{ LanguageCodes.Dutch, GetNewBuildTitleForLanguage("nl") },
|
||||
{ LanguageCodes.Polish, GetNewBuildTitleForLanguage("pl") },
|
||||
{
|
||||
LanguageCodes.Portuguese, GetNewBuildTitleForLanguage("pt")
|
||||
}, // Portuguese translation has notification translation ready, Brazil is used more, but not available right now.
|
||||
{ LanguageCodes.Romanian, GetNewBuildTitleForLanguage("ro") },
|
||||
{ LanguageCodes.Russian, GetNewBuildTitleForLanguage("ru") },
|
||||
{ LanguageCodes.Slovak, GetNewBuildTitleForLanguage("sk") },
|
||||
// no slovenian support for OneSignal?
|
||||
{LanguageCodes.Swedish, GetNewBuildTitleForLanguage("sv")},
|
||||
{LanguageCodes.Turkish, GetNewBuildTitleForLanguage("tr")},
|
||||
{LanguageCodes.Ukrainian, GetNewBuildTitleForLanguage("uk")},
|
||||
{LanguageCodes.Vietnamese, GetNewBuildTitleForLanguage("vi")},
|
||||
{LanguageCodes.ChineseSimplified, GetNewBuildTitleForLanguage("zh-hans")},
|
||||
{LanguageCodes.ChineseTraditional, GetNewBuildTitleForLanguage("zh-hant")}
|
||||
{ LanguageCodes.Swedish, GetNewBuildTitleForLanguage("sv") },
|
||||
{ LanguageCodes.Turkish, GetNewBuildTitleForLanguage("tr") },
|
||||
{ LanguageCodes.Ukrainian, GetNewBuildTitleForLanguage("uk") },
|
||||
{ LanguageCodes.Vietnamese, GetNewBuildTitleForLanguage("vi") },
|
||||
{ LanguageCodes.ChineseSimplified, GetNewBuildTitleForLanguage("zh-hans") },
|
||||
{ LanguageCodes.ChineseTraditional, GetNewBuildTitleForLanguage("zh-hant") }
|
||||
},
|
||||
Contents =
|
||||
{
|
||||
{LanguageCodes.English, build.AlternateBuildString}
|
||||
{ LanguageCodes.English, build.AlternateBuildString }
|
||||
},
|
||||
Url = url
|
||||
});
|
||||
|
@ -68,9 +70,13 @@ namespace BuildFeed.Code
|
|||
|
||||
private static string GetNewBuildTitleForLanguage(string lang)
|
||||
{
|
||||
string localised = VariantTerms.ResourceManager.GetString(nameof(VariantTerms.Notification_NewBuild), CultureInfo.GetCultureInfo(lang));
|
||||
string localised = VariantTerms.ResourceManager.GetString(nameof(VariantTerms.Notification_NewBuild),
|
||||
CultureInfo.GetCultureInfo(lang));
|
||||
|
||||
string generic = VariantTerms.ResourceManager.GetString(nameof(VariantTerms.Notification_NewBuild), CultureInfo.InvariantCulture) ?? "{0}";
|
||||
string generic =
|
||||
VariantTerms.ResourceManager.GetString(nameof(VariantTerms.Notification_NewBuild),
|
||||
CultureInfo.InvariantCulture)
|
||||
?? "{0}";
|
||||
|
||||
return string.IsNullOrEmpty(localised)
|
||||
? string.Format(generic, InvariantTerms.SiteName)
|
||||
|
|
|
@ -64,10 +64,12 @@ namespace BuildFeed.Code.Options
|
|||
{
|
||||
try
|
||||
{
|
||||
CultureInfo ci = (CultureInfo)CultureInfo.GetCultureInfo(langCookie).Clone();
|
||||
var ci = (CultureInfo)CultureInfo.GetCultureInfo(langCookie).Clone();
|
||||
|
||||
// Get Gregorian Calendar in locale if available
|
||||
Calendar gc = ci.OptionalCalendars.FirstOrDefault(c => c is GregorianCalendar && ((GregorianCalendar)c).CalendarType == GregorianCalendarTypes.Localized);
|
||||
Calendar gc = ci.OptionalCalendars.FirstOrDefault(c
|
||||
=> c is GregorianCalendar
|
||||
&& ((GregorianCalendar)c).CalendarType == GregorianCalendarTypes.Localized);
|
||||
if (gc != null)
|
||||
{
|
||||
ci.DateTimeFormat.Calendar = gc;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace BuildFeed.Code
|
|||
public override void OnResultExecuted(ResultExecutedContext filterContext)
|
||||
{
|
||||
bool isRtl = CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft;
|
||||
Theme theme = new Theme(Theme.DetectTheme(filterContext.HttpContext));
|
||||
var theme = new Theme(Theme.DetectTheme(filterContext.HttpContext));
|
||||
|
||||
filterContext.HttpContext.Response.PushPromise("/res/css/default.css");
|
||||
filterContext.HttpContext.Response.PushPromise(VirtualPathUtility.ToAbsolute(theme.CssPath));
|
||||
|
@ -18,6 +18,7 @@ namespace BuildFeed.Code
|
|||
{
|
||||
filterContext.HttpContext.Response.PushPromise("/res/css/rtl.css");
|
||||
}
|
||||
|
||||
filterContext.HttpContext.Response.PushPromise("/res/ts/bfs.js");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
@ -31,9 +30,9 @@ namespace BuildFeed.Controllers
|
|||
? 129600
|
||||
: 60;
|
||||
|
||||
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(ru.UserName, true, expiryLength);
|
||||
var ticket = new FormsAuthenticationTicket(ru.UserName, true, expiryLength);
|
||||
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
|
||||
HttpCookie cookieTicket = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
|
||||
var cookieTicket = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
|
||||
{
|
||||
Expires = DateTime.Now.AddMinutes(expiryLength),
|
||||
Path = FormsAuthentication.FormsCookiePath
|
||||
|
@ -98,7 +97,13 @@ namespace BuildFeed.Controllers
|
|||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
MembershipUser mu = Membership.CreateUser(ru.UserName, ru.Password, ru.EmailAddress, "{IGNORE}", "{IGNORE}", false, out MembershipCreateStatus status);
|
||||
MembershipUser mu = Membership.CreateUser(ru.UserName,
|
||||
ru.Password,
|
||||
ru.EmailAddress,
|
||||
"{IGNORE}",
|
||||
"{IGNORE}",
|
||||
false,
|
||||
out MembershipCreateStatus status);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
@ -106,17 +111,18 @@ namespace BuildFeed.Controllers
|
|||
{
|
||||
Roles.AddUserToRole(mu.UserName, "Users");
|
||||
|
||||
MongoMembershipProvider provider = (MongoMembershipProvider)Membership.Provider;
|
||||
Guid id = (Guid)mu.ProviderUserKey;
|
||||
var provider = (MongoMembershipProvider)Membership.Provider;
|
||||
var id = (Guid)mu.ProviderUserKey;
|
||||
string hash = (await provider.GenerateValidationHash(id)).ToLowerInvariant();
|
||||
|
||||
string fullUrl = Request.Url?.GetLeftPart(UriPartial.Authority) + Url.Action("Validate",
|
||||
"Account",
|
||||
new
|
||||
{
|
||||
id,
|
||||
hash
|
||||
});
|
||||
string fullUrl = Request.Url?.GetLeftPart(UriPartial.Authority)
|
||||
+ Url.Action("Validate",
|
||||
"Account",
|
||||
new
|
||||
{
|
||||
id,
|
||||
hash
|
||||
});
|
||||
await EmailManager.SendRegistrationEmail(mu, fullUrl);
|
||||
return RedirectToAction(nameof(RegisterThanks));
|
||||
}
|
||||
|
@ -144,7 +150,7 @@ namespace BuildFeed.Controllers
|
|||
[Route("validate/{id:guid}/{hash}/")]
|
||||
public async Task<ActionResult> Validate(Guid id, string hash)
|
||||
{
|
||||
MongoMembershipProvider provider = (MongoMembershipProvider)Membership.Provider;
|
||||
var provider = (MongoMembershipProvider)Membership.Provider;
|
||||
bool success = await provider.ValidateUserFromHash(id, hash);
|
||||
|
||||
return View(success
|
||||
|
|
|
@ -27,39 +27,30 @@ namespace BuildFeed.Controllers
|
|||
}
|
||||
|
||||
public async Task<ApiBuild[]> GetBuilds(int limit = 20, int skip = 0)
|
||||
{
|
||||
return (from b in await _bModel.SelectBuildsByOrder(limit, skip)
|
||||
select Mapper.Map<ApiBuild>(b)).ToArray();
|
||||
}
|
||||
=> (from b in await _bModel.SelectBuildsByOrder(limit, skip)
|
||||
select Mapper.Map<ApiBuild>(b)).ToArray();
|
||||
|
||||
public async Task<FrontBuildGroup[]> GetBuildGroups(int limit = 20, int skip = 0)
|
||||
{
|
||||
FrontBuildGroup[] bgroups = await _bModel.SelectAllGroups(limit, skip);
|
||||
var bgroups = await _bModel.SelectAllGroups(limit, skip);
|
||||
return bgroups.ToArray();
|
||||
}
|
||||
|
||||
public async Task<ApiBuild[]> GetBuildsForBuildGroup(uint major, uint minor, uint number, uint? revision = null)
|
||||
{
|
||||
return (from b in await _bModel.SelectGroup(new BuildGroup
|
||||
{
|
||||
Major = major,
|
||||
Minor = minor,
|
||||
Build = number,
|
||||
Revision = revision
|
||||
})
|
||||
select Mapper.Map<ApiBuild>(b)).ToArray();
|
||||
}
|
||||
=> (from b in await _bModel.SelectGroup(new BuildGroup
|
||||
{
|
||||
Major = major,
|
||||
Minor = minor,
|
||||
Build = number,
|
||||
Revision = revision
|
||||
})
|
||||
select Mapper.Map<ApiBuild>(b)).ToArray();
|
||||
|
||||
public async Task<ApiBuild[]> GetBuildsByLab(string lab, int limit = 20, int skip = 0)
|
||||
{
|
||||
return (from b in await _bModel.SelectLab(lab, limit, skip)
|
||||
select Mapper.Map<ApiBuild>(b)).ToArray();
|
||||
}
|
||||
=> (from b in await _bModel.SelectLab(lab, limit, skip)
|
||||
select Mapper.Map<ApiBuild>(b)).ToArray();
|
||||
|
||||
public async Task<List<FamilyOverview>> GetFamilyOverviews()
|
||||
{
|
||||
return await _bModel.SelectFamilyOverviews();
|
||||
}
|
||||
public async Task<List<FamilyOverview>> GetFamilyOverviews() => await _bModel.SelectFamilyOverviews();
|
||||
|
||||
public async Task<IEnumerable<string>> GetWin10Labs()
|
||||
{
|
||||
|
@ -77,11 +68,14 @@ namespace BuildFeed.Controllers
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (Membership.ValidateUser(apiModel.Username, apiModel.Password) && (Roles.IsUserInRole(apiModel.Username, "Editors") || Roles.IsUserInRole(apiModel.Username, "Administrators")))
|
||||
|
||||
if (Membership.ValidateUser(apiModel.Username, apiModel.Password)
|
||||
&& (Roles.IsUserInRole(apiModel.Username, "Editors")
|
||||
|| Roles.IsUserInRole(apiModel.Username, "Administrators")))
|
||||
{
|
||||
var generateOldItem = new Func<NewBuild, BuildDetails>(nb =>
|
||||
{
|
||||
BuildDetails bi = new BuildDetails
|
||||
var bi = new BuildDetails
|
||||
{
|
||||
MajorVersion = nb.MajorVersion,
|
||||
MinorVersion = nb.MinorVersion,
|
||||
|
@ -97,7 +91,7 @@ namespace BuildFeed.Controllers
|
|||
return bi;
|
||||
});
|
||||
|
||||
IEnumerable<Build> builds = apiModel.NewBuilds.Select(nb => new Build
|
||||
var builds = apiModel.NewBuilds.Select(nb => new Build
|
||||
{
|
||||
MajorVersion = nb.MajorVersion,
|
||||
MinorVersion = nb.MinorVersion,
|
||||
|
@ -127,12 +121,14 @@ namespace BuildFeed.Controllers
|
|||
{
|
||||
await _bModel.Insert(build);
|
||||
|
||||
OneSignalClient osc = new OneSignalClient(ConfigurationManager.AppSettings["push:OneSignalApiKey"]);
|
||||
var osc = new OneSignalClient(ConfigurationManager.AppSettings["push:OneSignalApiKey"]);
|
||||
osc.PushNewBuild(build,
|
||||
$"https://buildfeed.net{Url.Route("Build", new { controller = "Front", action = nameof(FrontController.ViewBuild), id = build.Id, area = "", httproute = "" })}?utm_source=notification&utm_campaign=new_build");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -146,26 +142,26 @@ namespace BuildFeed.Controllers
|
|||
var results = new List<SearchResult>();
|
||||
|
||||
results.AddRange(from s in (from c in await _bModel.SelectAllSources()
|
||||
select new
|
||||
{
|
||||
Text = MvcExtensions.GetDisplayTextForEnum(c),
|
||||
Value = c
|
||||
})
|
||||
where s.Text.ToLower().Contains(id.ToLower())
|
||||
orderby s.Text.ToLower().IndexOf(id.ToLower(), StringComparison.Ordinal)
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Source Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewSource",
|
||||
source = s.Value
|
||||
}),
|
||||
Label = s.Text.Replace(id, "<strong>" + id + "</strong>"),
|
||||
Title = s.Text,
|
||||
Group = VariantTerms.Search_Source
|
||||
});
|
||||
select new
|
||||
{
|
||||
Text = MvcExtensions.GetDisplayTextForEnum(c),
|
||||
Value = c
|
||||
})
|
||||
where s.Text.ToLower().Contains(id.ToLower())
|
||||
orderby s.Text.ToLower().IndexOf(id.ToLower(), StringComparison.Ordinal)
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Source Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewSource",
|
||||
source = s.Value
|
||||
}),
|
||||
Label = s.Text.Replace(id, "<strong>" + id + "</strong>"),
|
||||
Title = s.Text,
|
||||
Group = VariantTerms.Search_Source
|
||||
});
|
||||
|
||||
if (results.Count >= maxResults)
|
||||
{
|
||||
|
@ -173,22 +169,22 @@ namespace BuildFeed.Controllers
|
|||
}
|
||||
|
||||
results.AddRange(from v in await _bModel.SelectAllVersions()
|
||||
where $"{v.Major}.{v.Minor}".StartsWith(id)
|
||||
orderby v.Major descending, v.Minor descending
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Version Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewVersion",
|
||||
major = v.Major,
|
||||
minor = v.Minor
|
||||
}),
|
||||
Label = $"{v.Major}.{v.Minor}".Replace(id, "<strong>" + id + "</strong>"),
|
||||
Title = "",
|
||||
Group = VariantTerms.Search_Version
|
||||
});
|
||||
where $"{v.Major}.{v.Minor}".StartsWith(id)
|
||||
orderby v.Major descending, v.Minor descending
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Version Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewVersion",
|
||||
major = v.Major,
|
||||
minor = v.Minor
|
||||
}),
|
||||
Label = $"{v.Major}.{v.Minor}".Replace(id, "<strong>" + id + "</strong>"),
|
||||
Title = "",
|
||||
Group = VariantTerms.Search_Version
|
||||
});
|
||||
|
||||
if (results.Count >= maxResults)
|
||||
{
|
||||
|
@ -196,21 +192,21 @@ namespace BuildFeed.Controllers
|
|||
}
|
||||
|
||||
results.AddRange(from y in await _bModel.SelectAllYears()
|
||||
where y.ToString().Contains(id)
|
||||
orderby y descending
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Year Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewYear",
|
||||
year = y
|
||||
}),
|
||||
Label = y.ToString().Replace(id, "<strong>" + id + "</strong>"),
|
||||
Title = "",
|
||||
Group = VariantTerms.Search_Year
|
||||
});
|
||||
where y.ToString().Contains(id)
|
||||
orderby y descending
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Year Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewYear",
|
||||
year = y
|
||||
}),
|
||||
Label = y.ToString().Replace(id, "<strong>" + id + "</strong>"),
|
||||
Title = "",
|
||||
Group = VariantTerms.Search_Year
|
||||
});
|
||||
|
||||
if (results.Count >= maxResults)
|
||||
{
|
||||
|
@ -218,19 +214,19 @@ namespace BuildFeed.Controllers
|
|||
}
|
||||
|
||||
results.AddRange(from l in await _bModel.SearchLabs(id)
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Lab Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewLab",
|
||||
lab = l.Replace('/', '-')
|
||||
}),
|
||||
Label = l.Replace(id, $"<strong>{id}</strong>"),
|
||||
Title = l,
|
||||
Group = VariantTerms.Search_Lab
|
||||
});
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Lab Root",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewLab",
|
||||
lab = l.Replace('/', '-')
|
||||
}),
|
||||
Label = l.Replace(id, $"<strong>{id}</strong>"),
|
||||
Title = l,
|
||||
Group = VariantTerms.Search_Lab
|
||||
});
|
||||
|
||||
if (results.Count >= maxResults)
|
||||
{
|
||||
|
@ -238,19 +234,19 @@ namespace BuildFeed.Controllers
|
|||
}
|
||||
|
||||
results.AddRange(from b in await _bModel.SelectBuildsByStringSearch(id, maxResults)
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Build",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewBuild",
|
||||
id = b.Id
|
||||
}),
|
||||
Label = b.FullBuildString.Replace(id, $"<strong>{id}</strong>"),
|
||||
Title = b.FullBuildString,
|
||||
Group = VariantTerms.Search_Build
|
||||
});
|
||||
select new SearchResult
|
||||
{
|
||||
Url = Url.Route("Build",
|
||||
new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewBuild",
|
||||
id = b.Id
|
||||
}),
|
||||
Label = b.FullBuildString.Replace(id, $"<strong>{id}</strong>"),
|
||||
Title = b.FullBuildString,
|
||||
Group = VariantTerms.Search_Build
|
||||
});
|
||||
|
||||
if (results.Count == 0)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> Index()
|
||||
{
|
||||
ViewBag.Versions = await _bModel.SelectAllFamilies();
|
||||
|
@ -50,7 +50,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> IndexPage(int page)
|
||||
{
|
||||
var buildGroups = await _bModel.SelectAllGroups(PAGE_SIZE, (page - 1) * PAGE_SIZE);
|
||||
|
@ -73,7 +73,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewGroup(uint major, uint minor, uint number, uint? revision = null)
|
||||
{
|
||||
var bg = new BuildGroup
|
||||
|
@ -99,7 +99,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewBuild(Guid id)
|
||||
{
|
||||
Build b = await _bModel.SelectById(id);
|
||||
|
@ -131,7 +131,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[CustomContentType(ContentType = "image/png", Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> TwitterCard(Guid id)
|
||||
{
|
||||
Build b = await _bModel.SelectById(id);
|
||||
|
@ -279,7 +279,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewFamily(ProjectFamily family)
|
||||
{
|
||||
return await ViewFamilyPage(family, 1);
|
||||
|
@ -289,7 +289,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewFamilyPage(ProjectFamily family, int page)
|
||||
{
|
||||
ViewBag.MetaItem = await _mModel.SelectById(new MetaItemKey
|
||||
|
@ -317,7 +317,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewLab(string lab)
|
||||
{
|
||||
return await ViewLabPage(lab, 1);
|
||||
|
@ -327,7 +327,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewLabPage(string lab, int page)
|
||||
{
|
||||
ViewBag.MetaItem = await _mModel.SelectById(new MetaItemKey
|
||||
|
@ -355,7 +355,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewSource(TypeOfSource source)
|
||||
{
|
||||
return await ViewSourcePage(source, 1);
|
||||
|
@ -365,7 +365,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewSourcePage(TypeOfSource source, int page)
|
||||
{
|
||||
ViewBag.MetaItem = await _mModel.SelectById(new MetaItemKey
|
||||
|
@ -393,7 +393,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewYear(int year)
|
||||
{
|
||||
return await ViewYearPage(year, 1);
|
||||
|
@ -403,7 +403,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewYearPage(int year, int page)
|
||||
{
|
||||
ViewBag.MetaItem = await _mModel.SelectById(new MetaItemKey
|
||||
|
@ -430,7 +430,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewVersion(uint major, uint minor)
|
||||
{
|
||||
return await ViewVersionPage(major, minor, 1);
|
||||
|
@ -440,7 +440,7 @@ namespace BuildFeed.Controllers
|
|||
#if !DEBUG
|
||||
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
[OutputCachePush(Order = 2)]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> ViewVersionPage(uint major, uint minor, int page)
|
||||
{
|
||||
string valueString = $"{major}.{minor}";
|
||||
|
|
|
@ -29,12 +29,12 @@ namespace BuildFeed.Controllers
|
|||
}
|
||||
|
||||
[Route("sitemap/")]
|
||||
#if !DEBUG
|
||||
#if !DEBUG
|
||||
[OutputCache(Duration = 3600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> Sitemap()
|
||||
{
|
||||
List<Build> builds = await _bModel.SelectBuildsByOrder();
|
||||
var builds = await _bModel.SelectBuildsByOrder();
|
||||
var actions = new Dictionary<string, SitemapPagedAction[]>
|
||||
{
|
||||
{
|
||||
|
@ -54,144 +54,146 @@ namespace BuildFeed.Controllers
|
|||
},
|
||||
{
|
||||
"Versions", (from b in builds
|
||||
group b by new BuildVersion
|
||||
{
|
||||
Major = b.MajorVersion,
|
||||
Minor = b.MinorVersion
|
||||
}
|
||||
into bv
|
||||
orderby bv.Key.Major descending, bv.Key.Minor descending
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = $"{InvariantTerms.ProductName} {bv.Key.Major}.{bv.Key.Minor}",
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewVersion",
|
||||
major = bv.Key.Major,
|
||||
minor = bv.Key.Minor,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
group b by new BuildVersion
|
||||
{
|
||||
Major = b.MajorVersion,
|
||||
Minor = b.MinorVersion
|
||||
}
|
||||
into bv
|
||||
orderby bv.Key.Major descending, bv.Key.Minor descending
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = $"{InvariantTerms.ProductName} {bv.Key.Major}.{bv.Key.Minor}",
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewVersion",
|
||||
major = bv.Key.Major,
|
||||
minor = bv.Key.Minor,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
},
|
||||
{
|
||||
"Labs", (from b in builds
|
||||
where !string.IsNullOrEmpty(b.Lab)
|
||||
group b by b.Lab
|
||||
into bv
|
||||
orderby bv.Key
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = bv.Key,
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewLab",
|
||||
lab = bv.Key,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
where !string.IsNullOrEmpty(b.Lab)
|
||||
group b by b.Lab
|
||||
into bv
|
||||
orderby bv.Key
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = bv.Key,
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewLab",
|
||||
lab = bv.Key,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
},
|
||||
{
|
||||
"Years", (from b in builds
|
||||
where b.BuildTime.HasValue
|
||||
group b by b.BuildTime.Value.Year
|
||||
into bv
|
||||
orderby bv.Key descending
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = bv.Key.ToString(),
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewYear",
|
||||
year = bv.Key,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
where b.BuildTime.HasValue
|
||||
group b by b.BuildTime.Value.Year
|
||||
into bv
|
||||
orderby bv.Key descending
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = bv.Key.ToString(),
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewYear",
|
||||
year = bv.Key,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
},
|
||||
{
|
||||
"Sources", (from b in builds
|
||||
group b by b.SourceType
|
||||
into bv
|
||||
orderby bv.Key
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = MvcExtensions.GetDisplayTextForEnum(bv.Key),
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewSource",
|
||||
source = bv.Key,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
group b by b.SourceType
|
||||
into bv
|
||||
orderby bv.Key
|
||||
select new SitemapPagedAction
|
||||
{
|
||||
Name = MvcExtensions.GetDisplayTextForEnum(bv.Key),
|
||||
UrlParams = new RouteValueDictionary(new
|
||||
{
|
||||
controller = "Front",
|
||||
action = "ViewSource",
|
||||
source = bv.Key,
|
||||
page = 1
|
||||
}),
|
||||
Pages = (bv.Count() + (FrontController.PAGE_SIZE - 1)) / FrontController.PAGE_SIZE
|
||||
}).ToArray()
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SitemapData model = new SitemapData
|
||||
var model = new SitemapData
|
||||
{
|
||||
Builds = (from b in builds
|
||||
group b by new
|
||||
{
|
||||
Major = b.MajorVersion,
|
||||
Minor = b.MinorVersion,
|
||||
Build = b.Number,
|
||||
b.Revision
|
||||
}
|
||||
into bg
|
||||
orderby bg.Key.Major descending, bg.Key.Minor descending, bg.Key.Build descending, bg.Key.Revision descending
|
||||
select new SitemapDataBuildGroup
|
||||
{
|
||||
Id = new BuildGroup
|
||||
{
|
||||
Major = bg.Key.Major,
|
||||
Minor = bg.Key.Minor,
|
||||
Build = bg.Key.Build,
|
||||
Revision = bg.Key.Revision
|
||||
},
|
||||
Builds = (from bgb in bg
|
||||
select new SitemapDataBuild
|
||||
{
|
||||
Id = bgb.Id,
|
||||
Name = bgb.FullBuildString
|
||||
}).ToArray()
|
||||
}).ToArray(),
|
||||
group b by new
|
||||
{
|
||||
Major = b.MajorVersion,
|
||||
Minor = b.MinorVersion,
|
||||
Build = b.Number,
|
||||
b.Revision
|
||||
}
|
||||
into bg
|
||||
orderby bg.Key.Major descending, bg.Key.Minor descending, bg.Key.Build descending, bg.Key.Revision
|
||||
descending
|
||||
select new SitemapDataBuildGroup
|
||||
{
|
||||
Id = new BuildGroup
|
||||
{
|
||||
Major = bg.Key.Major,
|
||||
Minor = bg.Key.Minor,
|
||||
Build = bg.Key.Build,
|
||||
Revision = bg.Key.Revision
|
||||
},
|
||||
Builds = (from bgb in bg
|
||||
select new SitemapDataBuild
|
||||
{
|
||||
Id = bgb.Id,
|
||||
Name = bgb.FullBuildString
|
||||
}).ToArray()
|
||||
}).ToArray(),
|
||||
Actions = actions,
|
||||
Labs = (from b in builds
|
||||
group b by b.Lab
|
||||
into lab
|
||||
select lab.Key).ToArray()
|
||||
group b by b.Lab
|
||||
into lab
|
||||
select lab.Key).ToArray()
|
||||
};
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[Route("xml-sitemap/")]
|
||||
#if !DEBUG
|
||||
#if !DEBUG
|
||||
[OutputCache(Duration = 3600, VaryByParam = "none", VaryByCustom = "userName;lang;theme")]
|
||||
#endif
|
||||
#endif
|
||||
public async Task<ActionResult> XmlSitemap()
|
||||
{
|
||||
XNamespace xn = XNamespace.Get("http://www.sitemaps.org/schemas/sitemap/0.9");
|
||||
var xlist = new List<XElement>();
|
||||
|
||||
// home page
|
||||
XElement home = new XElement(xn + "url");
|
||||
var home = new XElement(xn + "url");
|
||||
home.Add(new XElement(xn + "loc", Request.Url?.GetLeftPart(UriPartial.Authority) + "/"));
|
||||
home.Add(new XElement(xn + "changefreq", "daily"));
|
||||
xlist.Add(home);
|
||||
|
||||
foreach (Build b in await _bModel.Select())
|
||||
{
|
||||
XElement url = new XElement(xn + "url");
|
||||
var url = new XElement(xn + "url");
|
||||
url.Add(new XElement(xn + "loc",
|
||||
Request.Url?.GetLeftPart(UriPartial.Authority) + Url.Action("ViewBuild",
|
||||
Request.Url?.GetLeftPart(UriPartial.Authority)
|
||||
+ Url.Action("ViewBuild",
|
||||
"Front",
|
||||
new
|
||||
{
|
||||
|
@ -201,13 +203,14 @@ namespace BuildFeed.Controllers
|
|||
{
|
||||
url.Add(new XElement(xn + "lastmod", b.Modified.ToString("yyyy-MM-dd")));
|
||||
}
|
||||
|
||||
xlist.Add(url);
|
||||
}
|
||||
|
||||
XDeclaration decl = new XDeclaration("1.0", "utf-8", "");
|
||||
XElement root = new XElement(xn + "urlset", xlist);
|
||||
var decl = new XDeclaration("1.0", "utf-8", "");
|
||||
var root = new XElement(xn + "urlset", xlist);
|
||||
|
||||
XDocument xdoc = new XDocument(decl, root);
|
||||
var xdoc = new XDocument(decl, root);
|
||||
|
||||
Response.ContentType = "application/xml";
|
||||
xdoc.Save(Response.OutputStream);
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace BuildFeed
|
|||
AreaRegistration.RegisterAllAreas();
|
||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||
|
||||
DateTimeModelBinder db = new DateTimeModelBinder();
|
||||
var db = new DateTimeModelBinder();
|
||||
|
||||
ModelBinders.Binders.Add(typeof(DateTime), db);
|
||||
ModelBinders.Binders.Add(typeof(DateTime?), db);
|
||||
|
@ -42,9 +42,9 @@ namespace BuildFeed
|
|||
|
||||
public override string GetVaryByCustomString(HttpContext context, string custom)
|
||||
{
|
||||
string[] parts = custom.Split(';');
|
||||
var parts = custom.Split(';');
|
||||
var varyParts = new List<string>();
|
||||
HttpContextWrapper contextWrapper = new HttpContextWrapper(context);
|
||||
var contextWrapper = new HttpContextWrapper(context);
|
||||
|
||||
foreach (string part in parts)
|
||||
{
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -1,429 +0,0 @@
|
|||
/* NUGET: BEGIN LICENSE TEXT
|
||||
*
|
||||
* Microsoft grants you the right to use these script files for the sole
|
||||
* purpose of either: (i) interacting through your browser with the Microsoft
|
||||
* website or online service, subject to the applicable licensing or use
|
||||
* terms; or (ii) using the files as included with a Microsoft product subject
|
||||
* to that product's license terms. Microsoft reserves all other rights to the
|
||||
* files not expressly granted by Microsoft, whether by implication, estoppel
|
||||
* or otherwise. Insofar as a script file is dual licensed under GPL,
|
||||
* Microsoft neither took the code under GPL nor distributes it thereunder but
|
||||
* under the terms set out in this paragraph. All notices and licenses
|
||||
* below are for informational purposes only.
|
||||
*
|
||||
* NUGET: END LICENSE TEXT */
|
||||
/*!
|
||||
** Unobtrusive validation support library for jQuery and jQuery Validate
|
||||
** Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
|
||||
/*global document: false, jQuery: false */
|
||||
|
||||
(function ($) {
|
||||
var $jQval = $.validator,
|
||||
adapters,
|
||||
data_validation = "unobtrusiveValidation";
|
||||
|
||||
function setValidationValues(options, ruleName, value) {
|
||||
options.rules[ruleName] = value;
|
||||
if (options.message) {
|
||||
options.messages[ruleName] = options.message;
|
||||
}
|
||||
}
|
||||
|
||||
function splitAndTrim(value) {
|
||||
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
|
||||
}
|
||||
|
||||
function escapeAttributeValue(value) {
|
||||
// As mentioned on http://api.jquery.com/category/selectors/
|
||||
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
|
||||
}
|
||||
|
||||
function getModelPrefix(fieldName) {
|
||||
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
function appendModelPrefix(value, prefix) {
|
||||
if (value.indexOf("*.") === 0) {
|
||||
value = value.replace("*.", prefix);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function onError(error, inputElement) { // 'this' is the form element
|
||||
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
|
||||
replaceAttrValue = container.attr("data-valmsg-replace"),
|
||||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
|
||||
|
||||
container.removeClass("field-validation-valid").addClass("field-validation-error");
|
||||
error.data("unobtrusiveContainer", container);
|
||||
|
||||
if (replace) {
|
||||
container.empty();
|
||||
error.removeClass("input-validation-error").appendTo(container);
|
||||
}
|
||||
else {
|
||||
error.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function onErrors(event, validator) { // 'this' is the form element
|
||||
var container = $(this).find("[data-valmsg-summary=true]"),
|
||||
list = container.find("ul");
|
||||
|
||||
if (list && list.length && validator.errorList.length) {
|
||||
list.empty();
|
||||
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
|
||||
|
||||
$.each(validator.errorList, function () {
|
||||
$("<li />").html(this.message).appendTo(list);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onSuccess(error) { // 'this' is the form element
|
||||
var container = error.data("unobtrusiveContainer"),
|
||||
replaceAttrValue = container.attr("data-valmsg-replace"),
|
||||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
|
||||
|
||||
if (container) {
|
||||
container.addClass("field-validation-valid").removeClass("field-validation-error");
|
||||
error.removeData("unobtrusiveContainer");
|
||||
|
||||
if (replace) {
|
||||
container.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onReset(event) { // 'this' is the form element
|
||||
var $form = $(this),
|
||||
key = '__jquery_unobtrusive_validation_form_reset';
|
||||
if ($form.data(key)) {
|
||||
return;
|
||||
}
|
||||
// Set a flag that indicates we're currently resetting the form.
|
||||
$form.data(key, true);
|
||||
try {
|
||||
$form.data("validator").resetForm();
|
||||
} finally {
|
||||
$form.removeData(key);
|
||||
}
|
||||
|
||||
$form.find(".validation-summary-errors")
|
||||
.addClass("validation-summary-valid")
|
||||
.removeClass("validation-summary-errors");
|
||||
$form.find(".field-validation-error")
|
||||
.addClass("field-validation-valid")
|
||||
.removeClass("field-validation-error")
|
||||
.removeData("unobtrusiveContainer")
|
||||
.find(">*") // If we were using valmsg-replace, get the underlying error
|
||||
.removeData("unobtrusiveContainer");
|
||||
}
|
||||
|
||||
function validationInfo(form) {
|
||||
var $form = $(form),
|
||||
result = $form.data(data_validation),
|
||||
onResetProxy = $.proxy(onReset, form),
|
||||
defaultOptions = $jQval.unobtrusive.options || {},
|
||||
execInContext = function (name, args) {
|
||||
var func = defaultOptions[name];
|
||||
func && $.isFunction(func) && func.apply(form, args);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = {
|
||||
options: { // options structure passed to jQuery Validate's validate() method
|
||||
errorClass: defaultOptions.errorClass || "input-validation-error",
|
||||
errorElement: defaultOptions.errorElement || "span",
|
||||
errorPlacement: function () {
|
||||
onError.apply(form, arguments);
|
||||
execInContext("errorPlacement", arguments);
|
||||
},
|
||||
invalidHandler: function () {
|
||||
onErrors.apply(form, arguments);
|
||||
execInContext("invalidHandler", arguments);
|
||||
},
|
||||
messages: {},
|
||||
rules: {},
|
||||
success: function () {
|
||||
onSuccess.apply(form, arguments);
|
||||
execInContext("success", arguments);
|
||||
}
|
||||
},
|
||||
attachValidation: function () {
|
||||
$form
|
||||
.off("reset." + data_validation, onResetProxy)
|
||||
.on("reset." + data_validation, onResetProxy)
|
||||
.validate(this.options);
|
||||
},
|
||||
validate: function () { // a validation function that is called by unobtrusive Ajax
|
||||
$form.validate();
|
||||
return $form.valid();
|
||||
}
|
||||
};
|
||||
$form.data(data_validation, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
$jQval.unobtrusive = {
|
||||
adapters: [],
|
||||
|
||||
parseElement: function (element, skipAttach) {
|
||||
/// <summary>
|
||||
/// Parses a single HTML element for unobtrusive validation attributes.
|
||||
/// </summary>
|
||||
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
|
||||
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
|
||||
/// validation to the form. If parsing just this single element, you should specify true.
|
||||
/// If parsing several elements, you should specify false, and manually attach the validation
|
||||
/// to the form when you are finished. The default is false.</param>
|
||||
var $element = $(element),
|
||||
form = $element.parents("form")[0],
|
||||
valInfo, rules, messages;
|
||||
|
||||
if (!form) { // Cannot do client-side validation without a form
|
||||
return;
|
||||
}
|
||||
|
||||
valInfo = validationInfo(form);
|
||||
valInfo.options.rules[element.name] = rules = {};
|
||||
valInfo.options.messages[element.name] = messages = {};
|
||||
|
||||
$.each(this.adapters, function () {
|
||||
var prefix = "data-val-" + this.name,
|
||||
message = $element.attr(prefix),
|
||||
paramValues = {};
|
||||
|
||||
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
|
||||
prefix += "-";
|
||||
|
||||
$.each(this.params, function () {
|
||||
paramValues[this] = $element.attr(prefix + this);
|
||||
});
|
||||
|
||||
this.adapt({
|
||||
element: element,
|
||||
form: form,
|
||||
message: message,
|
||||
params: paramValues,
|
||||
rules: rules,
|
||||
messages: messages
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(rules, { "__dummy__": true });
|
||||
|
||||
if (!skipAttach) {
|
||||
valInfo.attachValidation();
|
||||
}
|
||||
},
|
||||
|
||||
parse: function (selector) {
|
||||
/// <summary>
|
||||
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
|
||||
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
|
||||
/// attribute values.
|
||||
/// </summary>
|
||||
/// <param name="selector" type="String">Any valid jQuery selector.</param>
|
||||
|
||||
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
|
||||
// element with data-val=true
|
||||
var $selector = $(selector),
|
||||
$forms = $selector.parents()
|
||||
.addBack()
|
||||
.filter("form")
|
||||
.add($selector.find("form"))
|
||||
.has("[data-val=true]");
|
||||
|
||||
$selector.find("[data-val=true]").each(function () {
|
||||
$jQval.unobtrusive.parseElement(this, true);
|
||||
});
|
||||
|
||||
$forms.each(function () {
|
||||
var info = validationInfo(this);
|
||||
if (info) {
|
||||
info.attachValidation();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
adapters = $jQval.unobtrusive.adapters;
|
||||
|
||||
adapters.add = function (adapterName, params, fn) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
||||
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
|
||||
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
|
||||
/// mmmm is the parameter name).</param>
|
||||
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
|
||||
/// attributes into jQuery Validate rules and/or messages.</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
if (!fn) { // Called with no params, just a function
|
||||
fn = params;
|
||||
params = [];
|
||||
}
|
||||
this.push({ name: adapterName, params: params, adapt: fn });
|
||||
return this;
|
||||
};
|
||||
|
||||
adapters.addBool = function (adapterName, ruleName) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
||||
/// the jQuery Validate validation rule has no parameter values.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
||||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
||||
/// of adapterName will be used instead.</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
return this.add(adapterName, function (options) {
|
||||
setValidationValues(options, ruleName || adapterName, true);
|
||||
});
|
||||
};
|
||||
|
||||
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
||||
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
|
||||
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
||||
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
||||
/// have a minimum value.</param>
|
||||
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
||||
/// have a maximum value.</param>
|
||||
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
|
||||
/// have both a minimum and maximum value.</param>
|
||||
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
||||
/// contains the minimum value. The default is "min".</param>
|
||||
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
||||
/// contains the maximum value. The default is "max".</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
|
||||
var min = options.params.min,
|
||||
max = options.params.max;
|
||||
|
||||
if (min && max) {
|
||||
setValidationValues(options, minMaxRuleName, [min, max]);
|
||||
}
|
||||
else if (min) {
|
||||
setValidationValues(options, minRuleName, min);
|
||||
}
|
||||
else if (max) {
|
||||
setValidationValues(options, maxRuleName, max);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
||||
/// the jQuery Validate validation rule has a single value.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
|
||||
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
|
||||
/// The default is "val".</param>
|
||||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
||||
/// of adapterName will be used instead.</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
return this.add(adapterName, [attribute || "val"], function (options) {
|
||||
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
|
||||
});
|
||||
};
|
||||
|
||||
$jQval.addMethod("__dummy__", function (value, element, params) {
|
||||
return true;
|
||||
});
|
||||
|
||||
$jQval.addMethod("regex", function (value, element, params) {
|
||||
var match;
|
||||
if (this.optional(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
match = new RegExp(params).exec(value);
|
||||
return (match && (match.index === 0) && (match[0].length === value.length));
|
||||
});
|
||||
|
||||
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
|
||||
var match;
|
||||
if (nonalphamin) {
|
||||
match = value.match(/\W/g);
|
||||
match = match && match.length >= nonalphamin;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
if ($jQval.methods.extension) {
|
||||
adapters.addSingleVal("accept", "mimtype");
|
||||
adapters.addSingleVal("extension", "extension");
|
||||
} else {
|
||||
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
|
||||
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
|
||||
// validating the extension, and ignore mime-type validations as they are not supported.
|
||||
adapters.addSingleVal("extension", "extension", "accept");
|
||||
}
|
||||
|
||||
adapters.addSingleVal("regex", "pattern");
|
||||
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
|
||||
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
|
||||
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
|
||||
adapters.add("equalto", ["other"], function (options) {
|
||||
var prefix = getModelPrefix(options.element.name),
|
||||
other = options.params.other,
|
||||
fullOtherName = appendModelPrefix(other, prefix),
|
||||
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
|
||||
|
||||
setValidationValues(options, "equalTo", element);
|
||||
});
|
||||
adapters.add("required", function (options) {
|
||||
// jQuery Validate equates "required" with "mandatory" for checkbox elements
|
||||
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
|
||||
setValidationValues(options, "required", true);
|
||||
}
|
||||
});
|
||||
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
|
||||
var value = {
|
||||
url: options.params.url,
|
||||
type: options.params.type || "GET",
|
||||
data: {}
|
||||
},
|
||||
prefix = getModelPrefix(options.element.name);
|
||||
|
||||
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
|
||||
var paramName = appendModelPrefix(fieldName, prefix);
|
||||
value.data[paramName] = function () {
|
||||
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
|
||||
// For checkboxes and radio buttons, only pick up values from checked fields.
|
||||
if (field.is(":checkbox")) {
|
||||
return field.filter(":checked").val() || field.filter(":hidden").val() || '';
|
||||
}
|
||||
else if (field.is(":radio")) {
|
||||
return field.filter(":checked").val() || '';
|
||||
}
|
||||
return field.val();
|
||||
};
|
||||
});
|
||||
|
||||
setValidationValues(options, "remote", value);
|
||||
});
|
||||
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
|
||||
if (options.params.min) {
|
||||
setValidationValues(options, "minlength", options.params.min);
|
||||
}
|
||||
if (options.params.nonalphamin) {
|
||||
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
|
||||
}
|
||||
if (options.params.regex) {
|
||||
setValidationValues(options, "regex", options.params.regex);
|
||||
}
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$jQval.unobtrusive.parse(document);
|
||||
});
|
||||
}(jQuery));
|
File diff suppressed because one or more lines are too long
|
@ -1,32 +1,32 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="BuildFeed" />
|
||||
<add namespace="BuildFeed.Local" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler" />
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="BuildFeed" />
|
||||
<add namespace="BuildFeed.Local" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler" />
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -1,68 +1,69 @@
|
|||
@using BuildFeed.Controllers
|
||||
@model BuildFeed.Model.View.LoginUser
|
||||
@using BuildFeed.Model.View
|
||||
@model LoginUser
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Support_Login} | {InvariantTerms.SiteName}";
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
ViewBag.Title = $"{VariantTerms.Support_Login} | {InvariantTerms.SiteName}";
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Support_Login</h1>
|
||||
|
||||
@using (Html.BeginForm())
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
if (ViewData["ErrorMessage"] != null)
|
||||
{
|
||||
<p class="text-danger">
|
||||
@ViewData["ErrorMessage"]
|
||||
</p>
|
||||
}
|
||||
if (ViewData["ErrorMessage"] != null)
|
||||
{
|
||||
<p class="text-danger">
|
||||
@ViewData["ErrorMessage"]
|
||||
</p>
|
||||
}
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.UserName)
|
||||
<div>
|
||||
@Html.TextBoxFor(model => model.UserName)
|
||||
@Html.ValidationMessageFor(model => model.UserName)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.UserName)
|
||||
<div>
|
||||
@Html.TextBoxFor(model => model.UserName)
|
||||
@Html.ValidationMessageFor(model => model.UserName)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.Password)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.Password)
|
||||
@Html.ValidationMessageFor(model => model.Password)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.Password)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.Password)
|
||||
@Html.ValidationMessageFor(model => model.Password)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<label for="@Html.IdFor(model => model.RememberMe)">
|
||||
@Html.CheckBoxFor(model => model.RememberMe) @Html.DisplayNameFor(model => model.RememberMe)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<label for="@Html.IdFor(model => model.RememberMe)">
|
||||
@Html.CheckBoxFor(model => model.RememberMe) @Html.DisplayNameFor(model => model.RememberMe)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Support_Login" />  
|
||||
@Html.ActionLink(VariantTerms.Support_Register, nameof(AccountController.Register), new
|
||||
{
|
||||
controller = "Account"
|
||||
}, new
|
||||
{
|
||||
@class = "button"
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Support_Login" />  
|
||||
@Html.ActionLink(VariantTerms.Support_Register, nameof(AccountController.Register), new
|
||||
{
|
||||
controller = "Account"
|
||||
}, new
|
||||
{
|
||||
@class = "button"
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/jquery.validate.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js" integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js" integrity="sha256-g1QKGxqsp+x5JkuN/JjHl96je2wztgS5Wo4h4c7gm9M=" crossorigin="anonymous"></script>
|
||||
}
|
|
@ -1,59 +1,60 @@
|
|||
@model BuildFeed.Model.View.ChangePassword
|
||||
@using BuildFeed.Model.View
|
||||
@model ChangePassword
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Support_ChangePassword} | {InvariantTerms.SiteName}";
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
ViewBag.Title = $"{VariantTerms.Support_ChangePassword} | {InvariantTerms.SiteName}";
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Support_ChangePassword</h1>
|
||||
|
||||
@using (Html.BeginForm())
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
if (ViewData["ErrorMessage"] != null)
|
||||
{
|
||||
<p class="text-danger">
|
||||
@ViewData["ErrorMessage"]
|
||||
</p>
|
||||
}
|
||||
if (ViewData["ErrorMessage"] != null)
|
||||
{
|
||||
<p class="text-danger">
|
||||
@ViewData["ErrorMessage"]
|
||||
</p>
|
||||
}
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.OldPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.OldPassword)
|
||||
@Html.ValidationMessageFor(model => model.OldPassword)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.OldPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.OldPassword)
|
||||
@Html.ValidationMessageFor(model => model.OldPassword)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.NewPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.NewPassword)
|
||||
@Html.ValidationMessageFor(model => model.NewPassword)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.NewPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.NewPassword)
|
||||
@Html.ValidationMessageFor(model => model.NewPassword)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.ConfirmNewPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.ConfirmNewPassword)
|
||||
@Html.ValidationMessageFor(model => model.ConfirmNewPassword)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.ConfirmNewPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.ConfirmNewPassword)
|
||||
@Html.ValidationMessageFor(model => model.ConfirmNewPassword)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Support_ChangePassword" class="btn btn-primary" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Support_ChangePassword" class="btn btn-primary" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/jquery.validate.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js" integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js" integrity="sha256-g1QKGxqsp+x5JkuN/JjHl96je2wztgS5Wo4h4c7gm9M=" crossorigin="anonymous"></script>
|
||||
}
|
|
@ -1,67 +1,68 @@
|
|||
@model BuildFeed.Model.View.RegistrationUser
|
||||
@using BuildFeed.Model.View
|
||||
@model RegistrationUser
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Support_Register} | {InvariantTerms.SiteName}";
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
ViewBag.Title = $"{VariantTerms.Support_Register} | {InvariantTerms.SiteName}";
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Support_Register</h1>
|
||||
|
||||
@using (Html.BeginForm())
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
if (ViewData["ErrorMessage"] != null)
|
||||
{
|
||||
<p class="text-danger">
|
||||
@ViewData["ErrorMessage"]
|
||||
</p>
|
||||
}
|
||||
if (ViewData["ErrorMessage"] != null)
|
||||
{
|
||||
<p class="text-danger">
|
||||
@ViewData["ErrorMessage"]
|
||||
</p>
|
||||
}
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.UserName)
|
||||
<div>
|
||||
@Html.TextBoxFor(model => model.UserName)
|
||||
@Html.ValidationMessageFor(model => model.UserName)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.UserName)
|
||||
<div>
|
||||
@Html.TextBoxFor(model => model.UserName)
|
||||
@Html.ValidationMessageFor(model => model.UserName)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.Password)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.Password)
|
||||
@Html.ValidationMessageFor(model => model.Password)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.Password)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.Password)
|
||||
@Html.ValidationMessageFor(model => model.Password)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.ConfirmPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.ConfirmPassword)
|
||||
@Html.ValidationMessageFor(model => model.ConfirmPassword)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.ConfirmPassword)
|
||||
<div>
|
||||
@Html.PasswordFor(model => model.ConfirmPassword)
|
||||
@Html.ValidationMessageFor(model => model.ConfirmPassword)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.EmailAddress)
|
||||
<div class="col-md-10">
|
||||
@Html.TextBoxFor(model => model.EmailAddress)
|
||||
@Html.ValidationMessageFor(model => model.EmailAddress)
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.EmailAddress)
|
||||
<div class="col-md-10">
|
||||
@Html.TextBoxFor(model => model.EmailAddress)
|
||||
@Html.ValidationMessageFor(model => model.EmailAddress)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Support_Register" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Support_Register" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/jquery.validate.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js" integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js" integrity="sha256-g1QKGxqsp+x5JkuN/JjHl96je2wztgS5Wo4h4c7gm9M=" crossorigin="anonymous"></script>
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Support_EmailValidationTitle} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Support_EmailValidationTitle} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Support_EmailValidationTitle</h1>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Support_ValidationFailureTitle} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Support_ValidationFailureTitle} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Support_ValidationFailureTitle</h1>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Support_ValidationSuccessTitle} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Support_ValidationSuccessTitle} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Support_ValidationSuccessTitle</h1>
|
||||
|
|
|
@ -1,66 +1,67 @@
|
|||
@using BuildFeed.Controllers
|
||||
@using BuildFeed.Model
|
||||
@model BuildFeed.Model.View.BulkAddition
|
||||
@using BuildFeed.Model.View
|
||||
@model BulkAddition
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Common_AddBulk} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Common_AddBulk} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Common_AddBulk</h1>
|
||||
|
||||
@if (ViewBag.Results != null)
|
||||
{
|
||||
<p>@VariantTerms.Bulk_Success</p>
|
||||
<ul>
|
||||
@foreach (Build b in ViewBag.Results)
|
||||
{
|
||||
<li>
|
||||
<a href="@Url.Action(nameof(FrontController.ViewBuild), new
|
||||
{
|
||||
id = b.Id
|
||||
})" target="_blank">
|
||||
@b.AlternateBuildString</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<p>@VariantTerms.Bulk_Success</p>
|
||||
<ul>
|
||||
@foreach (Build b in ViewBag.Results)
|
||||
{
|
||||
<li>
|
||||
<a href="@Url.Action(nameof(FrontController.ViewBuild), new
|
||||
{
|
||||
id = b.Id
|
||||
})" target="_blank">
|
||||
@b.AlternateBuildString</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
||||
|
||||
@using (Html.BeginForm())
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
@VariantTerms.Bulk_Instructions
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
@VariantTerms.Bulk_Instructions
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="@Html.IdFor(m => m.Builds)">@VariantTerms.Bulk_Builds</label>
|
||||
<div>
|
||||
@Html.TextAreaFor(m => m.Builds, new
|
||||
{
|
||||
rows = 10
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="@Html.IdFor(m => m.Builds)">@VariantTerms.Bulk_Builds</label>
|
||||
<div>
|
||||
@Html.TextAreaFor(m => m.Builds, new
|
||||
{
|
||||
rows = 10
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<label for="@Html.IdFor(m => m.SendNotifications)">
|
||||
@Html.CheckBoxFor(m => m.SendNotifications)
|
||||
@VariantTerms.Bulk_SendNotifications
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<label for="@Html.IdFor(m => m.SendNotifications)">
|
||||
@Html.CheckBoxFor(m => m.SendNotifications)
|
||||
@VariantTerms.Bulk_SendNotifications
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Bulk_AddBuilds" class="button" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="label-placeholder"></span>
|
||||
<div>
|
||||
<input type="submit" value="@VariantTerms.Bulk_AddBuilds" class="button" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -4,57 +4,58 @@
|
|||
@using Humanizer
|
||||
@model IEnumerable<FrontBuildGroup>
|
||||
@{
|
||||
ViewBag.Title = $"{string.Format(VariantTerms.Front_HomepageH1, InvariantTerms.ProductName)} {string.Format(VariantTerms.Common_TitlePage, (int)ViewBag.PageNumber)} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{string.Format(VariantTerms.Front_HomepageH1, InvariantTerms.ProductName)} {string.Format(VariantTerms.Common_TitlePage, (int)ViewBag.PageNumber)} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
|
||||
<h1>@string.Format(VariantTerms.Front_HomepageH1, InvariantTerms.ProductName)</h1>
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (FrontBuildGroup group in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title">
|
||||
<a href="@Url.Action(nameof(FrontController.ViewGroup), new
|
||||
{
|
||||
major = group.Key.Major,
|
||||
minor = group.Key.Minor,
|
||||
number = group.Key.Build,
|
||||
revision = group.Key.Revision
|
||||
})">
|
||||
@group.Key.ToString()
|
||||
</a>
|
||||
</h3>
|
||||
@if (group.LastBuild.HasValue)
|
||||
{
|
||||
@foreach (FrontBuildGroup group in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title">
|
||||
<a href="@Url.Action(nameof(FrontController.ViewGroup), new
|
||||
{
|
||||
major = group.Key.Major,
|
||||
minor = group.Key.Minor,
|
||||
number = group.Key.Build,
|
||||
revision = group.Key.Revision
|
||||
})">
|
||||
@group.Key.ToString()
|
||||
</a>
|
||||
</h3>
|
||||
@if (group.LastBuild.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
@{
|
||||
DateTime maxDate = group.LastBuild.Value;
|
||||
if (maxDate.AddDays(28) > DateTime.Now)
|
||||
{
|
||||
<span title="@maxDate.ToLongDateWithoutDay()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @maxDate.Humanize()</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span title="@maxDate.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @maxDate.ToLongDateWithoutDay()</span>
|
||||
}
|
||||
}
|
||||
</p>
|
||||
}
|
||||
<p class="build-group-p">
|
||||
@{
|
||||
DateTime maxDate = group.LastBuild.Value;
|
||||
if (maxDate.AddDays(28) > DateTime.Now)
|
||||
{
|
||||
<span title="@maxDate.ToLongDateWithoutDay()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @maxDate.Humanize()</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span title="@maxDate.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @maxDate.ToLongDateWithoutDay()</span>
|
||||
}
|
||||
}
|
||||
<i class="fa fa-server fa-fw"></i> @string.Format(VariantTerms.Front_NumOfBuilds, group.BuildCount)
|
||||
</p>
|
||||
}
|
||||
<p class="build-group-p">
|
||||
<i class="fa fa-server fa-fw"></i> @string.Format(VariantTerms.Front_NumOfBuilds, group.BuildCount)
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
@PaginationHelpers.PaginationBlock((int)ViewBag.PageNumber, (int)ViewBag.PageCount, nameof(FrontController.Index), ViewContext.RouteData.Values)
|
|
@ -4,104 +4,104 @@
|
|||
@using Humanizer
|
||||
@model IEnumerable<Build>
|
||||
@{
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", ViewBag.ItemId, ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", ViewBag.ItemId, ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
}
|
||||
|
||||
<h1>@ViewBag.ItemId</h1>
|
||||
@if (ViewBag.MetaItem != null && !string.IsNullOrWhiteSpace(ViewBag.MetaItem.PageContent))
|
||||
{
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
}
|
||||
<h3>@VariantTerms.Front_Share</h3>
|
||||
<div class="addthis_sharing_toolbox"></div>
|
||||
<br />
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="no-wrapping build-group-p" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="no-wrapping build-group-p" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
@PaginationHelpers.PaginationBlock((int)ViewBag.PageNumber, (int)ViewBag.PageCount, "ViewFamily", ViewContext.RouteData.Values)
|
|
@ -126,7 +126,7 @@ else
|
|||
|
||||
@section Scripts
|
||||
{
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="~/Scripts/trumbowyg/trumbowyg.min.js" type="text/javascript"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js" integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=" crossorigin="anonymous"></script>
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
}
|
||||
}
|
||||
</select>
|
||||
<button onclick="window.location = document.getElementById('search-version').value; return false;">
|
||||
<button onclick="window.location = document.getElementById('search-version').value;return false;">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,143 +1,144 @@
|
|||
@using System.Globalization
|
||||
@using BuildFeed.Code
|
||||
@using BuildFeed.Controllers
|
||||
@model BuildFeed.Model.Build
|
||||
@using BuildFeed.Model
|
||||
@model Build
|
||||
|
||||
@{
|
||||
ViewBag.Title = $"{Model.FullBuildString} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{Model.FullBuildString} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
<meta property="og:title" content="@Model.FullBuildString" />
|
||||
<meta property="og:image" content="@Request.Url.GetLeftPart(UriPartial.Authority)@Url.Action("twitterCard", new
|
||||
{
|
||||
id = Model.Id
|
||||
})">
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="@Model.FullBuildString | @InvariantTerms.SiteName">
|
||||
<meta name="twitter:image" content="@Request.Url.GetLeftPart(UriPartial.Authority)@Url.Action("twitterCard", new
|
||||
<meta property="og:title" content="@Model.FullBuildString" />
|
||||
<meta property="og:image" content="@Request.Url.GetLeftPart(UriPartial.Authority)@Url.Action("twitterCard", new
|
||||
{
|
||||
id = Model.Id
|
||||
id = Model.Id
|
||||
})">
|
||||
@{
|
||||
string metaDesc = Model.BuildTime.HasValue
|
||||
? string.Format(VariantTerms.Meta_BuildDate, Model.Number, Model.Lab, Model.BuildTime.Value.ToLongDateWithoutDay())
|
||||
: string.Format(VariantTerms.Meta_BuildNoDate, Model.Number, Model.Lab);
|
||||
}
|
||||
<meta name="description" content="@metaDesc" />
|
||||
<meta property="og:description" content="@metaDesc" />
|
||||
<meta name="twitter:description" content="@metaDesc" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="@Model.FullBuildString | @InvariantTerms.SiteName">
|
||||
<meta name="twitter:image" content="@Request.Url.GetLeftPart(UriPartial.Authority)@Url.Action("twitterCard", new
|
||||
{
|
||||
id = Model.Id
|
||||
})">
|
||||
@{
|
||||
string metaDesc = Model.BuildTime.HasValue
|
||||
? string.Format(VariantTerms.Meta_BuildDate, Model.Number, Model.Lab, Model.BuildTime.Value.ToLongDateWithoutDay())
|
||||
: string.Format(VariantTerms.Meta_BuildNoDate, Model.Number, Model.Lab);
|
||||
}
|
||||
<meta name="description" content="@metaDesc" />
|
||||
<meta property="og:description" content="@metaDesc" />
|
||||
<meta name="twitter:description" content="@metaDesc" />
|
||||
}
|
||||
|
||||
<h1 dir="ltr" class="eager-wrapping">@Model.AlternateBuildString</h1>
|
||||
|
||||
<h3>@VariantTerms.Front_Details</h3>
|
||||
<div class="build-details-flex">
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.MajorVersion)
|
||||
<p class="build-details-flex-value">@Html.DisplayFor(model => model.MajorVersion)</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.MinorVersion)
|
||||
<p class="build-details-flex-value">@Html.DisplayFor(model => model.MinorVersion)</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Number)
|
||||
<p class="build-details-flex-value">@Html.DisplayFor(model => model.Number)</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Revision)
|
||||
<p class="build-details-flex-value">
|
||||
@if (Model.Revision.HasValue)
|
||||
{
|
||||
@Html.DisplayFor(model => model.Revision)
|
||||
}
|
||||
else
|
||||
{
|
||||
@("-")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.MajorVersion)
|
||||
<p class="build-details-flex-value">@Html.DisplayFor(model => model.MajorVersion)</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.MinorVersion)
|
||||
<p class="build-details-flex-value">@Html.DisplayFor(model => model.MinorVersion)</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Number)
|
||||
<p class="build-details-flex-value">@Html.DisplayFor(model => model.Number)</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Revision)
|
||||
<p class="build-details-flex-value">
|
||||
@if (Model.Revision.HasValue)
|
||||
{
|
||||
@Html.DisplayFor(model => model.Revision)
|
||||
}
|
||||
else
|
||||
{
|
||||
@("-")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex">
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Family)
|
||||
<div class="build-details-flex-value">
|
||||
@Html.DisplayFor(model => model.Family, "Enumeration")
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Lab)
|
||||
<p class="build-details-flex-value">
|
||||
@if (string.IsNullOrEmpty(Model.Lab))
|
||||
{
|
||||
<em>@VariantTerms.Front_NoLabString</em>
|
||||
}
|
||||
else
|
||||
{
|
||||
@Model.Lab<br />
|
||||
<a href="@Url.Action(nameof(FrontController.ViewLab), new
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Family)
|
||||
<div class="build-details-flex-value">
|
||||
@Html.DisplayFor(model => model.Family, "Enumeration")
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.Lab)
|
||||
<p class="build-details-flex-value">
|
||||
@if (string.IsNullOrEmpty(Model.Lab))
|
||||
{
|
||||
<em>@VariantTerms.Front_NoLabString</em>
|
||||
}
|
||||
else
|
||||
{
|
||||
@Model.Lab<br />
|
||||
<a href="@Url.Action(nameof(FrontController.ViewLab), new
|
||||
{
|
||||
lab = Model.LabUrl
|
||||
})" class="more-link">
|
||||
<i class="fa fa-plus-circle fa-sm"></i>
|
||||
@string.Format(VariantTerms.Front_MoreFromLab, Model.Lab)
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex">
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.BuildTime)
|
||||
<p class="build-details-flex-value">
|
||||
@if (Model.BuildTime.HasValue)
|
||||
{
|
||||
<time datetime="@Model.BuildTime.Value.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture.DateTimeFormat)" title="@Model.BuildTime.Value.ToString("h:mm tt on dddd, d MMMM yyyy")">@Model.BuildTime.Value.ToString("yyMMdd-HHmm", CultureInfo.InvariantCulture.DateTimeFormat)</time>
|
||||
<br />
|
||||
<a href="@Url.Action(nameof(FrontController.ViewYear), new
|
||||
{
|
||||
year = Model.BuildTime.Value.Year
|
||||
})" class="more-link">
|
||||
<i class="fa fa-plus-circle fa-sm"></i>
|
||||
@string.Format(VariantTerms.Front_MoreFromYear, Model.BuildTime.Value.Year)
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@if (Model.LeakDate.HasValue)
|
||||
{
|
||||
@Html.LabelFor(model => model.LeakDate)
|
||||
<div class="build-details-flex-value">
|
||||
<time datetime="@Model.LeakDate.Value.ToString("yyyy-MM-dd")" title="@Model.LeakDate.Value.ToLongDateString()">@Model.LeakDate.Value.ToShortDateString()</time>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex">
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.SourceType)
|
||||
<div class="build-details-flex-value">
|
||||
@Html.DisplayFor(model => model.SourceType, "Enumeration")<br />
|
||||
<a href="@Url.Action("ViewSource", new
|
||||
{
|
||||
lab = Model.LabUrl
|
||||
source = Model.SourceType
|
||||
})" class="more-link">
|
||||
<i class="fa fa-plus-circle fa-sm"></i>
|
||||
@string.Format(VariantTerms.Front_MoreFromLab, Model.Lab)
|
||||
<i class="fa fa-plus-circle fa-sm"></i>
|
||||
@string.Format(VariantTerms.Front_MoreFromSource, MvcExtensions.GetDisplayTextForEnum(Model.SourceType))
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex">
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.BuildTime)
|
||||
<p class="build-details-flex-value">
|
||||
@if (Model.BuildTime.HasValue)
|
||||
{
|
||||
<time datetime="@Model.BuildTime.Value.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture.DateTimeFormat)" title="@Model.BuildTime.Value.ToString("h:mm tt on dddd, d MMMM yyyy")">@Model.BuildTime.Value.ToString("yyMMdd-HHmm", CultureInfo.InvariantCulture.DateTimeFormat)</time>
|
||||
<br />
|
||||
<a href="@Url.Action(nameof(FrontController.ViewYear), new
|
||||
{
|
||||
year = Model.BuildTime.Value.Year
|
||||
})" class="more-link">
|
||||
<i class="fa fa-plus-circle fa-sm"></i>
|
||||
@string.Format(VariantTerms.Front_MoreFromYear, Model.BuildTime.Value.Year)
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="build-details-flex-item">
|
||||
@if (Model.LeakDate.HasValue)
|
||||
{
|
||||
@Html.LabelFor(model => model.LeakDate)
|
||||
<div class="build-details-flex-value">
|
||||
<time datetime="@Model.LeakDate.Value.ToString("yyyy-MM-dd")" title="@Model.LeakDate.Value.ToLongDateString()">@Model.LeakDate.Value.ToShortDateString()</time>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-details-flex">
|
||||
<div class="build-details-flex-item">
|
||||
@Html.LabelFor(model => model.SourceType)
|
||||
<div class="build-details-flex-value">
|
||||
@Html.DisplayFor(model => model.SourceType, "Enumeration")<br />
|
||||
<a href="@Url.Action("ViewSource", new
|
||||
{
|
||||
source = Model.SourceType
|
||||
})" class="more-link">
|
||||
<i class="fa fa-plus-circle fa-sm"></i>
|
||||
@string.Format(VariantTerms.Front_MoreFromSource, MvcExtensions.GetDisplayTextForEnum(Model.SourceType))
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
@if (!string.IsNullOrWhiteSpace(Model.SourceDetailsFiltered))
|
||||
{
|
||||
<h3>@Html.DisplayNameFor(model => model.SourceDetails)</h3>
|
||||
<div class="build-details-flex-value">@Html.Raw(Model.SourceDetailsFiltered)</div>
|
||||
<br />
|
||||
<h3>@Html.DisplayNameFor(model => model.SourceDetails)</h3>
|
||||
<div class="build-details-flex-value">@Html.Raw(Model.SourceDetailsFiltered)</div>
|
||||
<br />
|
||||
}
|
||||
<h3>@VariantTerms.Front_Share</h3>
|
||||
<div class="addthis_sharing_toolbox"></div>
|
||||
|
@ -145,60 +146,61 @@
|
|||
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<h3>@VariantTerms.Front_EditorActions</h3>
|
||||
<p class="build-details-flex-value">
|
||||
@Html.ActionLink(VariantTerms.Front_Edit, nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = Model.Id
|
||||
}, new
|
||||
{
|
||||
@class = "button edit-button"
|
||||
})
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
@Html.ActionLink(VariantTerms.Front_Delete, nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
<h3>@VariantTerms.Front_EditorActions</h3>
|
||||
<p class="build-details-flex-value">
|
||||
@Html.ActionLink(VariantTerms.Front_Edit, nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = Model.Id
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button"
|
||||
})
|
||||
}
|
||||
</p>
|
||||
}, new
|
||||
{
|
||||
@class = "button edit-button"
|
||||
})
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
@Html.ActionLink(VariantTerms.Front_Delete, nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = Model.Id
|
||||
}, new
|
||||
{
|
||||
@class = "button delete-button"
|
||||
})
|
||||
}
|
||||
</p>
|
||||
}
|
||||
<section class="build-details-comments">
|
||||
<h3>@VariantTerms.Front_Comments</h3>
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'buildfeed';
|
||||
var disqus_url = 'https://buildfeed.net/actions/info/@((object)Model.LegacyId ?? Model.Id)/';
|
||||
<h3>@VariantTerms.Front_Comments</h3>
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'buildfeed';
|
||||
var disqus_url = 'https://buildfeed.net/actions/info/@((object)Model.LegacyId ?? Model.Id)/';
|
||||
|
||||
(function()
|
||||
{
|
||||
var dsq = document.createElement('script');
|
||||
dsq.type = 'text/javascript';
|
||||
dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0])
|
||||
.appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||
(function()
|
||||
{
|
||||
var dsq = document.createElement('script');
|
||||
dsq.type = 'text/javascript';
|
||||
dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0])
|
||||
.appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||
</section>
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.ViewGroup), new
|
||||
{
|
||||
major = Model.MajorVersion,
|
||||
minor = Model.MinorVersion,
|
||||
number = Model.Number,
|
||||
revision = Model.Revision
|
||||
})" class="button">
|
||||
@VariantTerms.Front_ReturnToOverview
|
||||
</a>
|
||||
 
|
||||
<a href="@Url.Action(nameof(FrontController.IndexPage), new
|
||||
{
|
||||
page = 1
|
||||
})" class="button">@VariantTerms.Front_ReturnToListing</a>
|
||||
<a href="@Url.Action(nameof(FrontController.ViewGroup), new
|
||||
{
|
||||
major = Model.MajorVersion,
|
||||
minor = Model.MinorVersion,
|
||||
number = Model.Number,
|
||||
revision = Model.Revision
|
||||
})" class="button">
|
||||
@VariantTerms.Front_ReturnToOverview
|
||||
</a>
|
||||
 
|
||||
<a href="@Url.Action(nameof(FrontController.IndexPage), new
|
||||
{
|
||||
page = 1
|
||||
})" class="button">
|
||||
@VariantTerms.Front_ReturnToListing</a>
|
||||
</p>
|
|
@ -4,77 +4,77 @@
|
|||
@using Humanizer
|
||||
@model Tuple<BuildGroup, List<Build>>
|
||||
@{
|
||||
ViewBag.Title = $"{Model.Item1} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{Model.Item1} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@Model.Item1.ToString()</h1>
|
||||
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (Build build in Model.Item2)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="no-wrapping">
|
||||
@(string.IsNullOrEmpty(build.Lab)
|
||||
? "{Unknown}"
|
||||
: build.Lab)
|
||||
</a>
|
||||
</h3>
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
@foreach (Build build in Model.Item2)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="no-wrapping">
|
||||
@(string.IsNullOrEmpty(build.Lab)
|
||||
? "{Unknown}"
|
||||
: build.Lab)
|
||||
</a>
|
||||
</h3>
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
|
@ -4,107 +4,107 @@
|
|||
@using Humanizer
|
||||
@model IEnumerable<Build>
|
||||
@{
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId), ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId), ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
else
|
||||
{
|
||||
string metaDesc = string.Format(VariantTerms.Meta_LabGeneric, ViewBag.ItemId);
|
||||
<meta name="description" content="@metaDesc" />
|
||||
<meta property="og:description" content="@metaDesc" />
|
||||
}
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
else
|
||||
{
|
||||
string metaDesc = string.Format(VariantTerms.Meta_LabGeneric, ViewBag.ItemId);
|
||||
<meta name="description" content="@metaDesc" />
|
||||
<meta property="og:description" content="@metaDesc" />
|
||||
}
|
||||
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
}
|
||||
|
||||
<h1 class="eager-wrapping">@string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId)</h1>
|
||||
@if (ViewBag.MetaItem != null && !string.IsNullOrWhiteSpace(ViewBag.MetaItem.PageContent))
|
||||
{
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
}
|
||||
<h3>@VariantTerms.Front_Share</h3>
|
||||
<div class="addthis_sharing_toolbox"></div>
|
||||
<br />
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()
|
||||
</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()
|
||||
</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()
|
||||
</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()
|
||||
</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
@PaginationHelpers.PaginationBlock((int)ViewBag.PageNumber, (int)ViewBag.PageCount, "viewLab", ViewContext.RouteData.Values)
|
|
@ -4,104 +4,104 @@
|
|||
@using Humanizer
|
||||
@model IEnumerable<Build>
|
||||
@{
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", ViewBag.ItemId, ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", ViewBag.ItemId, ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
}
|
||||
|
||||
<h1>@ViewBag.ItemId</h1>
|
||||
@if (ViewBag.MetaItem != null && !string.IsNullOrWhiteSpace(ViewBag.MetaItem.PageContent))
|
||||
{
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
}
|
||||
<h3>@VariantTerms.Front_Share</h3>
|
||||
<div class="addthis_sharing_toolbox"></div>
|
||||
<br />
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="no-wrapping build-group-p" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="no-wrapping build-group-p" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
@PaginationHelpers.PaginationBlock((int)ViewBag.PageNumber, (int)ViewBag.PageCount, "viewSource", ViewContext.RouteData.Values)
|
|
@ -4,103 +4,103 @@
|
|||
@using Humanizer
|
||||
@model IEnumerable<Build>
|
||||
@{
|
||||
ViewBag.Title = $"{InvariantTerms.ProductName} {ViewBag.ItemId} {(ViewBag.PageNumber == 1 ? "" : string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber))} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{InvariantTerms.ProductName} {ViewBag.ItemId} {(ViewBag.PageNumber == 1 ? "" : string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber))} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
}
|
||||
|
||||
<h1>@string.Format("{0} {1}", InvariantTerms.ProductName, ViewBag.ItemId)</h1>
|
||||
@if (ViewBag.MetaItem != null
|
||||
&& !string.IsNullOrWhiteSpace(ViewBag.MetaItem.PageContent))
|
||||
&& !string.IsNullOrWhiteSpace(ViewBag.MetaItem.PageContent))
|
||||
{
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
}
|
||||
<h3>@VariantTerms.Front_Share</h3>
|
||||
<div class="addthis_sharing_toolbox"></div>
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="build-group-p no-wrapping" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab
|
||||
</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="build-group-p no-wrapping" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab
|
||||
</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
@PaginationHelpers.PaginationBlock((int)ViewBag.PageNumber, (int)ViewBag.PageCount, "viewVersion", ViewContext.RouteData.Values)
|
|
@ -4,113 +4,113 @@
|
|||
@using Humanizer
|
||||
@model IEnumerable<Build>
|
||||
@{
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId), ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
ViewBag.Title = string.Format("{0} {1} | {2}", string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId), ViewBag.PageNumber == 1
|
||||
? ""
|
||||
: string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber), InvariantTerms.SiteName);
|
||||
}
|
||||
|
||||
@section head
|
||||
{
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
else
|
||||
{
|
||||
string metaDesc = string.Format(VariantTerms.Meta_YearGeneric, ViewBag.ItemId);
|
||||
<meta name="description" content="@metaDesc" />
|
||||
<meta property="og:description" content="@metaDesc" />
|
||||
}
|
||||
@if (ViewBag.MetaItem != null)
|
||||
{
|
||||
<meta name="description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
<meta property="og:description" content="@ViewBag.MetaItem.MetaDescription" />
|
||||
}
|
||||
else
|
||||
{
|
||||
string metaDesc = string.Format(VariantTerms.Meta_YearGeneric, ViewBag.ItemId);
|
||||
<meta name="description" content="@metaDesc" />
|
||||
<meta property="og:description" content="@metaDesc" />
|
||||
}
|
||||
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
@if (ViewBag.PageNumber != 1)
|
||||
{
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
}
|
||||
}
|
||||
|
||||
<h1>@string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId)</h1>
|
||||
@if (ViewBag.MetaItem != null && !string.IsNullOrWhiteSpace(ViewBag.MetaItem.PageContent))
|
||||
{
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
<h3>@VariantTerms.Front_About</h3>
|
||||
@Html.Raw(ViewBag.MetaItem.PageContent)
|
||||
}
|
||||
<h3>@VariantTerms.Front_Share</h3>
|
||||
<div class="addthis_sharing_toolbox"></div>
|
||||
<br />
|
||||
<h3>@VariantTerms.Front_Listing</h3>
|
||||
<div class="build-group-listing">
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="build-group-p no-wrapping" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab
|
||||
</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()
|
||||
</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()
|
||||
</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
@foreach (Build build in Model)
|
||||
{
|
||||
<div class="build-group">
|
||||
<h3 class="build-group-title" title="@build.AlternateBuildString">
|
||||
<a href="@Url.Action("ViewBuild", new
|
||||
{
|
||||
id = build.Id
|
||||
})">
|
||||
@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")
|
||||
</a>
|
||||
</h3>
|
||||
@if (!string.IsNullOrEmpty(build.Lab))
|
||||
{
|
||||
<p class="build-group-p no-wrapping" title="@build.Lab">
|
||||
<i class="fa fa-code-fork fa-fw"></i> @build.Lab
|
||||
</p>
|
||||
}
|
||||
@if (build.BuildTime.HasValue)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-calendar fa-fw"></i> @build.BuildTime.Value.ToLongDateWithoutDay()
|
||||
</span>
|
||||
</p>
|
||||
<p class="build-group-p">
|
||||
<span title="@build.BuildTime.Value.Humanize()">
|
||||
<i class="fa fa-clock-o fa-fw"></i> @build.BuildTime.Value.ToShortTimeString()
|
||||
</span>
|
||||
</p>
|
||||
}
|
||||
@if (build.IsLeaked)
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-unlock-alt fa-fw"></i> @VariantTerms.Front_Public</span>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="build-group-p">
|
||||
<span>
|
||||
<i class="fa fa-lock fa-fw"></i> @VariantTerms.Front_Private</span>
|
||||
</p>
|
||||
}
|
||||
@if (Roles.IsUserInRole("Editors") || Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<p>
|
||||
<a href="@Url.Action(nameof(FrontController.EditBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button edit-button">
|
||||
@VariantTerms.Front_Edit
|
||||
</a>
|
||||
|
||||
@if (Roles.IsUserInRole("Administrators"))
|
||||
{
|
||||
<a href="@Url.Action(nameof(FrontController.DeleteBuild), new
|
||||
{
|
||||
id = build.Id
|
||||
})" class="button delete-button">
|
||||
@VariantTerms.Front_Delete
|
||||
</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
<div class="build-group-empty"></div>
|
||||
</div>
|
||||
@PaginationHelpers.PaginationBlock((int)ViewBag.PageNumber, (int)ViewBag.PageCount, "viewYear", ViewContext.RouteData.Values)
|
|
@ -1,96 +1,299 @@
|
|||
|
||||
@using System.Globalization
|
||||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Common_Credits} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Common_Credits} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Common_Credits</h1>
|
||||
|
||||
<dl class="credits-list">
|
||||
<dt>BuildFeed Team</dt>
|
||||
<dd>Thomas Hounsell <a target="_blank" rel="nofollow noopener" href="https://twitter.com/tomhounsell"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Nick (ultrawindows) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/nickurtnl"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Ahmed (airportsfan) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/airportsfan"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Lukas (tfwboredom) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/tfwboredom"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Soorya (fakirmeditation) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/fakirmeditation"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>BuildFeed Team</dt>
|
||||
<dd>
|
||||
Thomas Hounsell 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/tomhounsell">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Nick (ultrawindows) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/nickurtnl">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Ahmed (airportsfan) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/airportsfan">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Lukas (tfwboredom) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/tfwboredom">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Soorya (fakirmeditation) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/fakirmeditation">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="credits-wrapper">
|
||||
<dl class="credits-list">
|
||||
<dt>Arabic (@System.Globalization.CultureInfo.GetCultureInfo("ar").NativeName) Translation</dt>
|
||||
<dd>Ahmed (airportsfan) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/airportsfan"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Bengali (@System.Globalization.CultureInfo.GetCultureInfo("bn").NativeName) Translation</dt>
|
||||
<dd>Mehedi Hassan <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mehedih_"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Czech (@System.Globalization.CultureInfo.GetCultureInfo("cs").NativeName) Translation</dt>
|
||||
<dd>David (rezedus) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/rezedus"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>German (@System.Globalization.CultureInfo.GetCultureInfo("de").NativeName) Translation</dt>
|
||||
<dd>The Dhel <a target="_blank" rel="nofollow noopener" href="https://twitter.com/The_Dhel"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Christopher <a target="_blank" rel="nofollow noopener" href="https://twitter.com/evil_pro_"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Greek (@System.Globalization.CultureInfo.GetCultureInfo("el").NativeName) Translation</dt>
|
||||
<dd>Hacker?pcs</dd>
|
||||
<dd>Sotiris Michail <a target="_blank" rel="nofollow noopener" href="https://twitter.com/SnakeOnStick"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Spanish (@System.Globalization.CultureInfo.GetCultureInfo("es").NativeName) Translation</dt>
|
||||
<dd>Nightsteed</dd>
|
||||
<dd>Ben Ward <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_BenW_"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Meober Whagby <a target="_blank" rel="nofollow noopener" href="https://twitter.com/ultimofriki"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Farsi (@System.Globalization.CultureInfo.GetCultureInfo("fa").NativeName) Translation</dt>
|
||||
<dd>Niloo <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Niloo0937"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Finnish (@System.Globalization.CultureInfo.GetCultureInfo("fi").NativeName) Translation</dt>
|
||||
<dd>Daniel Gurney (wheatley) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Daniel_Gurney0"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>French (@System.Globalization.CultureInfo.GetCultureInfo("fr").NativeName) Translation</dt>
|
||||
<dd>CgSYannick <a target="_blank" rel="nofollow noopener" href="https://twitter.com/YannickTHFR"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Gustave M. <a target="_blank" rel="nofollow noopener" href="https://twitter.com/gus33000"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Christophe Lavalle <a target="_blank" rel="nofollow noopener" href="https://twitter.com/ChristopheLav"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Croatian (@System.Globalization.CultureInfo.GetCultureInfo("hr").NativeName) Translation</dt>
|
||||
<dd>Mario Bešen <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mariobesen"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Hebrew (@System.Globalization.CultureInfo.GetCultureInfo("he").NativeName) Translation</dt>
|
||||
<dd>David Fainshtein <a target="_blank" rel="nofollow noopener" href="https://twitter.com/david_f"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Indonesian (@System.Globalization.CultureInfo.GetCultureInfo("id").NativeName) Translation</dt>
|
||||
<dd>Andreas</dd>
|
||||
<dt>Italian (@System.Globalization.CultureInfo.GetCultureInfo("it").NativeName) Translation</dt>
|
||||
<dd>Meober Whagby <a target="_blank" rel="nofollow noopener" href="https://twitter.com/ultimofriki"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Simone Nataz <a target="_blank" rel="nofollow noopener" href="https://twitter.com/djnataz"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Japanese (@System.Globalization.CultureInfo.GetCultureInfo("ja").NativeName) Translation</dt>
|
||||
<dd>parly <a target="_blank" rel="nofollow noopener" href="https://github.com/parly"><i class="fa fa-github"></i></a></dd>
|
||||
<dt>Korean (@System.Globalization.CultureInfo.GetCultureInfo("ko").NativeName) Translation</dt>
|
||||
<dd>qta3426</dd>
|
||||
<dd>SD SkyKlouD <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_SDSkyKlouD"><i class="fa fa-twitter"></i></a></dd>
|
||||
</dl>
|
||||
<dl class="credits-list">
|
||||
<dt>Lithuanian (@System.Globalization.CultureInfo.GetCultureInfo("lt").NativeName) Translation</dt>
|
||||
<dd>Super User <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Superb_User"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Dutch (@System.Globalization.CultureInfo.GetCultureInfo("nl").NativeName) Translation</dt>
|
||||
<dd>Nick (ultrawindows) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/nickurtnl"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Polish (@System.Globalization.CultureInfo.GetCultureInfo("pl").NativeName) Translation</dt>
|
||||
<dd>piotrulos <a target="_blank" rel="nofollow noopener" href="https://twitter.com/piotrulos"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>dzaggiel <a target="_blank" rel="nofollow noopener" href="https://twitter.com/dzaggiel"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Portuguese (@System.Globalization.CultureInfo.GetCultureInfo("pt").NativeName) Translation</dt>
|
||||
<dd>OBattler</dd>
|
||||
<dt>Portugese - Brazilian (@System.Globalization.CultureInfo.GetCultureInfo("pt-br").NativeName) Translation</dt>
|
||||
<dd>RichardG</dd>
|
||||
@*<dt>Pseudo-localisation (@System.Globalization.CultureInfo.GetCultureInfo("qps-ploc").NativeName) Translation</dt>
|
||||
<dl class="credits-list">
|
||||
<dt>Arabic (@CultureInfo.GetCultureInfo("ar").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Ahmed (airportsfan) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/airportsfan">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Bengali (@CultureInfo.GetCultureInfo("bn").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Mehedi Hassan 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/mehedih_">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Czech (@CultureInfo.GetCultureInfo("cs").NativeName) Translation</dt>
|
||||
<dd>
|
||||
David (rezedus) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/rezedus">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>German (@CultureInfo.GetCultureInfo("de").NativeName) Translation</dt>
|
||||
<dd>
|
||||
The Dhel 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/The_Dhel">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Christopher 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/evil_pro_">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Greek (@CultureInfo.GetCultureInfo("el").NativeName) Translation</dt>
|
||||
<dd>Hacker?pcs</dd>
|
||||
<dd>
|
||||
Sotiris Michail 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/SnakeOnStick">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Spanish (@CultureInfo.GetCultureInfo("es").NativeName) Translation</dt>
|
||||
<dd>Nightsteed</dd>
|
||||
<dd>
|
||||
Ben Ward 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/_BenW_">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Meober Whagby 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/ultimofriki">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Farsi (@CultureInfo.GetCultureInfo("fa").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Niloo 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/Niloo0937">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Finnish (@CultureInfo.GetCultureInfo("fi").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Daniel Gurney (wheatley) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/Daniel_Gurney0">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>French (@CultureInfo.GetCultureInfo("fr").NativeName) Translation</dt>
|
||||
<dd>
|
||||
CgSYannick 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/YannickTHFR">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Gustave M. 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/gus33000">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Christophe Lavalle 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/ChristopheLav">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Croatian (@CultureInfo.GetCultureInfo("hr").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Mario Bešen 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/mariobesen">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Hebrew (@CultureInfo.GetCultureInfo("he").NativeName) Translation</dt>
|
||||
<dd>
|
||||
David Fainshtein 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/david_f">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Indonesian (@CultureInfo.GetCultureInfo("id").NativeName) Translation</dt>
|
||||
<dd>Andreas</dd>
|
||||
<dt>Italian (@CultureInfo.GetCultureInfo("it").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Meober Whagby 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/ultimofriki">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Simone Nataz 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/djnataz">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Japanese (@CultureInfo.GetCultureInfo("ja").NativeName) Translation</dt>
|
||||
<dd>
|
||||
parly 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://github.com/parly">
|
||||
<i class="fa fa-github"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Korean (@CultureInfo.GetCultureInfo("ko").NativeName) Translation</dt>
|
||||
<dd>qta3426</dd>
|
||||
<dd>
|
||||
SD SkyKlouD 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/_SDSkyKlouD">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="credits-list">
|
||||
<dt>Lithuanian (@CultureInfo.GetCultureInfo("lt").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Super User 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/Superb_User">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Dutch (@CultureInfo.GetCultureInfo("nl").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Nick (ultrawindows) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/nickurtnl">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Polish (@CultureInfo.GetCultureInfo("pl").NativeName) Translation</dt>
|
||||
<dd>
|
||||
piotrulos 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/piotrulos">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
dzaggiel 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/dzaggiel">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Portuguese (@CultureInfo.GetCultureInfo("pt").NativeName) Translation</dt>
|
||||
<dd>OBattler</dd>
|
||||
<dt>Portugese - Brazilian (@CultureInfo.GetCultureInfo("pt-br").NativeName) Translation</dt>
|
||||
<dd>RichardG</dd>
|
||||
@*<dt>Pseudo-localisation (@System.Globalization.CultureInfo.GetCultureInfo("qps-ploc").NativeName) Translation</dt>
|
||||
<dd>Thomas Hounsell, with <a target="_blank" rel="nofollow noopener" href="http://www.pseudolocalize.com/"><i class="fa fa-globe"></i> Pseudolocalize!</a></dd>*@
|
||||
<dt>Romanian (@System.Globalization.CultureInfo.GetCultureInfo("ro").NativeName) Translation</dt>
|
||||
<dd>ovctvct <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/channel/UC9AC01rKiwDhVPvAsT93rjw"><i class="fa fa-youtube"></i></a></dd>
|
||||
<dt>Russian (@System.Globalization.CultureInfo.GetCultureInfo("ru").NativeName) Translation</dt>
|
||||
<dd>Roman (rlinev) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/rlinev"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Fuhrer_Adolf <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Fuhrer_Adolf"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Slovak (@System.Globalization.CultureInfo.GetCultureInfo("sk").NativeName) Translation</dt>
|
||||
<dd>Lukas <a target="_blank" rel="nofollow noopener" href="https://twitter.com/tfwboredom"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Slovenian (@System.Globalization.CultureInfo.GetCultureInfo("sl").NativeName) Translation</dt>
|
||||
<dd>Overdoze</dd>
|
||||
<dt>Swedish (@System.Globalization.CultureInfo.GetCultureInfo("sv").NativeName) Translation</dt>
|
||||
<dd>mrpijey <a target="_blank" rel="nofollow noopener" href="http://www.mrpijey.net/"><i class="fa fa-globe"></i></a></dd>
|
||||
<dt>Turkish (@System.Globalization.CultureInfo.GetCultureInfo("tr").NativeName) Translation</dt>
|
||||
<dd>Furkan AKÇATEPE <a target="_blank" rel="nofollow noopener" href="https://twitter.com/FurkanAKATEPE"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dd>Can Taşan</dd>
|
||||
<dd>Duhan Ömür <a target="_blank" rel="nofollow noopener" href="https://twitter.com/BilgisyrKurdu16"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Ukrainian (@System.Globalization.CultureInfo.GetCultureInfo("uk").NativeName) Translation</dt>
|
||||
<dd>Fuhrer_Adolf <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Fuhrer_Adolf"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Vietnamese (@System.Globalization.CultureInfo.GetCultureInfo("vi").NativeName) Translation</dt>
|
||||
<dd>Trần Kim Long Hải <a target="_blank" rel="nofollow noopener" href="https://twitter.com/trankimlonghai"><i class="fa fa-twitter"></i></a></dd>
|
||||
<dt>Chinese - Simplified (@System.Globalization.CultureInfo.GetCultureInfo("zh-hans").NativeName) Translation</dt>
|
||||
<dd>Zheng He <a target="_blank" rel="nofollow noopener" href="http://www.betaworld.cn/"><i class="fa fa-globe"></i></a></dd>
|
||||
<dt>Chinese - Traditional (@System.Globalization.CultureInfo.GetCultureInfo("zh-hant").NativeName) Translation</dt>
|
||||
<dd>Andrew Huang <a target="_blank" rel="nofollow noopener" href="https://twitter.com/AndrewDev8383"><i class="fa fa-twitter"></i></a> <a target="_blank" rel="nofollow noopener" href="http://isite.tw/"><i class="fa fa-globe"></i></a></dd>
|
||||
<dd>GT Wang <a target="_blank" rel="nofollow noopener" href="http://mkvq.blogspot.com/"><i class="fa fa-globe"></i></a></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<dt>Romanian (@CultureInfo.GetCultureInfo("ro").NativeName) Translation</dt>
|
||||
<dd>
|
||||
ovctvct 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/channel/UC9AC01rKiwDhVPvAsT93rjw">
|
||||
<i class="fa fa-youtube"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Russian (@CultureInfo.GetCultureInfo("ru").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Roman (rlinev) 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/rlinev">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
Fuhrer_Adolf 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/Fuhrer_Adolf">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Slovak (@CultureInfo.GetCultureInfo("sk").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Lukas 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/tfwboredom">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Slovenian (@CultureInfo.GetCultureInfo("sl").NativeName) Translation</dt>
|
||||
<dd>Overdoze</dd>
|
||||
<dt>Swedish (@CultureInfo.GetCultureInfo("sv").NativeName) Translation</dt>
|
||||
<dd>
|
||||
mrpijey 
|
||||
<a target="_blank" rel="nofollow noopener" href="http://www.mrpijey.net/">
|
||||
<i class="fa fa-globe"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Turkish (@CultureInfo.GetCultureInfo("tr").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Furkan AKÇATEPE 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/FurkanAKATEPE">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>Can Taşan</dd>
|
||||
<dd>
|
||||
Duhan Ömür 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/BilgisyrKurdu16">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Ukrainian (@CultureInfo.GetCultureInfo("uk").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Fuhrer_Adolf 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/Fuhrer_Adolf">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Vietnamese (@CultureInfo.GetCultureInfo("vi").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Trần Kim Long Hải 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/trankimlonghai">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Chinese - Simplified (@CultureInfo.GetCultureInfo("zh-hans").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Zheng He 
|
||||
<a target="_blank" rel="nofollow noopener" href="http://www.betaworld.cn/">
|
||||
<i class="fa fa-globe"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dt>Chinese - Traditional (@CultureInfo.GetCultureInfo("zh-hant").NativeName) Translation</dt>
|
||||
<dd>
|
||||
Andrew Huang 
|
||||
<a target="_blank" rel="nofollow noopener" href="https://twitter.com/AndrewDev8383">
|
||||
<i class="fa fa-twitter"></i>
|
||||
</a> 
|
||||
<a target="_blank" rel="nofollow noopener" href="http://isite.tw/">
|
||||
<i class="fa fa-globe"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
GT Wang 
|
||||
<a target="_blank" rel="nofollow noopener" href="http://mkvq.blogspot.com/">
|
||||
<i class="fa fa-globe"></i>
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
|
@ -1,52 +1,52 @@
|
|||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Common_RssFeeds} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Common_RssFeeds} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Common_RssFeeds</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="@Url.Action("Index", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyCompiled">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyCompiled</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Leaked", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyLeaked">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyLeaked</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Added", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyAdded">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyAdded</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Version", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_HighestVersion">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_HighestVersion</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#rss-labs" data-toggle="collapse">@VariantTerms.Search_Lab</a>
|
||||
<ul id="rss-labs" class="collapse">
|
||||
@foreach (string lab in ViewBag.Labs)
|
||||
{
|
||||
<li>
|
||||
<a href="@Url.Action("Lab", new
|
||||
{
|
||||
controller = "Rss",
|
||||
lab
|
||||
})" title="@lab">
|
||||
<i class="fa fa-sm fa-rss"></i> @lab</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Index", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyCompiled">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyCompiled</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Leaked", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyLeaked">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyLeaked</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Added", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyAdded">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyAdded</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Version", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_HighestVersion">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_HighestVersion</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#rss-labs" data-toggle="collapse">@VariantTerms.Search_Lab</a>
|
||||
<ul id="rss-labs" class="collapse">
|
||||
@foreach (string lab in ViewBag.Labs)
|
||||
{
|
||||
<li>
|
||||
<a href="@Url.Action("Lab", new
|
||||
{
|
||||
controller = "Rss",
|
||||
lab
|
||||
})" title="@lab">
|
||||
<i class="fa fa-sm fa-rss"></i> @lab</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
|
@ -1,130 +1,130 @@
|
|||
@using BuildFeed.Controllers
|
||||
@using BuildFeed.Model.View
|
||||
@model BuildFeed.Model.View.SitemapData
|
||||
@model SitemapData
|
||||
@{
|
||||
ViewBag.Title = $"{VariantTerms.Common_Sitemap} | {InvariantTerms.SiteName}";
|
||||
ViewBag.Title = $"{VariantTerms.Common_Sitemap} | {InvariantTerms.SiteName}";
|
||||
}
|
||||
|
||||
<h1>@VariantTerms.Common_Sitemap</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
@Html.ActionLink("BuildFeed", nameof(FrontController.Index), "Front")
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#sitemap-builds">Builds</a>
|
||||
<ul id="sitemap-builds">
|
||||
@foreach (SitemapDataBuildGroup buildGroup in Model.Builds)
|
||||
{
|
||||
<li>
|
||||
@Html.ActionLink(buildGroup.Id.ToString(), "ViewGroup", new
|
||||
{
|
||||
controller = "Front",
|
||||
major = buildGroup.Id.Major,
|
||||
minor = buildGroup.Id.Minor,
|
||||
number = buildGroup.Id.Build,
|
||||
revision = buildGroup.Id.Revision
|
||||
})
|
||||
<ul>
|
||||
@foreach (SitemapDataBuild build in buildGroup.Builds)
|
||||
{
|
||||
<li>
|
||||
@Html.ActionLink(build.Name, "ViewBuild", new
|
||||
{
|
||||
controller = "Front",
|
||||
id = build.Id
|
||||
})</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
@foreach (KeyValuePair<string, SitemapPagedAction[]> item in Model.Actions)
|
||||
{
|
||||
<li>
|
||||
@Html.ActionLink("BuildFeed", nameof(FrontController.Index), "Front")
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#sitemap-@item.Key.ToLower()">@item.Key</a>
|
||||
<ul id="sitemap-@item.Key.ToLower()">
|
||||
@foreach (SitemapPagedAction action in item.Value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(action.Name))
|
||||
{
|
||||
<li>@Html.ActionLink("Page 1", action.Action, action.UrlParams)</li>
|
||||
for (int i = 2; i <= action.Pages; i++)
|
||||
{
|
||||
RouteValueDictionary urlParams = action.UrlParams;
|
||||
urlParams["page"] = i;
|
||||
<li>@Html.ActionLink($"Page {i}", action.Action + "Page", urlParams)</li>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<a href="#sitemap-builds">Builds</a>
|
||||
<ul id="sitemap-builds">
|
||||
@foreach (SitemapDataBuildGroup buildGroup in Model.Builds)
|
||||
{
|
||||
<li>
|
||||
<a href="#sitemap-@action.UniqueId">@action.Name</a>
|
||||
<ul id="sitemap-@action.UniqueId">
|
||||
<li>@Html.ActionLink("Page 1", action.Action, action.UrlParams)</li>
|
||||
@for (int i = 2; i <= action.Pages; i++)
|
||||
{
|
||||
RouteValueDictionary urlParams = action.UrlParams;
|
||||
urlParams["page"] = i;
|
||||
<li>@Html.ActionLink($"Page {i}", action.Action + "Page", urlParams)</li>
|
||||
}
|
||||
</ul>
|
||||
@Html.ActionLink(buildGroup.Id.ToString(), "ViewGroup", new
|
||||
{
|
||||
controller = "Front",
|
||||
major = buildGroup.Id.Major,
|
||||
minor = buildGroup.Id.Minor,
|
||||
number = buildGroup.Id.Build,
|
||||
revision = buildGroup.Id.Revision
|
||||
})
|
||||
<ul>
|
||||
@foreach (SitemapDataBuild build in buildGroup.Builds)
|
||||
{
|
||||
<li>
|
||||
@Html.ActionLink(build.Name, "ViewBuild", new
|
||||
{
|
||||
controller = "Front",
|
||||
id = build.Id
|
||||
})</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
<li>
|
||||
<a href="#sitemap-rss">@VariantTerms.Common_RssFeeds</a>
|
||||
<ul id="sitemap-rss">
|
||||
<li>
|
||||
<a href="@Url.Action("Index", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyCompiled">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyCompiled</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Leaked", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyLeaked">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyLeaked</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Added", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyAdded">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyAdded</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Version", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_HighestVersion">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_HighestVersion</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#rss-labs">@VariantTerms.Model_LabString</a>
|
||||
<ul id="rss-labs">
|
||||
@foreach (string lab in Model.Labs)
|
||||
{
|
||||
<li>
|
||||
<a href="@Url.Action("Lab", new
|
||||
{
|
||||
controller = "Rss",
|
||||
lab
|
||||
})" title="@lab">
|
||||
<i class="fa fa-sm fa-rss"></i> @lab</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@foreach (var item in Model.Actions)
|
||||
{
|
||||
<li>
|
||||
<a href="#sitemap-@item.Key.ToLower()">@item.Key</a>
|
||||
<ul id="sitemap-@item.Key.ToLower()">
|
||||
@foreach (SitemapPagedAction action in item.Value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(action.Name))
|
||||
{
|
||||
<li>@Html.ActionLink("Page 1", action.Action, action.UrlParams)</li>
|
||||
for (int i = 2; i <= action.Pages; i++)
|
||||
{
|
||||
RouteValueDictionary urlParams = action.UrlParams;
|
||||
urlParams["page"] = i;
|
||||
<li>@Html.ActionLink($"Page {i}", action.Action + "Page", urlParams)</li>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<li>
|
||||
<a href="#sitemap-@action.UniqueId">@action.Name</a>
|
||||
<ul id="sitemap-@action.UniqueId">
|
||||
<li>@Html.ActionLink("Page 1", action.Action, action.UrlParams)</li>
|
||||
@for (int i = 2; i <= action.Pages; i++)
|
||||
{
|
||||
RouteValueDictionary urlParams = action.UrlParams;
|
||||
urlParams["page"] = i;
|
||||
<li>@Html.ActionLink($"Page {i}", action.Action + "Page", urlParams)</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
<li>
|
||||
<a href="#sitemap-rss">@VariantTerms.Common_RssFeeds</a>
|
||||
<ul id="sitemap-rss">
|
||||
<li>
|
||||
<a href="@Url.Action("Index", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyCompiled">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyCompiled</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Leaked", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyLeaked">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyLeaked</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Added", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_RecentlyAdded">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_RecentlyAdded</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@Url.Action("Version", new
|
||||
{
|
||||
controller = "Rss"
|
||||
})" title="@VariantTerms.Support_HighestVersion">
|
||||
<i class="fa fa-sm fa-rss"></i> @VariantTerms.Support_HighestVersion</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#rss-labs">@VariantTerms.Model_LabString</a>
|
||||
<ul id="rss-labs">
|
||||
@foreach (string lab in Model.Labs)
|
||||
{
|
||||
<li>
|
||||
<a href="@Url.Action("Lab", new
|
||||
{
|
||||
controller = "Rss",
|
||||
lab
|
||||
})" title="@lab">
|
||||
<i class="fa fa-sm fa-rss"></i> @lab</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<system.web>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
</system.webServer>
|
||||
<system.web>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -1,28 +1,28 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<system.web>
|
||||
<customErrors mode="On" xdt:Transform="Insert" />
|
||||
<compilation xdt:Transform="RemoveAttributes(debug)" />
|
||||
<trace enabled="false" requestLimit="40" pageOutput="false" xdt:Transform="Replace" />
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="CanonicalHost" stopProcessing="true" xdt:Transform="Insert">
|
||||
<match url="(.*)" />
|
||||
<conditions logicalGrouping="MatchAny">
|
||||
<add input="{HTTP_HOST}" pattern="^buildfeed\.net$" negate="true" />
|
||||
<add input="{HTTPS}" pattern="off" />
|
||||
</conditions>
|
||||
<action type="Redirect" url="https://buildfeed.net/{R:1}" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<add name="Strict-Transport-Security" value="max-age=31536000" xdt:Transform="Insert" />
|
||||
</customHeaders>
|
||||
</httpProtocol>
|
||||
</system.webServer>
|
||||
<system.web>
|
||||
<customErrors mode="On" xdt:Transform="Insert" />
|
||||
<compilation xdt:Transform="RemoveAttributes(debug)" />
|
||||
<trace enabled="false" requestLimit="40" pageOutput="false" xdt:Transform="Replace" />
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="CanonicalHost" stopProcessing="true" xdt:Transform="Insert">
|
||||
<match url="(.*)" />
|
||||
<conditions logicalGrouping="MatchAny">
|
||||
<add input="{HTTP_HOST}" pattern="^buildfeed\.net$" negate="true" />
|
||||
<add input="{HTTPS}" pattern="off" />
|
||||
</conditions>
|
||||
<action type="Redirect" url="https://buildfeed.net/{R:1}" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<add name="Strict-Transport-Security" value="max-age=31536000" xdt:Transform="Insert" />
|
||||
</customHeaders>
|
||||
</httpProtocol>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -1,22 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="res/ico/tiny.png" />
|
||||
<square150x150logo src="res/ico/square.png" />
|
||||
<wide310x150logo src="res/ico/wide.png" />
|
||||
<square310x310logo src="res/ico/large.png" />
|
||||
<TileColor>#2E3440</TileColor>
|
||||
</tile>
|
||||
<notification>
|
||||
<polling-uri src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=1" />
|
||||
<polling-uri2 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=2" />
|
||||
<polling-uri3 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=3" />
|
||||
<polling-uri4 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=4" />
|
||||
<polling-uri5 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=5" />
|
||||
<frequency>30</frequency>
|
||||
<cycle>1</cycle>
|
||||
</notification>
|
||||
</msapplication>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="res/ico/tiny.png" />
|
||||
<square150x150logo src="res/ico/square.png" />
|
||||
<wide310x150logo src="res/ico/wide.png" />
|
||||
<square310x310logo src="res/ico/large.png" />
|
||||
<TileColor>#2E3440</TileColor>
|
||||
</tile>
|
||||
<notification>
|
||||
<polling-uri src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=1" />
|
||||
<polling-uri2 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=2" />
|
||||
<polling-uri3 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=3" />
|
||||
<polling-uri4 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=4" />
|
||||
<polling-uri5 src="http://notifications.buildmypinnedsite.com/?feed=https://buildfeed.net/rss/Added/&id=5" />
|
||||
<frequency>30</frequency>
|
||||
<cycle>1</cycle>
|
||||
</notification>
|
||||
</msapplication>
|
||||
</browserconfig>
|
|
@ -8,38 +8,38 @@ var uglify = require("gulp-uglify-es").default;
|
|||
var autoprefixer = require("gulp-autoprefixer");
|
||||
|
||||
gulp.task("sass-compile",
|
||||
function()
|
||||
{
|
||||
gulp.src("./res/css/*.scss")
|
||||
.pipe(sourceMaps.init())
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer({
|
||||
browsers: ["> 1%", "IE 10-11", "last 5 versions"],
|
||||
cascade: false
|
||||
}))
|
||||
.pipe(cleanCss())
|
||||
.pipe(sourceMaps.write("./"))
|
||||
.pipe(gulp.dest("./res/css/"));
|
||||
});
|
||||
function()
|
||||
{
|
||||
gulp.src("./res/css/*.scss")
|
||||
.pipe(sourceMaps.init())
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer({
|
||||
browsers: ["> 1%", "IE 10-11", "last 5 versions"],
|
||||
cascade: false
|
||||
}))
|
||||
.pipe(cleanCss())
|
||||
.pipe(sourceMaps.write("./"))
|
||||
.pipe(gulp.dest("./res/css/"));
|
||||
});
|
||||
|
||||
gulp.task("typescript",
|
||||
function()
|
||||
{
|
||||
return gulp.src("./res/ts/*.ts")
|
||||
.pipe(sourceMaps.init())
|
||||
.pipe(ts({
|
||||
target: "es6",
|
||||
sourceMap: false
|
||||
}))
|
||||
.js
|
||||
.pipe(uglify())
|
||||
.pipe(sourceMaps.write("./"))
|
||||
.pipe(gulp.dest("./res/ts/"));
|
||||
});
|
||||
function()
|
||||
{
|
||||
return gulp.src("./res/ts/*.ts")
|
||||
.pipe(sourceMaps.init())
|
||||
.pipe(ts({
|
||||
target: "es6",
|
||||
sourceMap: false
|
||||
}))
|
||||
.js
|
||||
.pipe(uglify())
|
||||
.pipe(sourceMaps.write("./"))
|
||||
.pipe(gulp.dest("./res/ts/"));
|
||||
});
|
||||
|
||||
gulp.task("watch-sass",
|
||||
function()
|
||||
{
|
||||
gulp.watch("./res/css/**.scss", ["sass-compile"]);
|
||||
gulp.watch("./res/ts/*.ts", ["typescript"]);
|
||||
});
|
||||
function()
|
||||
{
|
||||
gulp.watch("./res/css/**.scss", ["sass-compile"]);
|
||||
gulp.watch("./res/ts/*.ts", ["typescript"]);
|
||||
});
|
|
@ -46,9 +46,7 @@
|
|||
<package id="Humanizer.Core.zh-CN" version="2.2.0" targetFramework="net47" />
|
||||
<package id="Humanizer.Core.zh-Hans" version="2.2.0" targetFramework="net47" />
|
||||
<package id="Humanizer.Core.zh-Hant" version="2.2.0" targetFramework="net47" />
|
||||
<package id="jQuery" version="3.3.1" targetFramework="net47" />
|
||||
<package id="jquery.TypeScript.DefinitelyTyped" version="3.1.2" targetFramework="net47" />
|
||||
<package id="jQuery.Validation" version="1.17.0" targetFramework="net47" />
|
||||
<package id="jsrender.TypeScript.DefinitelyTyped" version="0.1.8" targetFramework="net47" />
|
||||
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net47" />
|
||||
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net47" />
|
||||
|
@ -59,7 +57,6 @@
|
|||
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net47" />
|
||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.8" targetFramework="net47" />
|
||||
<package id="Microsoft.CSharp" version="4.4.1" targetFramework="net47" />
|
||||
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net47" />
|
||||
<package id="Microsoft.Net.Compilers" version="2.6.1" targetFramework="net47" developmentDependency="true" />
|
||||
<package id="Microsoft.NETCore.Platforms" version="2.0.1" targetFramework="net47" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net47" />
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<staticContent>
|
||||
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
|
||||
</staticContent>
|
||||
</system.webServer>
|
||||
<system.webServer>
|
||||
<staticContent>
|
||||
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
|
||||
</staticContent>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -11,4 +11,4 @@ $strong-blue: #4076B5;
|
|||
@mixin standard-box-shadow($color)
|
||||
{
|
||||
box-shadow: 0 0 10px 0 rgba($color, 0.33);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["rtl.scss"],"names":[],"mappings":"AAAA,2CAEG,WAAA,KAFH,gDAMM,WAAA,MAIN,gCAEG,WAAA,MAGH,kBAIM,WAAA,KAJN,kBASM,aAAA,EACA,YAAA,IAIN,6DAKM,WAAA,KALN,8DAUM,WAAA,MAIN,yBAEG,8DAIM,WAAA,OAJN,6DASM,WAAA","file":"rtl.css","sourcesContent":["nav#page-navigation #page-navigation-links\r\n{\r\n text-align: left;\r\n\r\n > li > a\r\n {\r\n text-align: right;\r\n }\r\n}\r\n\r\n.dropdown-parent .dropdown-menu\r\n{\r\n text-align: right;\r\n}\r\n\r\n.form-group\r\n{\r\n label\r\n {\r\n text-align: left;\r\n }\r\n\r\n > label\r\n {\r\n margin-right: 0;\r\n margin-left: 1em;\r\n }\r\n}\r\n\r\nfooter#page-footer .footer-flex .footer-flex-item\r\n{\r\n\r\n &:last-child\r\n {\r\n text-align: left;\r\n }\r\n\r\n &:first-child\r\n {\r\n text-align: right;\r\n }\r\n}\r\n\r\n@media (max-width: 640px)\r\n{\r\n footer#page-footer .footer-flex .footer-flex-item\r\n {\r\n &:first-child\r\n {\r\n text-align: center;\r\n }\r\n\r\n &:last-child\r\n {\r\n text-align: center;\r\n }\r\n }\r\n}\r\n"]}
|
||||
{"version":3,"sources":["rtl.scss"],"names":[],"mappings":"AAAA,2CAEI,WAAA,KAFJ,gDAMQ,WAAA,MAIR,gCAEI,WAAA,MAGJ,kBAIQ,WAAA,KAJR,kBASQ,aAAA,EACA,YAAA,IAIR,6DAKQ,WAAA,KALR,8DAUQ,WAAA,MAIR,yBAEI,8DAIQ,WAAA,OAJR,6DASQ,WAAA","file":"rtl.css","sourcesContent":["nav#page-navigation #page-navigation-links\r\n{\r\n text-align: left;\r\n\r\n > li > a\r\n {\r\n text-align: right;\r\n }\r\n}\r\n\r\n.dropdown-parent .dropdown-menu\r\n{\r\n text-align: right;\r\n}\r\n\r\n.form-group\r\n{\r\n label\r\n {\r\n text-align: left;\r\n }\r\n\r\n > label\r\n {\r\n margin-right: 0;\r\n margin-left: 1em;\r\n }\r\n}\r\n\r\nfooter#page-footer .footer-flex .footer-flex-item\r\n{\r\n\r\n &:last-child\r\n {\r\n text-align: left;\r\n }\r\n\r\n &:first-child\r\n {\r\n text-align: right;\r\n }\r\n}\r\n\r\n@media (max-width: 640px)\r\n{\r\n footer#page-footer .footer-flex .footer-flex-item\r\n {\r\n &:first-child\r\n {\r\n text-align: center;\r\n }\r\n\r\n &:last-child\r\n {\r\n text-align: center;\r\n }\r\n }\r\n}\r\n"]}
|
|
@ -1,58 +1,58 @@
|
|||
nav#page-navigation #page-navigation-links
|
||||
{
|
||||
text-align: left;
|
||||
text-align: left;
|
||||
|
||||
> li > a
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
> li > a
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-parent .dropdown-menu
|
||||
{
|
||||
text-align: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.form-group
|
||||
{
|
||||
label
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
label
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
> label
|
||||
{
|
||||
margin-right: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
> label
|
||||
{
|
||||
margin-right: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
footer#page-footer .footer-flex .footer-flex-item
|
||||
{
|
||||
|
||||
&:last-child
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
&:last-child
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&:first-child
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
&:first-child
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px)
|
||||
{
|
||||
footer#page-footer .footer-flex .footer-flex-item
|
||||
{
|
||||
&:first-child
|
||||
{
|
||||
text-align: center;
|
||||
}
|
||||
footer#page-footer .footer-flex .footer-flex-item
|
||||
{
|
||||
&:first-child
|
||||
{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:last-child
|
||||
{
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
&:last-child
|
||||
{
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
@import "dark.scss";
|
||||
@import "inc/_christmas.scss";
|
||||
@import "inc/_christmas.scss";
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,195 +4,196 @@
|
|||
|
||||
module BuildFeed
|
||||
{
|
||||
let ajax: XMLHttpRequest;
|
||||
let timeout: number;
|
||||
let ajax: XMLHttpRequest;
|
||||
let timeout: number;
|
||||
|
||||
export function MobileMenuToggle(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function MobileMenuToggle(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const button = this as HTMLButtonElement;
|
||||
button.nextElementSibling.classList.toggle("open");
|
||||
}
|
||||
const button = this as HTMLButtonElement;
|
||||
button.nextElementSibling.classList.toggle("open");
|
||||
}
|
||||
|
||||
export function DropdownClick(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function DropdownClick(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const link = this as HTMLAnchorElement;
|
||||
const alreadyOpen = link.parentElement.classList.contains("open");
|
||||
const link = this as HTMLAnchorElement;
|
||||
const alreadyOpen = link.parentElement.classList.contains("open");
|
||||
|
||||
CloseDropdowns(ev);
|
||||
CloseDropdowns(ev);
|
||||
|
||||
if (!alreadyOpen)
|
||||
{
|
||||
link.parentElement.classList.toggle("open");
|
||||
if (!alreadyOpen)
|
||||
{
|
||||
link.parentElement.classList.toggle("open");
|
||||
|
||||
const menuClickCapture = document.getElementById("menu-open-overlay") as HTMLDivElement;
|
||||
menuClickCapture.classList.add("open");
|
||||
}
|
||||
}
|
||||
const menuClickCapture = document.getElementById("menu-open-overlay") as HTMLDivElement;
|
||||
menuClickCapture.classList.add("open");
|
||||
}
|
||||
}
|
||||
|
||||
export function CloseDropdowns(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function CloseDropdowns(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const ddParents = document.getElementsByClassName("dropdown-parent");
|
||||
for (let i = 0; i < ddParents.length; i++)
|
||||
{
|
||||
ddParents[i].classList.remove("open");
|
||||
}
|
||||
const ddParents = document.getElementsByClassName("dropdown-parent");
|
||||
for (let i = 0; i < ddParents.length; i++)
|
||||
{
|
||||
ddParents[i].classList.remove("open");
|
||||
}
|
||||
|
||||
const menuClickCapture = document.getElementById("menu-open-overlay") as HTMLDivElement;
|
||||
menuClickCapture.classList.remove("open");
|
||||
}
|
||||
const menuClickCapture = document.getElementById("menu-open-overlay") as HTMLDivElement;
|
||||
menuClickCapture.classList.remove("open");
|
||||
}
|
||||
|
||||
export function SwitchTheme(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function SwitchTheme(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const link = this as HTMLAnchorElement;
|
||||
document.cookie = `bf_theme=${link.dataset["theme"]}; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/`;
|
||||
location.reload(true);
|
||||
}
|
||||
const link = this as HTMLAnchorElement;
|
||||
document.cookie = `bf_theme=${link.dataset["theme"]}; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/`;
|
||||
location.reload(true);
|
||||
}
|
||||
|
||||
export function SwitchLanguage(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function SwitchLanguage(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const link = this as HTMLAnchorElement;
|
||||
document.cookie = `bf_lang=${link.dataset["lang"]}; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/`;
|
||||
location.reload(true);
|
||||
}
|
||||
const link = this as HTMLAnchorElement;
|
||||
document.cookie = `bf_lang=${link.dataset["lang"]}; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/`;
|
||||
location.reload(true);
|
||||
}
|
||||
|
||||
export function OpenSearch(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function OpenSearch(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const modal = document.getElementById("modal-search-overlay") as HTMLDivElement;
|
||||
modal.classList.add("open");
|
||||
}
|
||||
const modal = document.getElementById("modal-search-overlay") as HTMLDivElement;
|
||||
modal.classList.add("open");
|
||||
}
|
||||
|
||||
export function CloseSearch(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
export function CloseSearch(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
const modal = document.getElementById("modal-search-overlay") as HTMLDivElement;
|
||||
modal.classList.remove("open");
|
||||
}
|
||||
const modal = document.getElementById("modal-search-overlay") as HTMLDivElement;
|
||||
modal.classList.remove("open");
|
||||
}
|
||||
|
||||
export function StopClick(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
export function StopClick(ev: MouseEvent)
|
||||
{
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
export function InitiateSearch(ev: KeyboardEvent)
|
||||
{
|
||||
const resultPane = document.getElementById("modal-search-result") as HTMLDivElement;
|
||||
resultPane.innerHTML = "";
|
||||
export function InitiateSearch(ev: KeyboardEvent)
|
||||
{
|
||||
const resultPane = document.getElementById("modal-search-result") as HTMLDivElement;
|
||||
resultPane.innerHTML = "";
|
||||
|
||||
if (typeof (timeout) !== "undefined")
|
||||
{
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
if (typeof (timeout) !== "undefined")
|
||||
{
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
if (typeof (ajax) !== "undefined" && ajax.readyState !== XMLHttpRequest.DONE)
|
||||
{
|
||||
ajax.abort();
|
||||
}
|
||||
if (typeof (ajax) !== "undefined" && ajax.readyState !== XMLHttpRequest.DONE)
|
||||
{
|
||||
ajax.abort();
|
||||
}
|
||||
|
||||
timeout = setInterval(SendSearch, 200);
|
||||
}
|
||||
timeout = setInterval(SendSearch, 200);
|
||||
}
|
||||
|
||||
export function SendSearch()
|
||||
{
|
||||
if (typeof (timeout) !== "undefined")
|
||||
{
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
export function SendSearch()
|
||||
{
|
||||
if (typeof (timeout) !== "undefined")
|
||||
{
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
const modalInput = document.getElementById("modal-search-input") as HTMLInputElement;
|
||||
const modalInput = document.getElementById("modal-search-input") as HTMLInputElement;
|
||||
|
||||
ajax = new XMLHttpRequest();
|
||||
ajax.onreadystatechange = CompleteSearch;
|
||||
ajax.open("GET", `/api/GetSearchResult/${modalInput.value}/`, true);
|
||||
ajax.setRequestHeader("accept", "application/json");
|
||||
ajax.send(null);
|
||||
}
|
||||
ajax = new XMLHttpRequest();
|
||||
ajax.onreadystatechange = CompleteSearch;
|
||||
ajax.open("GET", `/api/GetSearchResult/${modalInput.value}/`, true);
|
||||
ajax.setRequestHeader("accept", "application/json");
|
||||
ajax.send(null);
|
||||
}
|
||||
|
||||
export function CompleteSearch(ev: ProgressEvent)
|
||||
{
|
||||
if (ajax.readyState !== XMLHttpRequest.DONE || ajax.status !== 200)
|
||||
{
|
||||
return;
|
||||
}
|
||||
export function CompleteSearch(ev: ProgressEvent)
|
||||
{
|
||||
if (ajax.readyState !== XMLHttpRequest.DONE || ajax.status !== 200)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const resultPane = document.getElementById("modal-search-result") as HTMLDivElement;
|
||||
const templateContent = document.getElementById("result-template") as HTMLDivElement;
|
||||
const template = jsrender.templates(templateContent.innerHTML);
|
||||
const content = template.render(JSON.parse(ajax.responseText));
|
||||
resultPane.innerHTML = content;
|
||||
const resultPane = document.getElementById("modal-search-result") as HTMLDivElement;
|
||||
const templateContent = document.getElementById("result-template") as HTMLDivElement;
|
||||
const template = jsrender.templates(templateContent.innerHTML);
|
||||
const content = template.render(JSON.parse(ajax.responseText));
|
||||
resultPane.innerHTML = content;
|
||||
|
||||
const resultLinks = resultPane.getElementsByTagName("a");
|
||||
for (let i = 0; i < resultLinks.length; i++)
|
||||
{
|
||||
resultLinks[i].addEventListener("click", (mev: MouseEvent) =>
|
||||
{
|
||||
mev.preventDefault();
|
||||
const modalInput = document.getElementById("modal-search-input") as HTMLInputElement;
|
||||
ga("send", "pageview", `/api/GetSearchResult/${modalInput.value}/`);
|
||||
location.assign((mev.currentTarget as HTMLAnchorElement).href);
|
||||
});
|
||||
}
|
||||
}
|
||||
const resultLinks = resultPane.getElementsByTagName("a");
|
||||
for (let i = 0; i < resultLinks.length; i++)
|
||||
{
|
||||
resultLinks[i].addEventListener("click",
|
||||
(mev: MouseEvent) =>
|
||||
{
|
||||
mev.preventDefault();
|
||||
const modalInput = document.getElementById("modal-search-input") as HTMLInputElement;
|
||||
ga("send", "pageview", `/api/GetSearchResult/${modalInput.value}/`);
|
||||
location.assign((mev.currentTarget as HTMLAnchorElement).href);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function BuildFeedSetup(ev: Event)
|
||||
{
|
||||
const ddParents = document.getElementsByClassName("dropdown-parent");
|
||||
for (let i = 0; i < ddParents.length; i++)
|
||||
{
|
||||
for (let j = 0; j < ddParents[i].childNodes.length; j++)
|
||||
{
|
||||
const el = ddParents[i].childNodes[j];
|
||||
|
||||
if (el.nodeName === "A")
|
||||
export function BuildFeedSetup(ev: Event)
|
||||
{
|
||||
const ddParents = document.getElementsByClassName("dropdown-parent");
|
||||
for (let i = 0; i < ddParents.length; i++)
|
||||
{
|
||||
for (let j = 0; j < ddParents[i].childNodes.length; j++)
|
||||
{
|
||||
el.addEventListener("click", DropdownClick);
|
||||
const el = ddParents[i].childNodes[j];
|
||||
|
||||
if (el.nodeName === "A")
|
||||
{
|
||||
el.addEventListener("click", DropdownClick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const menuClickCapture = document.getElementById("menu-open-overlay") as HTMLDivElement;
|
||||
menuClickCapture.addEventListener("click", CloseDropdowns);
|
||||
const menuClickCapture = document.getElementById("menu-open-overlay") as HTMLDivElement;
|
||||
menuClickCapture.addEventListener("click", CloseDropdowns);
|
||||
|
||||
const ddThemes = document.getElementById("settings-theme-menu").getElementsByTagName("a");
|
||||
for (let i = 0; i < ddThemes.length; i++)
|
||||
{
|
||||
ddThemes[i].addEventListener("click", SwitchTheme);
|
||||
}
|
||||
const ddThemes = document.getElementById("settings-theme-menu").getElementsByTagName("a");
|
||||
for (let i = 0; i < ddThemes.length; i++)
|
||||
{
|
||||
ddThemes[i].addEventListener("click", SwitchTheme);
|
||||
}
|
||||
|
||||
const ddLangs = document.getElementById("settings-lang-menu").getElementsByTagName("a");
|
||||
for (let i = 0; i < ddLangs.length; i++)
|
||||
{
|
||||
ddLangs[i].addEventListener("click", SwitchLanguage);
|
||||
}
|
||||
const ddLangs = document.getElementById("settings-lang-menu").getElementsByTagName("a");
|
||||
for (let i = 0; i < ddLangs.length; i++)
|
||||
{
|
||||
ddLangs[i].addEventListener("click", SwitchLanguage);
|
||||
}
|
||||
|
||||
const btnNav = document.getElementById("page-navigation-toggle");
|
||||
btnNav.addEventListener("click", MobileMenuToggle);
|
||||
const btnNav = document.getElementById("page-navigation-toggle");
|
||||
btnNav.addEventListener("click", MobileMenuToggle);
|
||||
|
||||
const btnSearch = document.getElementById("page-navigation-search");
|
||||
btnSearch.addEventListener("click", OpenSearch);
|
||||
const btnSearch = document.getElementById("page-navigation-search");
|
||||
btnSearch.addEventListener("click", OpenSearch);
|
||||
|
||||
const modalOverlay = document.getElementById("modal-search-overlay") as HTMLDivElement;
|
||||
modalOverlay.addEventListener("click", CloseSearch);
|
||||
const modalOverlay = document.getElementById("modal-search-overlay") as HTMLDivElement;
|
||||
modalOverlay.addEventListener("click", CloseSearch);
|
||||
|
||||
const modalDialog = document.getElementById("modal-search") as HTMLDivElement;
|
||||
modalDialog.addEventListener("click", StopClick);
|
||||
const modalDialog = document.getElementById("modal-search") as HTMLDivElement;
|
||||
modalDialog.addEventListener("click", StopClick);
|
||||
|
||||
const modalInput = document.getElementById("modal-search-input") as HTMLInputElement;
|
||||
modalInput.addEventListener("keyup", InitiateSearch);
|
||||
}
|
||||
const modalInput = document.getElementById("modal-search-input") as HTMLInputElement;
|
||||
modalInput.addEventListener("keyup", InitiateSearch);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("load", BuildFeed.BuildFeedSetup);
|
Loading…
Reference in New Issue