padong4284 / padong-app

PADONG means wave in Korean. PADONG is a platform where people can come together to create an ocean of human waves.
5 stars 0 forks source link

To Do in Code #232

Closed jtjun closed 3 years ago

jtjun commented 3 years ago

FIXME

core/padong_router.dart


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;

...

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()); }


> core/node/cover/wiki.dart
``` dart

  void updateBackLinks(String targetWikiId, {bool isRemove = false}) async {
    // TODO: update firebase with Transaction, Target Wiki's frontLinks update
  }

  void updateFrontLinks(String targetWikiId, {bool isRemove = false}) async {
    // TODO: update firebase with Transaction, Target Wiki's backLinks update
  }

core/node/deck/board.dart

List<TitleNode> getNotices() {
// TODO: get notice posts!
// only owner can write, set isNotice
return [];
}

core/node/deck/deck.dart

Map<String, Board> getFixedBoards() {
// TODO: get fixed boards!
// TODO: move to university
return {
'Global': null,
'Public': null,
'Internal': null,
'Popular': null,
'Favorite': null,
'Inform': null,
};
}

core/node/map/service.dart


class Service extends Evaluation {
SERVICE serviceCode;

// TODO: when CRUD Service, update building's serviceCheckBit // One building can serve same type of services, not only one.


> core/node/schedule/schedule.dart
``` dart
  List<Event> getTodaySchedule() {
    // TODO: get today's events & lectures!
    return [];
  }

core/node/schedule/review.dart

@override
Future<bool> update() async {
// TODO: transaction to update Evaluation's rate
return await super.update();
}

core/node/map/building.dart

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);

}


> core/service/session.dart
``` dart
  static Future<bool> changeCurrentUniversity(
      University university, BuildContext context) async {
    // TODO: use Provider, alert all view
    currUniversity = university;
    Navigator.pushNamed(context, '/main');
    return true; // TODO: check success
  }

core/shared/statistics.dart

TODO: with transaction

core/shared/notification.dart


mixin Notification on Node {
bool isSubscribed(User me) {
// TODO: get user's Alert setting
return false;
}

void updateSubscribe(User me, bool isSubscribed) { // TODO: update user's Subscribe setting Subscribe.fromMap('', {}); } }


> ui/views/chat/chat_room_view.dart
``` dart
return SafePaddingTemplate(
      appBar:
          BackAppBar(title: this.chatRoom['title'], isClose: true, actions: [
        IconButton(
            icon: Icon(Icons.more_horiz, color: AppTheme.colors.support),
            onPressed: () {}) // TODO: more dialog
      ]),
      floatingBottomBar: BottomSender(
        BottomSenderType.CHAT,
        msgController: this._msgController,
        onSubmit: () {
          // TODO: send and receive messages !
          this._msgController.text = '';
        },
      ),

ui/views/chat/chat_view.dart

void onTabOk() {
List<String> participants = this.invites + [Session.user['id']];
Map<String, dynamic> data = {
'parentId': Session.user['id'],
'title': this._titleController.text.length > 0
? this._titleController.text
: participants.map((id) => getUserAPI(id)['username']).join(', '),
'description': this._contentController.text,
'participants': participants,
'pip': [PIP.PUBLIC, PIP.INTERNAL, PIP.PRIVATE][this.pipIdx],
};
creatChatRoomAPI(data);
PadongRouter.goBack();
// TODO: show dialog or snackBar to alert submit complete
}

ui/views/chat/chats_view.dart

appBar: BackAppBar(title: 'Chats', actions: [
IconButton(
icon: Icon(Icons.more_horiz, color: AppTheme.colors.support),
onPressed: () {}) // TODO: more dialog

ui/views/deck/board.dart

class BoardView extends StatelessWidget {
final String id;
final bool readOnly = false; // TODO: check by User and PIP
final Map<String, dynamic> board;

ui/views/deck/board_view.dart

appBar: BackAppBar(title: this.board['title'], actions: [
IconButton(
icon: Icon(Icons.more_horiz, color: AppTheme.colors.support),
onPressed: () {}) // TODO: more dialog
]),

ui/views/map/building_view.dart


class BuildingView extends StatelessWidget {
// TODO: PIP / Written, Replied, Liked, Bookmarked
final String id;
final Map<String, dynamic> building;
...

appBar: BackAppBar(title: this.building['title'], actions: [ IconButton( icon: Icon(Icons.more_horiz, color: AppTheme.colors.support), onPressed: () {}) // TODO: more dialog ]),


> ui/views/map/service_view.dart
``` dart
  Widget likeAndBookmark() {
    // TODO: same code Post refactor
    return BackAppBar(actions: [
      ToggleIconButton(

  List<Widget> bottomLine() {
    return [
      Stack(children: [
        BottomButtons(left: 0, bottoms: this.service['bottoms']),
        Positioned(
          bottom: 5,
          right: 0,
          child: TranspButton(
              buttonSize: ButtonSize.SMALL,
              icon: Icon(Icons.more_horiz,
                  color: AppTheme.colors.support, size: 20),
              callback: () {
                // TODO: click more
              }),
        )
      ]),

ui/views/profile/configure_view.dart


Row(mainAxisAlignment: MainAxisAlignment.end, children: [
SizedBox(
width: 32,
height: 20,
child: IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {}, // TODO: more dialog
icon: Icon(Icons.more_horiz_rounded,
color: AppTheme.colors.support))),
Input(
controller: this._controllers[0],
margin: EdgeInsets.only(top: 10.0),
hintText: 'Password'),
Input(
controller: this._controllers[1],
margin: EdgeInsets.only(top: 10.0),
hintText: 'Repeat Password'),
// TODO: check match feedback real-time
...

          this.isVerified
              ? this.lockedInput(this.user['universityName'])
              : ListPicker(this._controllers[3],
                  margin: EdgeInsets.only(top: 10.0),
                  hintText: 'University',
                  list: ['Georgia Tech']),
          // TODO: get univ list

> ui/views/profile/configure_view.dart
``` dart
  Function addPhotoFunction(context) {
    return getImageFromUser(context, (PickedFile image) {
      setState(() {
        this.user['profileImgURL'] = image.path;
        // https://github.com/ptyagicodecamp/flutter_cookbook/blob/widgets/flutter_widgets/lib/images/upload_image.dart
        // TODO: upload to firebase
      });
    });
  }

DO NOT UPDATE UNIV AT SESSION

ui/views/profile/configure_view.dart

if (!this.isVerified) {
String univ = this._controllers[3].text;
String email = this._controllers[5].text;
// TODO: update univId
data['universityName'] =
univ.length > 0 ? univ : this.user['universityName'];
data['email'] = email.length > 0 ? email : this.user['email'];
}

ui/views/profile/friends_view.dart


Widget friendList(List<String> friendIds) {
return Column(
children: friendIds
.map((id) => InkWell(
onTap: () => PadongRouter.routeURL('/profile?id=$id'),
child: FriendTile(id, chatCallback: this.chatWith,
moreCallback: () {
// TODO: more dialog
})))
.toList());
}

void chatWith(String id) { // TODO : check chatRoom exists PadongRouter.routeURL('/chat_room?id=$id'); }


> ui/views/profile/profile_view.dart
``` dart

  List<Widget> topAction() {
    return widget.isMine
        ? [
            SizedBox(
                width: 32,
                child: IconButton(
                    onPressed: () => PadongRouter.routeURL('/configure'),
                    icon: Icon(Icons.settings_rounded,
                        color: AppTheme.colors.support)))
          ]
        : [
            SizedBox(
                width: 32,
                child: IconButton(
                  // TODO: check chatRoom is exists
                    onPressed: () => PadongRouter.routeURL('/chat'),
                    icon: Icon(Icons.mode_comment_outlined,
                        color: AppTheme.colors.support))),
            SizedBox(
                width: 32,
                child: IconButton(
                    onPressed: () {}, // TODO: more dialog
                    icon: Icon(Icons.more_horiz_rounded,
                        color: AppTheme.colors.support)))
          ];
  }

ui/views/schedule/lecture_view.dart

appBar: BackAppBar(title: this.lecture['title'], actions: [
IconButton(
icon: Icon(Icons.mode_comment_outlined,
color: AppTheme.colors.support),
onPressed: () {}), // TODO: route to chat
IconButton(
icon: Icon(Icons.more_horiz, color: AppTheme.colors.support),
onPressed: () {
PadongRouter.routeURL(
'/update?id=${this.lecture['parentId']}&lectureId=${this.id}');
}) // TODO: more dialog
]),

ui/views/schedule/event_view.dart

appBar: BackAppBar(title: this.event['title'], actions: [
IconButton(
icon: Icon(Icons.more_horiz, color: AppTheme.colors.support),
onPressed: () {
PadongRouter.routeURL(
'/update?id=${this.event['parentId']}&eventId=${this.id}');
}) // TODO: more dialog
]),

ui/views/schedule/update_view.dart


void onTabOk() {
...

  createEventAPI(data); // TODO: edit or create
PadongRouter.goBack();
// TODO: show dialog or snackBar to alert submit complete

}


> ui/views/templates/markdown_editor_template.dart
``` dart
  void onTabOk() {
    Map data = {
      'title': this._titleController.text,
      'description': this._mdController.text,
    };
    if (widget.topArea == null)
      data['pip'] = [PIP.PUBLIC, PIP.INTERNAL, PIP.PRIVATE][this.pipIdx];
    widget.onSubmit(data);
    PadongRouter.goBack();
    // TODO: show dialog or snackBar to alert submit complete
  }

ui/views/sign/sign_in_view.dart


Future<bool> onSignIn() async {
String id = _idController.text;
String pw = _pwController.text;
// TODO: validate check
SignInResult result = await Session.signInUser(id, pw);
if (result == SignInResult.success) return true;
return false;

}


> ui/views/sign/sign_up_view.dart
``` dart
                    Input(
                        controller: this._controllers[1],
                        margin: EdgeInsets.only(top: 10.0),
                        hintText: 'Password'),
                    Input(
                        controller: this._controllers[2],
                        margin: EdgeInsets.only(top: 10.0),
                        hintText: 'Repeat Password'),
                    // TODO: check match feedback real-time
                    Input(
                        controller: this._controllers[3],
                        margin: EdgeInsets.only(top: 20.0 + paddingBottom),
                        hintText: 'Name'),
                    ListPicker(
                      this._controllers[4],
                      margin: EdgeInsets.only(top: 10.0),
                      hintText: 'University',
                      list: ['Georgia Tech'], // TODO: get from PB
                    ),
                    // TODO: get univ list

ui/views/sign/sign_up_view.dart


Future<bool> onSignUp() async {
String id = this._controllers[0].text;
String pw = this._controllers[1].text;
String rePw = this._controllers[2].text;
String name = this._controllers[3].text;
String univName = this._controllers[4].text;
int entranceYear = int.tryParse(this._controllers[5].text);
String email = this._controllers[6].text;
// 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;

PhotoCard(id, {isWiki = false, isBuilding = false}) : this.id = id, // TODO: getNode(id, type)


> ui/widgets/cards/time_table.dart
``` dart
class TimeTable extends StatefulWidget {
  final List lectures;

  // TODO: this week's events

ui/widgets/cards/timelines/history_card.dart

child: Text('15', // TODO: get difference ADDED
style: AppTheme.getFont(
color: AppTheme.colors.primary,
fontSize: AppTheme.fontSizes.small))),
Icon(Icons.remove_rounded,
size: 15, color: AppTheme.colors.pointRed),
SizedBox(
width: 30,
child: Text('15', // TODO: get difference REMOVED
style: AppTheme.getFont(

ui/widgets/cards/timelines/history_cart.dart

Positioned(
bottom: 2,
right: 0,
child: Text(
'e' + this.id, // TODO: history ID
style: AppTheme.getFont(
color: AppTheme.colors.fontPalette[2],
fontSize: AppTheme.fontSizes.small),
))

ui/widgets/cards/timelines/timeline_card.dart

String getTerm() {
TimeManager tm = TimeManager.fromString(this.event['times'][0]);
return tm.range + (tm.dMin > 0 ?' (${tm.dMin}min)' : ' All day'); // TODO: get Term from TimeRange
}

ui/widgets/containers/vertical_timeline.dart

class VerticalTimeline extends StatelessWidget {
final String date; // TODO: DateTime class

ui/widgets/inputs/bottom_sender.dart

Function addPhotoFunction(context) {
return getImageFromUser(context, (PickedFile image) {
// https://github.com/ptyagicodecamp/flutter_cookbook/blob/widgets/flutter_widgets/lib/images/upload_image.dart
// TODO: upload to firebase
this.msgController.text = image.path; // TODO: send img to chatroom
});
}

ui/widgets/inputs/markdown_supporter.dart

Function addPhotoFunction(context) {
return getImageFromUser(context, (PickedFile image) {
this._mdController.text += '![IMAGE](' + image.path + ')';
// https://github.com/ptyagicodecamp/flutter_cookbook/blob/widgets/flutter_widgets/lib/images/upload_image.dart
// TODO: upload to firebase
});
}

ui/widgets/node_base.dart

void moreCallback() {
// TODO: Click more button " ... "
}

ui/widgets/nod_base_tile.dart

void moreCallback() {
// TODO: Click more button " ... "
}

ui/widgets/tiles/chat_ballon.dart

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');
jtjun commented 3 years ago

to #278