case '/main':
// TODO: set session current University <- FIXME: remove this
Session.currentUniv = getUnivAPI(args['univId']);
return MaterialPageRoute(builder: (_) => RouteView());
case '/pmain': // FIXME: remove this
Session.currentUniv = getUnivAPI('uPADONG'); // PADONG Univ Id
return MaterialPageRoute(builder: () => RouteView());
# TODO
> android/app/build.gradle
``` gradle
android {
compileSdkVersion 29
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "app.padong"
minSdkVersion 23
targetSdkVersion 29
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
ui/views/map/rail_view.dart
static Map<String, List> cutDayByDay(String scheduleId) {
List<String> ids = getEventIdsAPI(scheduleId);
Map<String, List> cutDay = {};
for (String id in ids) {
Map event = getEventAPI(id);
for (String time in event['times']) {
TimeManager tm = TimeManager.fromString(time);
cutDay[tm.date] = (cutDay[tm.date] ?? []) + [event];
}
} // TODO: periodicity
return cutDay;
}
core/node/chat/participant.dart
int countUnread() {
// TODO: based on Participant's modifiedAt, message's createdAt
return 0;
}
core/node/common/university.dart
class University extends TitleNode {
String emblemImgURL;
LatLng location; // TODO: get from Building
String address;
core/node/cover/item.dart
void revertWikiToThisItem() {
// TODO: revert Wiki to this Item
// check current Item & User authority
}
core/node/cover/wiki.dart
class Wiki extends TitleNode with Statistics {
List<String> backLinks; // List of wikiId
List<String> frontLinks; // List of wikiId
List<Argue> _argues;
class Building extends TitleNode with Statistics {
LatLng location;
int serviceCheckBits; // TODO transaction!
core/service/padong_auth.dart
static Future<SignUpResult> signUp(String email, String pw) async {
// When registerWithEmail returned AuthError.success,
// the verification email has sent. so, TODO: View must notify it to user.
try {
...
if (!currentUser.emailVerified) // TODO: notify email send
> core/service/padong_auth
``` dart
static Future<String> changeEmail(String email) async {
await _auth.currentUser.reload();
User sessionUser = _auth.currentUser;
if (sessionUser == null) return null;
try {
// TODO: Must Check changeEmail with exist email.
// In Firebase Auth Document, verifyBeforeUpdateEmail's Error code doesn't
// have [auth/email-already-in-use].
await sessionUser.verifyBeforeUpdateEmail(email);
core/service/session.dart
static Future changeUserEmail(String email, BuildContext context) async {
String uid = await PadongAuth.getUid();
if (user == null || user.id != uid)
throw Exception('Invalid User try to Change Email');
// TODO: user's parentId <- if user change university
String currEmail = await PadongAuth.changeEmail(email);
user.userEmails = [currEmail, email];
await user.update();
await signOutUser(context);
class BoardView extends StatelessWidget {
final String id;
final bool readOnly = false; // TODO: check by User and PIP
final Map<String, dynamic> board;
// TODO: validation check
if ((entranceYear) == null || (pw != rePw)) return false;
SignUpResult result =
await Session.signUpUser(id, pw, name, email, univName, entranceYear);
// TODO: result feedback
if (result == SignUpResult.success) return true;
return false;
}
> ui/views/sign/sign_view.dart
``` dart
onPressed: () async {
if (this.isButtonDisabled == false) {
this.isButtonDisabled = true;
if (await widget.onTapEnter())
// Session is Already Updated
Navigator.pushNamed(context, '/main');
else
// TODO: feedback to user
log("${widget.isSignIn ? 'SignIn' : 'SignUp'} Failed");
this.isButtonDisabled = false;
}
})
ui/views/templates/map_supporter_template.dart
child: HorizontalScroller(height: 150, children: [
// TODO: get building cards from API
...List.generate(10, (idx) => BuildingCard(idx.toString())),
SizedBox(width: 60)
])));
ui/widgets/cards/photo_card.dart
class PhotoCard extends StatelessWidget {
final String id; // node's id
final Map<String, dynamic> node;
final bool isWiki;
final bool isBuilding;
class ChatBalloon extends StatelessWidget {
// TODO: img!
final bool isMine;
etc
// at ChatRoom
unreads = 0;
// get recent Nodes
> ui/utils/compare/diff_line.dart
``` dart
//Todo: Have to optimize with https://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reduce_the_problem_set
//Todo: Have to study google/diff-match-patch's Algorithm ( Myer's diff algorithm, https://neil.fraser.name/writing/diff/ )
List<Diff> diffLine(String prev, String next) {
List<Diff> result = List<Diff>();
List<String> p = toLinuxNewLine(prev).split('\n');
List<String> n = toLinuxNewLine(next).split('\n');
FIXME
case '/pmain': // FIXME: remove this Session.currentUniv = getUnivAPI('uPADONG'); // PADONG Univ Id return MaterialPageRoute(builder: () => RouteView());
...
void _getArgues() async { // TODO: move it to constructor ? this._argues = await PadongFB.getDocsByRule(Argue().type, rule: (query) => query.where('wikiId', isEqualTo: this.id)) .then((docs) => docs.map((doc) => Argue.fromMap(doc.id, doc.data())).toList()); }
// TODO: when CRUD Service, update building's serviceCheckBit // One building can serve same type of services, not only one.
}
void updateSubscribe(User me, bool isSubscribed) { // TODO: update user's Subscribe setting Subscribe.fromMap('', {}); } }
appBar: BackAppBar(title: this.building['title'], actions: [ IconButton( icon: Icon(Icons.more_horiz, color: AppTheme.colors.support), onPressed: () {}) // TODO: more dialog ]),
DO NOT UPDATE UNIV AT SESSION
void chatWith(String id) { // TODO : check chatRoom exists PadongRouter.routeURL('/chat_room?id=$id'); }
}
}
}
PhotoCard(id, {isWiki = false, isBuilding = false}) : this.id = id, // TODO: getNode(id, type)
// get recent Nodes